Introduced map util and now the Loading does not create new String object.

This commit is contained in:
Leonardo
2021-09-11 15:56:46 +02:00
parent 1395e32a50
commit bdcc4c7755
6 changed files with 149 additions and 64 deletions
@@ -10,11 +10,6 @@ public interface LevelContainer
{
public static final char VERTICAL_DATA_DELIMITER = '\t';
public static final char DATA_DELIMITER = ',';
public static final ConcurrentMap<String,long[]> threadAddDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadGetDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadSingleUpdateMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[][][]> threadVerticalUpdateMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,int[]> threadVerticalIndexesMap = new ConcurrentHashMap();
/**With this you can add data to the level container
*
* @param data actual data to add in a array of long format.
@@ -25,10 +25,7 @@ import java.util.concurrent.Executors;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.*;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.util.math.ChunkPos;
@@ -446,12 +443,7 @@ public class LodDimension
LodRegion region = getRegion(regionPosX, regionPosZ);
if (region == null)
return false;
;
if(!LevelContainer.threadAddDataMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadAddDataMap.get(Thread.currentThread().getName()) == null))
{
LevelContainer.threadAddDataMap.put(Thread.currentThread().getName(), new long[10]);
}
long[] dataArray = LevelContainer.threadAddDataMap.get(Thread.currentThread().getName());
long[] dataArray = ThreadMapUtil.getSingleAddDataArray();
dataArray[0] = lodDataPoint;
boolean nodeAdded = region.addData(detailLevel, posX, posZ, dataArray, serverQuality);
// only save valid LODs to disk
@@ -2,10 +2,7 @@ package com.seibel.lod.objects;
import com.seibel.lod.builders.LodBuilder;
import com.seibel.lod.enums.DistanceGenerationMode;
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.*;
public class SingleLevelContainer implements LevelContainer
{
@@ -35,20 +32,16 @@ public class SingleLevelContainer implements LevelContainer
data[posX][posZ] = newData;
return true;
}
public long[] getData(int posX, int posZ){
if(!LevelContainer.threadGetDataMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadGetDataMap.get(Thread.currentThread().getName()) == null))
{
LevelContainer.threadGetDataMap.put(Thread.currentThread().getName(), new long[1]);
}
long[] dataArray = LevelContainer.threadGetDataMap.get(Thread.currentThread().getName());
long[] dataArray = ThreadMapUtil.getSingleGetDataArray();
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
//Improve this using a thread map to long[]
dataArray[0] = data[posX][posZ];
return dataArray;
}
private long getSingleData(int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
@@ -66,23 +59,35 @@ public class SingleLevelContainer implements LevelContainer
public SingleLevelContainer(String inputString)
{
int tempIndex;
int shift = 0;
int index = 0;
int lastIndex = 0;
index = inputString.indexOf(DATA_DELIMITER, 0);
detailLevel = (byte) Integer.parseInt(inputString.substring(0, index));
int digit;
char currentChar;
long newData;
currentChar = inputString.charAt(index);
digit = Character.digit(currentChar,16);
detailLevel = (byte) digit;
size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
this.data = new long[size][size];
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
lastIndex = index;
index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1);
data[x][z] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16);
newData = 0;
for(tempIndex = 0; tempIndex < 16; tempIndex++)
{
currentChar = inputString.charAt(index+tempIndex);
if(currentChar == ','){
break;
}
shift = (15-tempIndex)*4;
digit = Character.digit(currentChar,16);
newData += ((long) (digit & 0xf)) << shift;
}
newData = newData >>> (shift);
data[x][z] = newData;
index = index + tempIndex;
}
}
}
@@ -90,11 +95,7 @@ public class SingleLevelContainer implements LevelContainer
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{
//We reset the array
if(!LevelContainer.threadGetDataMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadGetDataMap.get(Thread.currentThread().getName()) == null))
{
LevelContainer.threadGetDataMap.put(Thread.currentThread().getName(), new long[4]);
}
long[] dataToMerge = LevelContainer.threadGetDataMap.get(Thread.currentThread().getName());
long[] dataToMerge = ThreadMapUtil.getSingleUpdateArray();
int childPosX;
int childPosZ;
@@ -1,9 +1,9 @@
package com.seibel.lod.objects;
/*
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
/*
public class VerticalLevelContainer implements LevelContainer
{
@@ -75,6 +75,33 @@ public class VerticalLevelContainer implements LevelContainer
return new SingleLevelContainer((byte) (getDetailLevel() - 1));
}
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{
//We reset the array
if(!LevelContainer.threadGetDataMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadGetDataMap.get(Thread.currentThread().getName()) == null))
{
LevelContainer.threadGetDataMap.put(Thread.currentThread().getName(), new long[4]);
}
long[] dataToMerge = LevelContainer.threadGetDataMap.get(Thread.currentThread().getName());
int childPosX;
int childPosZ;
long data = 0;
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
{
childPosX = 2 * posX + x;
childPosZ = 2 * posZ + z;
dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ)[0];
}
}
data = DataPointUtil.mergeSingleData(dataToMerge);
addData(data,posX,posZ);
}
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{
long[][][] updateTemps;
@@ -46,11 +46,12 @@ public class DataPointUtil
public static long createDataPoint(int height, int depth, int color, int lightValue, int generationMode)
{
int alpha = ColorUtil.getAlpha(color);
int red = ColorUtil.getRed(color);
int green = ColorUtil.getGreen(color);
int blue = ColorUtil.getBlue(color);
return createDataPoint(alpha, red, green, blue, height, depth, lightValue, generationMode);
return createDataPoint(
ColorUtil.getAlpha(color),
ColorUtil.getRed(color),
ColorUtil.getGreen(color),
ColorUtil.getBlue(color),
height, depth, lightValue, generationMode);
}
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightValue, int generationMode)
@@ -62,15 +63,15 @@ public class DataPointUtil
dataPoint += (blue & BLUE_MASK) << BLUE_SHIFT;
dataPoint += (height & HEIGHT_MASK) << HEIGHT_SHIFT;
dataPoint += (depth & DEPTH_MASK) << DEPTH_SHIFT;
dataPoint += (depth & LIGHT_MASK) << LIGHT_SHIFT;
dataPoint += (depth & GEN_TYPE_MASK) << GEN_TYPE_SHIFT;
dataPoint += (lightValue & LIGHT_MASK) << LIGHT_SHIFT;
dataPoint += (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT;
dataPoint += EXISTENCE_MASK << EXISTENCE_SHIFT;
return dataPoint;
}
public static short getHeight(long dataPoint)
{
return (short) ((dataPoint >> HEIGHT_SHIFT) & HEIGHT_MASK);
return (short) ((dataPoint >>> HEIGHT_SHIFT) & HEIGHT_MASK);
}
public static short getDepth(long dataPoint)
@@ -81,51 +82,48 @@ public class DataPointUtil
public static short getAlpha(long dataPoint)
{
return (short) ((dataPoint >> ALPHA_SHIFT) & ALPHA_MASK);
return (short) ((dataPoint >>> ALPHA_SHIFT) & ALPHA_MASK);
}
public static short getRed(long dataPoint)
{
return (short) ((dataPoint >> RED_SHIFT) & RED_MASK);
return (short) ((dataPoint >>> RED_SHIFT) & RED_MASK);
}
public static short getGreen(long dataPoint)
{
return (short) ((dataPoint >> GREEN_SHIFT) & GREEN_MASK);
return (short) ((dataPoint >>> GREEN_SHIFT) & GREEN_MASK);
}
public static short getBlue(long dataPoint)
{
return (short) ((dataPoint >> BLUE_SHIFT) & BLUE_MASK);
return (short) ((dataPoint >>> BLUE_SHIFT) & BLUE_MASK);
}
public static byte getLightValue(long dataPoint)
{
return (byte) ((dataPoint >> LIGHT_SHIFT) & LIGHT_MASK);
return (byte) ((dataPoint >>> LIGHT_SHIFT) & LIGHT_MASK);
}
public static byte getGenerationMode(long dataPoint)
{
return (byte) ((dataPoint >> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
return (byte) ((dataPoint >>> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
}
public static boolean isItVoid(long dataPoint)
{
return (((dataPoint >> VOID_SHIFT) & VOID_MASK) == 1);
return (((dataPoint >>> VOID_SHIFT) & VOID_MASK) == 1);
}
public static boolean doesItExist(long dataPoint)
{
return (((dataPoint >> EXISTENCE_SHIFT) & EXISTENCE_MASK) == 1);
return (((dataPoint >>> EXISTENCE_SHIFT) & EXISTENCE_MASK) == 1);
}
public static int getColor(long dataPoint)
{
int R = (getRed(dataPoint) << 16) & 0x00FF0000;
int G = (getGreen(dataPoint) << 8) & 0x0000FF00;
int B = getBlue(dataPoint) & 0x000000FF;
return 0xFF000000 | R | G | B;
return (int) ((dataPoint >>> COLOR_SHIFT) & COLOR_MASK);
}
public static String toString(long dataPoint)
@@ -157,7 +155,6 @@ public class DataPointUtil
int tempDepth = 0;
int tempLight = 0;
byte tempGenMode = DistanceGenerationMode.SERVER.complexity;
long newData = 0;
for(long data : dataToMerge)
{
if (DataPointUtil.doesItExist(data))
@@ -0,0 +1,73 @@
package com.seibel.lod.util;
import com.seibel.lod.objects.LevelContainer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ThreadMapUtil
{
public static final ConcurrentMap<String,long[]> threadSingleAddDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadSingleGetDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadVerticalAddDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadVerticalGetDataMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[]> threadSingleUpdateMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,long[][][]> threadVerticalUpdateMap = new ConcurrentHashMap();
public static final ConcurrentMap<String,int[]> threadVerticalIndexesMap = new ConcurrentHashMap();
public static long[] getSingleAddDataArray(){
if(!threadSingleAddDataMap.containsKey(Thread.currentThread().getName()) || (threadSingleAddDataMap.get(Thread.currentThread().getName()) == null))
{
threadSingleAddDataMap.put(Thread.currentThread().getName(), new long[1]);
}
return threadSingleAddDataMap.get(Thread.currentThread().getName());
}
public static long[] getSingleGetDataArray(){
if(!threadSingleGetDataMap.containsKey(Thread.currentThread().getName()) || (threadSingleGetDataMap.get(Thread.currentThread().getName()) == null))
{
threadSingleGetDataMap.put(Thread.currentThread().getName(), new long[1]);
}
return threadSingleGetDataMap.get(Thread.currentThread().getName());
}
public static long[] getSingleUpdateArray(){
if(!threadSingleUpdateMap.containsKey(Thread.currentThread().getName()) || (threadSingleUpdateMap.get(Thread.currentThread().getName()) == null))
{
threadSingleUpdateMap.put(Thread.currentThread().getName(), new long[4]);
}
return threadSingleUpdateMap.get(Thread.currentThread().getName());
}
public static long[] addVerticalDataArray(){
if(!threadVerticalAddDataMap.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMap.get(Thread.currentThread().getName()) == null))
{
threadVerticalAddDataMap.put(Thread.currentThread().getName(), new long[16]);
}
return threadVerticalAddDataMap.get(Thread.currentThread().getName());
}
public static long[] getVerticalGetDataArray(){
if(!threadVerticalGetDataMap.containsKey(Thread.currentThread().getName()) || (threadVerticalGetDataMap.get(Thread.currentThread().getName()) == null))
{
threadVerticalGetDataMap.put(Thread.currentThread().getName(), new long[16]);
}
return threadVerticalGetDataMap.get(Thread.currentThread().getName());
}
public static long[][][] getVerticalUpdateArray(){
if(!threadVerticalUpdateMap.containsKey(Thread.currentThread().getName()) || (threadVerticalUpdateMap.get(Thread.currentThread().getName()) == null))
{
threadVerticalUpdateMap.put(Thread.currentThread().getName(), new long[4][4][16]);
}
return threadVerticalUpdateMap.get(Thread.currentThread().getName());
}
public static int[] getVerticalIndexesArray(){
if(!threadVerticalIndexesMap.containsKey(Thread.currentThread().getName()) || (threadVerticalIndexesMap.get(Thread.currentThread().getName()) == null))
{
threadVerticalIndexesMap.put(Thread.currentThread().getName(), new int[4]);
}
return threadVerticalIndexesMap.get(Thread.currentThread().getName());
}
}