CacheEntry class

Пакет: com.hypixel.hytale.server.worldgen.util.cache

Файл: com/hypixel/hytale/server/worldgen/util/cache/SizedTimeoutCache.java

Поля (3)

МодификаторыТипИмя
private K key
private long timestamp
private V value

Исходный код

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

class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
class="kw">import java.lang.ref.WeakReference;
class="kw">import java.lang.ref.Cleaner.Cleanable;
class="kw">import java.util.ArrayDeque;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.function.BiConsumer;
class="kw">import java.util.function.Function;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class SizedTimeoutCache<K, V> class="kw">implements Cache<K, V> {
   class="kw">private class="kw">final ArrayDeque<SizedTimeoutCache.CacheEntry<K, V>> pool = new ArrayDeque<>();
   class="kw">private class="kw">final Object2ObjectLinkedOpenHashMap<K, SizedTimeoutCache.CacheEntry<K, V>> map = new Object2ObjectLinkedOpenHashMap();
   class="kw">private class="kw">final long timeout;
   class="kw">private class="kw">final int maxSize;
   @Nullable
   class="kw">private class="kw">final Function<K, V> func;
   @Nullable
   class="kw">private class="kw">final BiConsumer<K, V> destroyer;
   @Nonnull
   class="kw">private class="kw">final ScheduledFuture<?> future;
   @Nonnull
   class="kw">private class="kw">final Cleanable cleanable;

   class="kw">public SizedTimeoutCache(long var1, @Nonnull TimeUnit var3, int var4, @Nullable Function<K, V> var5, @Nullable BiConsumer<K, V> var6) {
      this.timeout = var3.toNanos(var1);
      this.maxSize = var4;
      this.func = var5;
      this.destroyer = var6;
      this.future = HytaleServer.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(new CleanupRunnable(new WeakReference<>(this)), var1, var1, var3);
      this.cleanable = CleanupFutureAction.CLEANER.register(this, new CleanupFutureAction(this.future));
   }

   @Override
   class="kw">public void cleanup() {
      this.reduceLength(this.maxSize);
      long var1 = System.nanoTime() - this.timeout;

      while (true) {
         Object var3;
         Object var4;
         class="kw">synchronized (this.map) {
            label37: {
               if (!this.map.isEmpty()) {
                  var3 = (K)this.map.lastKey();
                  SizedTimeoutCache.CacheEntry var6 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.get(var3);
                  if (var6.timestamp <= var1) {
                     this.map.remove(var3);
                     var4 = var6.value;
                     if (this.pool.size() < this.maxSize) {
                        var6.key = null;
                        var6.value = null;
                        var6.timestamp = 0L;
                        this.pool.addLast(var6);
                     }
                     break label37;
                  }
               }

               class="kw">return;
            }
         }

         if (this.destroyer != null) {
            this.destroyer.accept(var3, var4);
         }
      }
   }

   class="kw">private void reduceLength(int var1) {
      while (true) {
         Object var2;
         Object var3;
         class="kw">synchronized (this.map) {
            if (this.map.size() <= var1) {
               class="kw">return;
            }

            SizedTimeoutCache.CacheEntry var5 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.removeLast();
            var2 = var5.key;
            var3 = var5.value;
            if (this.pool.size() < this.maxSize) {
               var5.key = null;
               var5.value = null;
               var5.timestamp = 0L;
               this.pool.addLast(var5);
            }
         }

         if (this.destroyer != null) {
            this.destroyer.accept(var2, var3);
         }
      }
   }

   @Override
   class="kw">public void shutdown() {
      this.cleanable.clean();
      if (this.destroyer != null) {
         this.reduceLength(0);
      } else {
         class="kw">synchronized (this.map) {
            this.map.clear();
         }
      }
   }

   @Nullable
   @Override
   class="kw">public V get(K var1) {
      if (this.future.isCancelled()) {
         throw new IllegalStateException("Cache has been shutdown!");
      }

      long var2 = System.nanoTime();
      class="kw">synchronized (this.map) {
         SizedTimeoutCache.CacheEntry var5 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.getAndMoveToFirst(var1);
         if (var5 != null) {
            var5.timestamp = var2;
            class="kw">return var5.value;
         }
      }

      if (this.func == null) {
         class="kw">return null;
      }

      Object var13 = this.func.apply(var1);
      var2 = System.nanoTime();
      SizedTimeoutCache.CacheEntry var6;
      Object var7;
      SizedTimeoutCache.CacheEntry var14;
      class="kw">synchronized (this.map) {
         var14 = this.pool.isEmpty() ? new SizedTimeoutCache.CacheEntry<>() : this.pool.removeLast();
         var14.key = var1;
         var14.value = var13;
         var14.timestamp = var2;
         var6 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.getAndMoveToFirst(var1);
         if (var6 != null) {
            var6.timestamp = var2;
         } else {
            var6 = var14;
            this.map.put(var1, var6);
         }

         var7 = var6.value;
      }

      if (var6 != var14 && this.destroyer != null) {
         this.destroyer.accept(var1, var13);
      }

      class="kw">return var7;
   }

   class="kw">public void put(K var1, V var2) {
      if (this.future.isCancelled()) {
         throw new IllegalStateException("Cache has been shutdown!");
      }

      long var3 = System.nanoTime();
      SizedTimeoutCache.CacheEntry var6;
      class="kw">synchronized (this.map) {
         SizedTimeoutCache.CacheEntry var5 = this.pool.isEmpty() ? new SizedTimeoutCache.CacheEntry<>() : this.pool.removeLast();
         var5.key = var1;
         var5.value = var2;
         var5.timestamp = var3;
         var6 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.putAndMoveToFirst(var1, var5);
         if (var6 != null) {
            var5.key = var6.key;
         }
      }

      if (var6 != null && this.destroyer != null) {
         this.destroyer.accept(var1, var6.value);
      }
   }

   @Nullable
   class="kw">public V getWithReusedKey(K var1, @Nonnull Function<K, K> var2) {
      if (this.future.isCancelled()) {
         throw new IllegalStateException("Cache has been shutdown!");
      }

      long var3 = System.nanoTime();
      class="kw">synchronized (this.map) {
         SizedTimeoutCache.CacheEntry var6 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.getAndMoveToFirst(var1);
         if (var6 != null) {
            var6.timestamp = var3;
            class="kw">return var6.value;
         }
      }

      if (this.func == null) {
         class="kw">return null;
      }

      Object var15 = var2.apply(var1);
      Object var16 = this.func.apply(var15);
      var3 = System.nanoTime();
      SizedTimeoutCache.CacheEntry var7;
      SizedTimeoutCache.CacheEntry var8;
      Object var9;
      class="kw">synchronized (this.map) {
         var7 = this.pool.isEmpty() ? new SizedTimeoutCache.CacheEntry<>() : this.pool.removeLast();
         var7.key = var15;
         var7.value = var16;
         var7.timestamp = var3;
         var8 = (SizedTimeoutCache.CacheEntry<K, V>)this.map.getAndMoveToFirst(var15);
         if (var8 != null) {
            var8.timestamp = var3;
         } else {
            var8 = var7;
            this.map.put(var15, var8);
         }

         var9 = var8.value;
      }

      if (var8 != var7 && this.destroyer != null) {
         this.destroyer.accept(var15, var16);
      }

      class="kw">return var9;
   }

   class="kw">private class="kw">static class CacheEntry<K, V> {
      @Nullable
      class="kw">private V value;
      @Nullable
      class="kw">private K key;
      class="kw">private long timestamp;

      class="kw">private CacheEntry() {
      }
   }
}