add get fresh methods to TheadMapUtil

the getFresh versions create/clear the data for the given map.
This commit is contained in:
James Seibel
2021-09-25 11:48:05 -05:00
parent 430a908829
commit 1a3e1dfa8c
6 changed files with 197 additions and 91 deletions
@@ -275,13 +275,8 @@ public class LodBuilder
{
int size = 1 << detail.detailLevel;
long[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray()[detail.detailLevel];
long[] dataToMerge = ThreadMapUtil.getFreshBuilderVerticalArray(size * size * DataPointUtil.worldHeight + 1, detail.detailLevel);
if (dataToMerge == null || dataToMerge.length != size * size * DataPointUtil.worldHeight + 1)
dataToMerge = new long[size * size * DataPointUtil.worldHeight + 1];
for (int i = 0; i < dataToMerge.length; i++)
dataToMerge[i] = DataPointUtil.EMPTY_DATA;
int verticalData = DataPointUtil.worldHeight;
@@ -429,7 +424,7 @@ public class LodBuilder
private long[] createSingleDataToMerge(HorizontalResolution detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ)
{
long[] dataToMerge = ThreadMapUtil.getBuilderArray()[detail.detailLevel];
long[] dataToMerge = ThreadMapUtil.getBuilderArray(detail.detailLevel);
ChunkPos chunkPos = chunk.getPos();
int size = 1 << detail.detailLevel;
@@ -38,7 +38,6 @@ import com.seibel.lod.util.LodUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.WeightedList.Entry;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.palette.UpgradeData;
import net.minecraft.util.registry.Registry;
@@ -74,7 +73,6 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker;
public class LodNodeGenWorker implements IWorker
{
public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
//public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new LodThreadFactory(LodNodeGenWorker.class.getSimpleName()));
private boolean threadStarted = false;
private LodChunkGenThread thread;
@@ -111,10 +109,6 @@ public class LodNodeGenWorker implements IWorker
newLodDimension, newServerWorld);
}
public static void resetGenerator(){
ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
}
@Override
public boolean doWork()
{
@@ -155,11 +155,8 @@ public class SingleLevelContainer implements LevelContainer
{
int index = 0;
int tempIndex;
byte[] tempData = ThreadMapUtil.getSaveContainer();
if (tempData == null || tempData.length != (1 + (size * size * 8)))
tempData = new byte[1 + (size * size * 8)];
else
Arrays.fill(tempData, (byte) 0);
byte[] tempData = ThreadMapUtil.getFreshSaveContainer(1 + (size * size * 8));
tempData[index] = detailLevel;
index++;
for (int x = 0; x < size; x++)
@@ -1,9 +1,13 @@
package com.seibel.lod.objects;
import com.seibel.lod.util.*;
import java.util.Arrays;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
public class VerticalLevelContainer implements LevelContainer
{
@@ -27,6 +31,7 @@ public class VerticalLevelContainer implements LevelContainer
return detailLevel;
}
@Override
public void clear(int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
@@ -36,6 +41,7 @@ public class VerticalLevelContainer implements LevelContainer
}
}
@Override
public boolean addData(long data, int posX, int posZ, int verticalIndex){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
@@ -44,20 +50,24 @@ public class VerticalLevelContainer implements LevelContainer
return true;
}
@Override
public boolean addSingleData(long data, int posX, int posZ){
return addData(data, posX, posZ, 0);
}
@Override
public long getData(int posX, int posZ, int verticalIndex){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return dataContainer[posX*size*maxVerticalData + posZ*maxVerticalData + verticalIndex];
}
@Override
public long getSingleData(int posX, int posZ){
return getData(posX,posZ,0);
}
@Override
public int getMaxVerticalData(){
return maxVerticalData;
}
@@ -66,6 +76,7 @@ public class VerticalLevelContainer implements LevelContainer
return size;
}
@Override
public boolean doesItExist(int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
@@ -126,19 +137,16 @@ public class VerticalLevelContainer implements LevelContainer
}
}
@Override
public LevelContainer expand(){
return new VerticalLevelContainer((byte) (getDetailLevel() - 1));
}
@Override
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{
//We reset the array
long[] dataToMerge = ThreadMapUtil.getVerticalUpdateArray()[detailLevel];
if(dataToMerge == null || dataToMerge.length != 4*lowerLevelContainer.getMaxVerticalData())
dataToMerge = new long[4 * lowerLevelContainer.getMaxVerticalData()];
else
Arrays.fill(dataToMerge, DataPointUtil.EMPTY_DATA);
long[] dataToMerge = ThreadMapUtil.getFreshVerticalUpdateArray(4 * lowerLevelContainer.getMaxVerticalData(), detailLevel);
int lowerMaxVertical = dataToMerge.length/4;
int childPosX;
@@ -157,7 +165,7 @@ public class VerticalLevelContainer implements LevelContainer
}
}
data = DataPointUtil.mergeMultiData(dataToMerge, lowerMaxVertical, getMaxVerticalData());
for(int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < maxVerticalData); verticalIndex++)
{
addData(data[verticalIndex],
@@ -167,6 +175,7 @@ public class VerticalLevelContainer implements LevelContainer
}
}
@Override
public byte[] toDataString()
{
int index = 0;
@@ -174,12 +183,9 @@ public class VerticalLevelContainer implements LevelContainer
byte last = -1;
int x = size * size * maxVerticalData;
int tempIndex;
byte[] tempData = ThreadMapUtil.getSaveContainer();
long current;
if(tempData == null || tempData.length != (2 + (x * 8)))
tempData = new byte[2 + (x * 8)];
else
Arrays.fill(tempData, (byte) 0);
byte[] tempData = ThreadMapUtil.getFreshSaveContainer(2 + (x * 8));
tempData[index] = detailLevel;
index++;
@@ -243,10 +249,12 @@ public class VerticalLevelContainer implements LevelContainer
return " ";
}
@Override
public int getMaxNumberOfLods(){
return size*size*getMaxVerticalData();
}
@Override
public int getMaxMemoryUse(){
return getMaxNumberOfLods() * 2; //2 byte
}
@@ -1,7 +1,5 @@
package com.seibel.lod.util;
import java.util.Arrays;
import com.seibel.lod.enums.DistanceGenerationMode;
import net.minecraft.client.renderer.texture.NativeImage;
@@ -279,31 +277,12 @@ public class DataPointUtil
{
int size = dataToMerge.length / inputVerticalData;
//We initialise the arrays that are going to be used
short[] projection = ThreadMapUtil.getProjectionShort();
short[] heightAndDepth = ThreadMapUtil.getHeightAndDepth();
long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge();
long[] dataPoint = ThreadMapUtil.verticalDataArray();
// We initialize the arrays that are going to be used
short[] projection = ThreadMapUtil.getFreshProjectionArray((worldHeight) / 16 + 1);
short[] heightAndDepth = ThreadMapUtil.getFreshHeightAndDepth((worldHeight + 1) * 2);
long[] singleDataToMerge = ThreadMapUtil.getFreshSingleAddDataToMerge(size);
long[] dataPoint = ThreadMapUtil.getFreshVerticalDataArray(worldHeight + 1);
if (projection == null || projection.length != (worldHeight) / 16 + 1)
projection = new short[(worldHeight) / 16 + 1];
else
Arrays.fill(projection, (short) 0);
if (heightAndDepth == null || heightAndDepth.length != (worldHeight + 1) * 2)
heightAndDepth = new short[(worldHeight + 1) * 2];
else
Arrays.fill(heightAndDepth, (short) 0);
if (singleDataToMerge == null || singleDataToMerge.length != size)
singleDataToMerge = new long[size];
else
Arrays.fill(singleDataToMerge, EMPTY_DATA);
if (dataPoint == null || dataPoint.length != worldHeight + 1)
dataPoint = new long[worldHeight + 1];
else
Arrays.fill(dataPoint, EMPTY_DATA);
int genMode = DistanceGenerationMode.SERVER.complexity;
boolean allEmpty = true;
@@ -1,8 +1,17 @@
package com.seibel.lod.util;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Holds data used by specific threads so
* the data doesn't have to be recreated every
* time it is needed.
*
* @author Leonardo Amato
* @version 9-25-2021
*/
public class ThreadMapUtil
{
public static final ConcurrentMap<String, long[]> threadSingleUpdateMap = new ConcurrentHashMap<>();
@@ -10,11 +19,20 @@ public class ThreadMapUtil
public static final ConcurrentMap<String, long[][]> threadBuilderVerticalArrayMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, long[]> threadVerticalAddDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, byte[]> saveContainer = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, short[]> projectionShortMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, short[]> projectionArrayMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, short[]> heightAndDepthMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, long[]> singleDataToMergeMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, long[][]> verticalUpdate = new ConcurrentHashMap<>();
/** returns the array filled with 0's */
public static long[] getFreshSingleUpdateArray(int arrayLength)
{
long[] array = getSingleUpdateArray();
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getSingleUpdateArray()
{
if (!threadSingleUpdateMap.containsKey(Thread.currentThread().getName()) || (threadSingleUpdateMap.get(Thread.currentThread().getName()) == null))
@@ -23,28 +41,52 @@ public class ThreadMapUtil
}
return threadSingleUpdateMap.get(Thread.currentThread().getName());
}
public static long[][] getBuilderArray()
/** returns the array filled with 0's */
public static long[] getFreshBuilderArray(int arrayLength, int detailLevel)
{
long[] array = getBuilderArray(detailLevel);
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getBuilderArray(int detailLevel)
{
if (!threadBuilderArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderArrayMap.get(Thread.currentThread().getName()) == null))
{
long[][] array = new long[5][];
threadBuilderArrayMap.put(Thread.currentThread().getName(), array);
}
return threadBuilderArrayMap.get(Thread.currentThread().getName());
return threadBuilderArrayMap.get(Thread.currentThread().getName())[detailLevel];
}
public static long[][] getBuilderVerticalArray()
/** returns the array filled with 0's */
public static long[] getFreshBuilderVerticalArray(int arrayLength, int detailLevel)
{
long[] array = getBuilderVerticalArray(detailLevel);
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getBuilderVerticalArray(int detailLevel)
{
if (!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null))
{
long[][] array = new long[5][];
threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array);
}
return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName());
return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName())[detailLevel];
}
public static long[] verticalDataArray()
/** returns the array filled with 0's */
public static long[] getFreshVerticalDataArray(int arrayLength)
{
long[] array = getVerticalDataArray();
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getVerticalDataArray()
{
if (!threadVerticalAddDataMap.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMap.get(Thread.currentThread().getName()) == null))
{
@@ -52,57 +94,148 @@ public class ThreadMapUtil
}
return threadVerticalAddDataMap.get(Thread.currentThread().getName());
}
public static short[] getProjectionShort(){
if(!projectionShortMap.containsKey(Thread.currentThread().getName()) || (projectionShortMap.get(Thread.currentThread().getName()) == null))
{
projectionShortMap.put(Thread.currentThread().getName(), new short[0]);
}
return projectionShortMap.get(Thread.currentThread().getName());
/** returns the array filled with 0's */
public static short[] getFreshProjectionArray(int arrayLength)
{
short[] array = getProjectionArray();
clearOrCreateArray(array, arrayLength);
return array;
}
public static short[] getHeightAndDepth(){
if(!heightAndDepthMap.containsKey(Thread.currentThread().getName()) || (heightAndDepthMap.get(Thread.currentThread().getName()) == null))
public static short[] getProjectionArray()
{
if (!projectionArrayMap.containsKey(Thread.currentThread().getName()) || (projectionArrayMap.get(Thread.currentThread().getName()) == null))
{
projectionArrayMap.put(Thread.currentThread().getName(), new short[0]);
}
return projectionArrayMap.get(Thread.currentThread().getName());
}
/** returns the array filled with 0's */
public static short[] getFreshHeightAndDepth(int arrayLength)
{
short[] array = getHeightAndDepth();
clearOrCreateArray(array, arrayLength);
return array;
}
public static short[] getHeightAndDepth()
{
if (!heightAndDepthMap.containsKey(Thread.currentThread().getName()) || (heightAndDepthMap.get(Thread.currentThread().getName()) == null))
{
heightAndDepthMap.put(Thread.currentThread().getName(), new short[0]);
}
return heightAndDepthMap.get(Thread.currentThread().getName());
}
public static byte[] getSaveContainer(){
if(!saveContainer.containsKey(Thread.currentThread().getName()) || (saveContainer.get(Thread.currentThread().getName()) == null))
/** returns the array filled with 0's */
public static byte[] getFreshSaveContainer(int arrayLength)
{
byte[] array = getSaveContainer();
clearOrCreateArray(array, arrayLength);
return array;
}
public static byte[] getSaveContainer()
{
if (!saveContainer.containsKey(Thread.currentThread().getName()) || (saveContainer.get(Thread.currentThread().getName()) == null))
{
saveContainer.put(Thread.currentThread().getName(), new byte[0]);
}
return saveContainer.get(Thread.currentThread().getName());
}
public static long[][] getVerticalUpdateArray(){
if(!verticalUpdate.containsKey(Thread.currentThread().getName()) || (verticalUpdate.get(Thread.currentThread().getName()) == null))
/** returns the array filled with 0's */
public static long[] getFreshVerticalUpdateArray(int arrayLength, int detailLevel)
{
long[] array = ThreadMapUtil.getVerticalUpdateArray(detailLevel);
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getVerticalUpdateArray(int detailLevel)
{
if (!verticalUpdate.containsKey(Thread.currentThread().getName()) || (verticalUpdate.get(Thread.currentThread().getName()) == null))
{
long[][] array = new long[10][];
verticalUpdate.put(Thread.currentThread().getName(), array);
}
return verticalUpdate.get(Thread.currentThread().getName());
return verticalUpdate.get(Thread.currentThread().getName())[detailLevel];
}
public static long[] getSingleAddDataToMerge(){
if(!singleDataToMergeMap.containsKey(Thread.currentThread().getName()) || (singleDataToMergeMap.get(Thread.currentThread().getName()) == null))
/** returns the array filled with 0's */
public static long[] getFreshSingleAddDataToMerge(int arrayLength)
{
long[] array = getSingleAddDataToMerge();
clearOrCreateArray(array, arrayLength);
return array;
}
public static long[] getSingleAddDataToMerge()
{
if (!singleDataToMergeMap.containsKey(Thread.currentThread().getName()) || (singleDataToMergeMap.get(Thread.currentThread().getName()) == null))
{
singleDataToMergeMap.put(Thread.currentThread().getName(), new long[0]);
}
return singleDataToMergeMap.get(Thread.currentThread().getName());
}
public static void clearMaps(){
/** clears all arrays so they will have to be rebuilt */
public static void clearMaps()
{
threadSingleUpdateMap.clear();
threadBuilderArrayMap.clear();
threadBuilderVerticalArrayMap.clear();
threadVerticalAddDataMap.clear();
saveContainer.clear();
projectionShortMap.clear();
projectionArrayMap.clear();
heightAndDepthMap.clear();
singleDataToMergeMap.clear();
verticalUpdate.clear();
}
/** fills the array with 0's */
private static void clearOrCreateArray(long[] array, int arrayLength)
{
if (array == null || array.length != arrayLength)
array = new long[arrayLength];
else
Arrays.fill(array, 0);
}
/** fills the array with 0's */
@SuppressWarnings("unused")
private static void clearOrCreateArray(int[] array, int arrayLength)
{
if (array == null || array.length != arrayLength)
array = new int[arrayLength];
else
Arrays.fill(array, 0);
}
/** fills the array with 0's */
private static void clearOrCreateArray(short[] array, int arrayLength)
{
if (array == null || array.length != arrayLength)
array = new short[arrayLength];
else
Arrays.fill(array, (short) 0);
}
/** fills the array with 0's */
private static void clearOrCreateArray(byte[] array, int arrayLength)
{
if (array == null || array.length != arrayLength)
array = new byte[arrayLength];
else
Arrays.fill(array, (byte) 0);
}
}