classpublicPriority 3
CachedPositionProvider
com.hypixel.hytale.builtin.hytalegenerator.positionproviders.cached.CachedPositionProvider
extends PositionProvider
3
Methods
3
Public Methods
3
Fields
1
Constructors
Constructors
public
CachedPositionProvider(PositionProvider positionProvider, int sectionSize, int cacheSize, boolean useInternalThreadData, int threadCount)Methods
Public Methods (3)
public
void get(PositionProvider.Context context)public
void positionsIn(PositionProvider.Context context)@Override
public
int sectionFloor(int voxelAddress)Fields
Private/Package Fields (3)
private
PositionProvider positionProviderprivate
int sectionSizeprivate
WorkerIndexer.Data<CacheThreadMemory> threadDataInheritance
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.positionproviders.cached;
import com.hypixel.hytale.builtin.hytalegenerator.VectorUtil;
import com.hypixel.hytale.builtin.hytalegenerator.positionproviders.PositionProvider;
import com.hypixel.hytale.builtin.hytalegenerator.threadindexer.WorkerIndexer;
import com.hypixel.hytale.math.util.HashUtil;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.ArrayList;
import javax.annotation.Nonnull;
public class CachedPositionProvider extends PositionProvider {
@Nonnull
private final PositionProvider positionProvider;
private final int sectionSize;
private WorkerIndexer.Data<CacheThreadMemory> threadData;
public CachedPositionProvider(@Nonnull PositionProvider positionProvider, int sectionSize, int cacheSize, boolean useInternalThreadData, int threadCount) {
if (sectionSize > 0 && cacheSize >= 0 && threadCount > 0) {
this.positionProvider = positionProvider;
this.sectionSize = sectionSize;
this.threadData = new WorkerIndexer.Data<>(threadCount, () -> new CacheThreadMemory(cacheSize));
} else {
throw new IllegalArgumentException();
}
}
@Override
public void positionsIn(@Nonnull PositionProvider.Context context) {
this.get(context);
}
public void get(@Nonnull PositionProvider.Context context) {
CacheThreadMemory cachedData = this.threadData.get(context.workerId);
Vector3i minSection = this.sectionAddress(context.minInclusive);
Vector3i maxSection = this.sectionAddress(context.maxExclusive);
Vector3i sectionAddress = minSection.clone();
for (sectionAddress.x = minSection.x; sectionAddress.x <= maxSection.x; sectionAddress.x++) {
for (sectionAddress.z = minSection.z; sectionAddress.z <= maxSection.z; sectionAddress.z++) {
for (sectionAddress.y = minSection.y; sectionAddress.y <= maxSection.y; sectionAddress.y++) {
long key = HashUtil.hash((long)sectionAddress.x, (long)sectionAddress.y, (long)sectionAddress.z);
Vector3d[] section = cachedData.sections.get(key);
if (section == null) {
Vector3d sectionMin = this.sectionMin(sectionAddress);
Vector3d sectionMax = sectionMin.clone().add((double)this.sectionSize, (double)this.sectionSize, (double)this.sectionSize);
ArrayList<Vector3d> generatedPositions = new ArrayList<>();
PositionProvider.Context childContext = new PositionProvider.Context(sectionMin, sectionMax, generatedPositions::add, null, context.workerId);
this.positionProvider.positionsIn(childContext);
section = new Vector3d[generatedPositions.size()];
generatedPositions.toArray(section);
cachedData.sections.put(key, section);
cachedData.expirationList.addFirst(key);
if (cachedData.expirationList.size() > cachedData.size) {
long removedKey = cachedData.expirationList.removeLast();
cachedData.sections.remove(removedKey);
}
}
for (Vector3d position : section) {
if (VectorUtil.isInside(position, context.minInclusive, context.maxExclusive)) {
context.consumer.accept(position.clone());
}
}
}
}
}
}
@Nonnull
private Vector3i sectionAddress(@Nonnull Vector3d pointer) {
Vector3i address = pointer.toVector3i();
address.x = this.sectionFloor(address.x) / this.sectionSize;
address.y = this.sectionFloor(address.y) / this.sectionSize;
address.z = this.sectionFloor(address.z) / this.sectionSize;
return address;
}
@Nonnull
private Vector3d sectionMin(@Nonnull Vector3i sectionAddress) {
Vector3d min = sectionAddress.toVector3d();
min.x = min.x * (double)this.sectionSize;
min.y = min.y * (double)this.sectionSize;
min.z = min.z * (double)this.sectionSize;
return min;
}
private int toSectionAddress(double position) {
int positionAddress = (int)position;
positionAddress = this.sectionFloor(positionAddress);
return positionAddress / this.sectionSize;
}
public int sectionFloor(int voxelAddress) {
return voxelAddress < 0 ? voxelAddress - voxelAddress % this.sectionSize - this.sectionSize : voxelAddress - voxelAddress % this.sectionSize;
}
}