PendingOp class

Пакет: com.hypixel.hytale.server.core.universe

Файл: com/hypixel/hytale/server/core/universe/StorageManager.java

Поля (4)

МодификаторыТипИмя
private int activeLoads
private Supplier<CompletableFuture<Void>> doSave
private CompletableFuture<Void> loadBarrier
private CompletableFuture<Void> onComplete

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe;

class="kw">import java.nio.file.Path;
class="kw">import java.util.ArrayList;
class="kw">import java.util.HashMap;
class="kw">import java.util.Map;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import java.util.function.BooleanSupplier;
class="kw">import java.util.function.Supplier;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class StorageManager {
   class="kw">private class="kw">final BooleanSupplier isSavingLocked;
   class="kw">private class="kw">final StampedLock lock = new StampedLock();
   class="kw">private class="kw">final Map<Path, StorageManager.PendingOp> pendingOps = new HashMap<>();

   class="kw">public StorageManager(BooleanSupplier var1) {
      this.isSavingLocked = var1;
   }

   class="kw">public boolean hasQueuedSave(@Nonnull Path var1) {
      var1 = var1.normalize();
      long var2 = this.lock.readLock();

      try {
         StorageManager.PendingOp var4 = this.pendingOps.get(var1);
         class="kw">return var4 != null && var4.activeLoads == 0;
      } class="kw">finally {
         this.lock.unlockRead(var2);
      }
   }

   class="kw">private void clearSave(@Nonnull Path var1) {
      long var2 = this.lock.writeLock();

      try {
         this.pendingOps.remove(var1);
      } class="kw">finally {
         this.lock.unlockWrite(var2);
      }
   }

   class="kw">public CompletableFuture<Void> doSave(@Nonnull Path var1, @Nonnull Supplier<CompletableFuture<Void>> var2) {
      var1 = var1.normalize();
      long var3 = this.lock.writeLock();

      try {
         StorageManager.PendingOp var5 = this.pendingOps.get(var1);
         if (var5 != null) {
            if (var5.doSave != null) {
               var5.doSave = var2;
               class="kw">return var5.onComplete;
            } else {
               Path var13 = var1;
               class="kw">return var5.onComplete = var5.onComplete.thenCompose(var3x -> this.doSave(var13, var2));
            }
         } else {
            CompletableFuture var6 = new CompletableFuture<>();
            if (this.isSavingLocked.getAsBoolean()) {
               var5 = new StorageManager.PendingOp(var6, var2);
            } else {
               Path var7 = var1;
               var2.get().whenCompleteAsync((var3x, var4) -> {
                  this.clearSave(var7);
                  if (var4 != null) {
                     var6.completeExceptionally(var4);
                  } else {
                     var6.complete(null);
                  }
               });
               var5 = new StorageManager.PendingOp(var6, null);
            }

            this.pendingOps.put(var1, var5);
            class="kw">return var6;
         }
      } class="kw">finally {
         this.lock.unlockWrite(var3);
      }
   }

   class="kw">public <T> CompletableFuture<T> doLoad(@Nonnull Path var1, @Nonnull Supplier<CompletableFuture<T>> var2) {
      var1 = var1.normalize();
      long var3 = this.lock.writeLock();

      try {
         StorageManager.PendingOp var5 = this.pendingOps.get(var1);
         if (var5 != null && var5.activeLoads == 0) {
            Path var14 = var1;
            class="kw">return var5.onComplete.thenCompose(var3x -> this.doLoad(var14, var2));
         }

         CompletableFuture var6 = var2.get();
         if (var5 == null) {
            CompletableFuture var7 = new CompletableFuture<>();
            var5 = new StorageManager.PendingOp(var7, null);
            var5.loadBarrier = var7;
            var5.activeLoads = 1;
            this.pendingOps.put(var1, var5);
         } else {
            var5.activeLoads++;
         }

         Path var15 = var1;
         StorageManager.PendingOp var8 = var5;
         var6.whenCompleteAsync((var3x, var4) -> {
            CompletableFuture var5 = null;
            long var6 = this.lock.writeLock();

            try {
               var8.activeLoads--;
               if (var8.activeLoads == 0) {
                  if (this.pendingOps.get(var15) == var8) {
                     this.pendingOps.remove(var15);
                  }

                  var5 = var8.loadBarrier;
               }
            } class="kw">finally {
               this.lock.unlockWrite(var6);
            }

            if (var5 != null) {
               var5.complete(null);
            }
         });
         class="kw">return var6;
      } class="kw">finally {
         this.lock.unlockWrite(var3);
      }
   }

   class="kw">public CompletableFuture<Void> pendingOperations() {
      long var1 = this.lock.readLock();

      try {
         ArrayList var3 = new ArrayList<>();

         for (StorageManager.PendingOp var5 : this.pendingOps.values()) {
            if (var5.doSave == null && var5.activeLoads <= 0) {
               var3.add(var5.onComplete);
            }
         }

         class="kw">return CompletableFuture.allOf(var3.toArray(CompletableFuture[]::new));
      } class="kw">finally {
         this.lock.unlockRead(var1);
      }
   }

   class="kw">public void onSavingRelease() {
      long var1 = this.lock.writeLock();

      try {
         for (Entry var4 : this.pendingOps.entrySet()) {
            Path var5 = var4.getKey();
            StorageManager.PendingOp var6 = var4.getValue();
            if (var6.doSave != null) {
               Supplier var7 = var6.doSave;
               var6.doSave = null;
               CompletableFuture var8 = var6.onComplete;
               var7.get().whenCompleteAsync((var3, var4x) -> {
                  this.clearSave(var5);
                  if (var4x != null) {
                     var8.completeExceptionally(var4x);
                  } else {
                     var8.complete(null);
                  }
               });
            }
         }
      } class="kw">finally {
         this.lock.unlockWrite(var1);
      }
   }

   class="kw">private class="kw">static class="kw">final class PendingOp {
      @Nonnull
      class="kw">private CompletableFuture<Void> onComplete;
      @Nullable
      class="kw">private Supplier<CompletableFuture<Void>> doSave;
      @Nullable
      class="kw">private CompletableFuture<Void> loadBarrier;
      class="kw">private int activeLoads;

      class="kw">private PendingOp(@Nonnull CompletableFuture<Void> var1, @Nullable Supplier<CompletableFuture<Void>> var2) {
         this.onComplete = var1;
         this.doSave = var2;
      }
   }
}