General update/polish. (Add more pref dumpping)

This commit is contained in:
tom lee
2022-02-09 18:03:49 +08:00
parent 1b27161518
commit cbcb7ca6ac
7 changed files with 77 additions and 21 deletions
@@ -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);