General update/polish. (Add more pref dumpping)
This commit is contained in:
@@ -585,6 +585,8 @@ public class LodBufferBuilderFactory
|
||||
long bufferCount = 0;
|
||||
long fullBufferCount = 0;
|
||||
long totalUsage = 0;
|
||||
long builderCount = 0;
|
||||
long totalBuilderUsage = 0;
|
||||
int maxLength = MAX_TRIANGLES_PER_BUFFER*(LodUtil.LOD_VERTEX_FORMAT.getByteSize()*3);
|
||||
for (LodVertexBuffer[] buffers : buildableVbos) {
|
||||
if (buffers == null) continue;
|
||||
@@ -600,6 +602,11 @@ public class LodBufferBuilderFactory
|
||||
totalUsage += b.size;
|
||||
}
|
||||
}
|
||||
for (LodBufferBuilder builder : buildableBuffers) {
|
||||
if (builder == null) continue;
|
||||
builderCount++;
|
||||
totalBuilderUsage += builder.getMemUsage();
|
||||
}
|
||||
for (LodVertexBuffer[] buffers : drawableVbos) {
|
||||
if (buffers == null) continue;
|
||||
LodVertexBuffer[] bs = buffers.clone();
|
||||
@@ -617,6 +624,8 @@ public class LodBufferBuilderFactory
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.info("Buffers: [{}], Full-sized Buffers: [{}], Total: [{}]",
|
||||
bufferCount, fullBufferCount, new UnitBytes(totalUsage));
|
||||
ramLogger.info("Builders: [{}], Total: [{}]",
|
||||
builderCount, new UnitBytes(totalBuilderUsage));
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.incLogTries();
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class LodBuilder
|
||||
private boolean writeAllLodNodeData(LodDimension lodDim, LodRegion region, int chunkX, int chunkZ,
|
||||
long[] data, LodBuilderConfig config, boolean override)
|
||||
{
|
||||
region.isWriting++;
|
||||
region.isWriting.incrementAndGet();
|
||||
try {
|
||||
if (region.getMinDetailLevel()!= 0) {
|
||||
if (!LodUtil.checkRamUsage(0.05, 16)) {
|
||||
@@ -230,7 +230,7 @@ public class LodBuilder
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
region.isWriting--;
|
||||
region.isWriting.decrementAndGet();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -238,7 +238,7 @@ public class LodBuilder
|
||||
private boolean writePartialLodNodeData(LodDimension lodDim, LodRegion region, int chunkX, int chunkZ,
|
||||
long[] data, LodBuilderConfig config, boolean override)
|
||||
{
|
||||
region.isWriting++;
|
||||
region.isWriting.incrementAndGet();
|
||||
try {
|
||||
byte targetLevel = region.getMinDetailLevel();
|
||||
int vertQual = DetailDistanceUtil.getMaxVerticalData(targetLevel);
|
||||
@@ -295,7 +295,7 @@ public class LodBuilder
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
region.isWriting--;
|
||||
region.isWriting.decrementAndGet();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -37,12 +38,15 @@ import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
|
||||
|
||||
import com.seibel.lod.core.api.ClientApi;
|
||||
import com.seibel.lod.core.enums.config.VerticalQuality;
|
||||
import com.seibel.lod.core.objects.lod.LevelContainer;
|
||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
||||
import com.seibel.lod.core.objects.lod.LodRegion;
|
||||
import com.seibel.lod.core.objects.lod.RegionPos;
|
||||
import com.seibel.lod.core.objects.lod.VerticalLevelContainer;
|
||||
import com.seibel.lod.core.util.LodThreadFactory;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.util.SpamReducedLogger;
|
||||
import com.seibel.lod.core.util.UnitBytes;
|
||||
|
||||
|
||||
/**
|
||||
@@ -316,6 +320,47 @@ public class LodDimensionFileHandler
|
||||
public void addRegionsToSave(LodRegion r) {
|
||||
regionToSave.put(r.getRegionPos(), r);
|
||||
}
|
||||
|
||||
private final SpamReducedLogger ramLogger = new SpamReducedLogger(1);
|
||||
public void dumpBufferMemoryUsage() {
|
||||
if (!ramLogger.canMaybeLog()) return;
|
||||
ArrayList<LodRegion> regions = new ArrayList<LodRegion>(regionToSave.values());
|
||||
ramLogger.info("Dumping Ram Usage for file writer for {} with {} regions...",
|
||||
lodDimension.dimension.getDimensionName(), regions.size());
|
||||
int nonNullRegionCount = 0;
|
||||
int nonDirtiedRegionCount = 0;
|
||||
int writingRegionCount = 0;
|
||||
long totalUsage = 0;
|
||||
int[] detailCount = new int[LodUtil.DETAIL_OPTIONS];
|
||||
long[] detailUsage = new long[LodUtil.DETAIL_OPTIONS];
|
||||
for (LodRegion r : regions) {
|
||||
if (r==null) continue;
|
||||
nonNullRegionCount++;
|
||||
if (!r.needSaving) nonDirtiedRegionCount++;
|
||||
if (r.isWriting.get() != 0) writingRegionCount++;
|
||||
LevelContainer[] container = r.debugGetDataContainers().clone();
|
||||
if (container == null || container.length != LodUtil.DETAIL_OPTIONS) {
|
||||
ClientApi.LOGGER.warn("DumpRamUsage encountered an invalid region!");
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
if (container[i] == null) continue;
|
||||
detailCount[i]++;
|
||||
long byteUsage = container[i].getRoughRamUsage();
|
||||
detailUsage[i] += byteUsage;
|
||||
totalUsage += byteUsage;
|
||||
}
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.info("Non Null Regions: [{}], Non-Dirtied Regions: [{}], Writing Regions: [{}], Bytes: [{}]",
|
||||
nonNullRegionCount, nonDirtiedRegionCount, writingRegionCount, new UnitBytes(totalUsage));
|
||||
ramLogger.info("------------------------------------------------");
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
ramLogger.info("DETAIL {}: Containers: [{}], Bytes: [{}]", i, detailCount[i], new UnitBytes(detailUsage[i]));
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.incLogTries();
|
||||
}
|
||||
|
||||
/** Save all dirty regions in this LodDimension to file */
|
||||
public void saveDirtyRegionsToFile(boolean blockUntilFinished)
|
||||
@@ -380,9 +425,9 @@ public class LodDimensionFileHandler
|
||||
// this for loop should be safe and loop until all values are gone.
|
||||
while (!regionToSave.isEmpty()) {
|
||||
for (LodRegion r : regionToSave.values()) {
|
||||
r.isWriting++;
|
||||
|
||||
try {
|
||||
if (r.isWriting>1) continue;
|
||||
if (r.isWriting.getAndIncrement()>0) continue;
|
||||
//Check if the data has been swapped out right under me. Otherwise remove it from the entry
|
||||
if (!regionToSave.remove(r.getRegionPos(), r)) continue;
|
||||
r.needSaving = false;
|
||||
@@ -399,7 +444,7 @@ public class LodDimensionFileHandler
|
||||
{
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
r.isWriting--;
|
||||
r.isWriting.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ public class LodDimension
|
||||
|
||||
LodRegion region = regions.get(x+minPos.x, z+minPos.y);
|
||||
if (region != null && region.needSaving) totalDirtiedRegions++;
|
||||
if (region != null && !region.needSaving && region.isWriting==0) {
|
||||
if (region != null && !region.needSaving && region.isWriting.get()==0) {
|
||||
// check what detail level this region should be
|
||||
// and cut it if it is higher then that
|
||||
minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, x+minPos.x, z+minPos.y,
|
||||
@@ -366,7 +366,7 @@ public class LodDimension
|
||||
regionZ = z + minPos.y;
|
||||
final RegionPos regionPos = new RegionPos(regionX, regionZ);
|
||||
region = regions.get(regionX, regionZ);
|
||||
if (region != null && region.isWriting!=0) return; // FIXME: A crude attempt at lowering chance of race condition!
|
||||
if (region != null && region.isWriting.get()!=0) return; // FIXME: A crude attempt at lowering chance of race condition!
|
||||
|
||||
minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ, playerPosX,
|
||||
playerPosZ);
|
||||
@@ -716,15 +716,12 @@ public class LodDimension
|
||||
if (r==null) continue;
|
||||
nonNullRegionCount++;
|
||||
if (r.needSaving) dirtiedRegionCount++;
|
||||
if (r.isWriting != 0) writingRegionCount++;
|
||||
if (r.isWriting.get() != 0) writingRegionCount++;
|
||||
LevelContainer[] container = r.debugGetDataContainers().clone();
|
||||
if (container == null || container.length != LodUtil.DETAIL_OPTIONS) {
|
||||
ClientApi.LOGGER.warn("DumpRamUsage encountered an invalid region!");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
if (container[i] == null) continue;
|
||||
detailCount[i]++;
|
||||
@@ -742,6 +739,7 @@ public class LodDimension
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.incLogTries();
|
||||
fileHandler.dumpBufferMemoryUsage();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package com.seibel.lod.core.objects.lod;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.core.enums.config.DropoffQuality;
|
||||
import com.seibel.lod.core.enums.config.GenerationPriority;
|
||||
@@ -69,7 +72,7 @@ public class LodRegion {
|
||||
public volatile boolean needRecheckGenPoint = true;
|
||||
public volatile int needRegenBuffer = 2;
|
||||
public volatile boolean needSaving = false;
|
||||
public volatile int isWriting = 0;
|
||||
public final AtomicInteger isWriting = new AtomicInteger(0);
|
||||
|
||||
public static byte calculateFarModeSwitch(byte targetLevel) {
|
||||
if (targetLevel==0) return 0; // Always use detail 0 if it's way too close
|
||||
@@ -100,7 +103,7 @@ public class LodRegion {
|
||||
* @return true if the data was added successfully
|
||||
*/
|
||||
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data) {
|
||||
assert(isWriting!=0);
|
||||
if(isWriting.get()<=0) throw new ConcurrentModificationException("isWriting counter lock should have been aquired!");
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
|
||||
@@ -121,7 +124,7 @@ public class LodRegion {
|
||||
* @return true if the data was added successfully
|
||||
*/
|
||||
public boolean addVerticalData(byte detailLevel, int posX, int posZ, long[] data, boolean override) {
|
||||
assert(isWriting!=0);
|
||||
if(isWriting.get()<=0) throw new ConcurrentModificationException("isWriting counter lock should have been aquired!");
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
|
||||
@@ -145,7 +148,7 @@ public class LodRegion {
|
||||
* @return true if the data was added successfully
|
||||
*/
|
||||
public boolean addChunkOfData(byte detailLevel, int posX, int posZ, int widthX, int widthZ, long[] data, int verticalSize, boolean override) {
|
||||
assert(isWriting!=0);
|
||||
if(isWriting.get()<=0) throw new ConcurrentModificationException("isWriting counter lock should have been aquired!");
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ public class LodBufferBuilder
|
||||
this.buffer = allocateByteBuffer(bufferSizeInBytes * 4);
|
||||
}
|
||||
|
||||
public int getMemUsage() {return buffer.capacity();}
|
||||
|
||||
|
||||
|
||||
/** originally from MC's GLAllocation class */
|
||||
|
||||
@@ -261,10 +261,9 @@ public class DataPointUtil
|
||||
|
||||
/** Return (>0) if dataA should replace dataB, (0) if equal, (<0) if dataB should replace dataA */
|
||||
public static int compareDatapointPriority(long dataA, long dataB) {
|
||||
if (dataA==0 || dataB==0) {
|
||||
if (dataA!=0) dataA = Integer.MAX_VALUE;
|
||||
if (dataB!=0) dataB = Integer.MAX_VALUE;
|
||||
return (int)(dataA-dataB);
|
||||
if (!doesItExist(dataA) || !doesItExist(dataB)) {
|
||||
if (doesItExist(dataA)) return Integer.MAX_VALUE;
|
||||
if (doesItExist(dataB)) return Integer.MIN_VALUE;
|
||||
}
|
||||
int genA = (int)getGenerationMode(dataA);
|
||||
int genB = (int)getGenerationMode(dataB);
|
||||
|
||||
Reference in New Issue
Block a user