HyCodeYourTale
classpublicPriority 3

MultiCacheDensity

com.hypixel.hytale.builtin.hytalegenerator.density.nodes.MultiCacheDensity

extends Density

2

Methods

2

Public Methods

2

Fields

1

Constructors

Constructors

public
MultiCacheDensity(Density input, int threadCount, int capacity)

Methods

Public Methods (2)

public
double process(Density.Context context)
@Override
public
void setInputs(Density[] inputs)
@Override

Fields

Private/Package Fields (2)

privateDensity input
privateWorkerIndexer.Data<MultiCacheDensity.Cache> threadData

Inheritance

Parent
Current
Interface
Child

Use mouse wheel to zoom, drag to pan. Click nodes to navigate.

Related Classes

Source Code

package com.hypixel.hytale.builtin.hytalegenerator.density.nodes;

import com.hypixel.hytale.builtin.hytalegenerator.density.Density;
import com.hypixel.hytale.builtin.hytalegenerator.threadindexer.WorkerIndexer;
import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class MultiCacheDensity extends Density {
   @Nonnull
   private final WorkerIndexer.Data<MultiCacheDensity.Cache> threadData;
   @Nonnull
   private Density input;

   public MultiCacheDensity(@Nonnull Density input, int threadCount, int capacity) {
      this.input = input;
      this.threadData = new WorkerIndexer.Data<>(threadCount, () -> new MultiCacheDensity.Cache(capacity));
   }

   @Override
   public double process(@Nonnull Density.Context context) {
      MultiCacheDensity.Cache cache = this.threadData.get(context.workerId);
      MultiCacheDensity.Entry matchingEntry = cache.find(context.position);
      if (matchingEntry == null) {
         matchingEntry = cache.getNext();
         if (matchingEntry.position == null) {
            matchingEntry.position = new Vector3d();
         }

         matchingEntry.position.assign(context.position);
         matchingEntry.value = this.input.process(context);
      }

      return matchingEntry.value;
   }

   @Override
   public void setInputs(@Nonnull Density[] inputs) {
      assert inputs.length != 0;

      assert inputs[0] != null;

      this.input = inputs[0];
   }

   private static class Cache {
      MultiCacheDensity.Entry[] entries;
      int oldestIndex;

      Cache(int size) {
         this.entries = new MultiCacheDensity.Entry[size];

         for (int i = 0; i < size; i++) {
            this.entries[i] = new MultiCacheDensity.Entry();
         }

         this.oldestIndex = 0;
      }

      MultiCacheDensity.Entry getNext() {
         MultiCacheDensity.Entry entry = this.entries[this.oldestIndex];
         this.oldestIndex++;
         if (this.oldestIndex >= this.entries.length) {
            this.oldestIndex = 0;
         }

         return entry;
      }

      @Nullable
      MultiCacheDensity.Entry find(@Nonnull Vector3d position) {
         int startIndex = this.oldestIndex - 1;
         if (startIndex < 0) {
            startIndex += this.entries.length;
         }

         int index = startIndex;

         while (!position.equals(this.entries[index].position)) {
            if (++index >= this.entries.length) {
               index = 0;
            }

            if (index == startIndex) {
               return null;
            }
         }

         return this.entries[index];
      }
   }

   private static class Entry {
      Vector3d position = null;
      double value = 0.0;

      Entry() {
      }
   }
}