Add ColumnWorldCompressionMode to the database
This commit is contained in:
+6
-3
@@ -20,7 +20,7 @@
|
||||
package com.seibel.distanthorizons.api.enums.config;
|
||||
|
||||
/**
|
||||
* UNCOMPRESSED <br>
|
||||
* MERGE_SAME_BLOCKS <br>
|
||||
* VISUALLY_EQUAL <br><br>
|
||||
*
|
||||
* @version 2024-3-27
|
||||
@@ -32,8 +32,11 @@ public enum EDhApiWorldCompressionMode
|
||||
// when adding items up the API minor version
|
||||
// when removing items up the API major version
|
||||
|
||||
/** Every block/biome change is recorded in the database. */
|
||||
UNCOMPRESSED(0),
|
||||
/**
|
||||
* Every block/biome change is recorded in the database. <br>
|
||||
* This is what DH 2.0 and 2.0.1 all used by default and will store a lot of data.
|
||||
*/
|
||||
MERGE_SAME_BLOCKS(0),
|
||||
|
||||
/**
|
||||
* Only visible block/biome changes are recorded in the database. <Br>
|
||||
|
||||
+45
-4
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiWorldCompressionMode;
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder;
|
||||
@@ -93,6 +94,11 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
* @see EDhApiWorldGenerationStep
|
||||
*/
|
||||
public byte[] columnGenerationSteps;
|
||||
/**
|
||||
* stores what world compression was used for each column.
|
||||
* @see EDhApiWorldCompressionMode
|
||||
*/
|
||||
public byte[] columnWorldCompressionMode;
|
||||
|
||||
/**
|
||||
* stored x/z, y <br>
|
||||
@@ -122,10 +128,11 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
// doesn't need to be populated since nothing has been generated yet
|
||||
// the default value of all 0's is adequate
|
||||
this.columnGenerationSteps = new byte[WIDTH * WIDTH];
|
||||
this.columnWorldCompressionMode = new byte[WIDTH * WIDTH];
|
||||
}
|
||||
|
||||
public static FullDataSourceV2 createWithData(DhSectionPos pos, FullDataPointIdMap mapping, LongArrayList[] data, byte[] columnGenerationStep) { return new FullDataSourceV2(pos, mapping, data, columnGenerationStep); }
|
||||
private FullDataSourceV2(DhSectionPos pos, FullDataPointIdMap mapping, LongArrayList[] data, byte[] columnGenerationSteps)
|
||||
public static FullDataSourceV2 createWithData(DhSectionPos pos, FullDataPointIdMap mapping, LongArrayList[] data, byte[] columnGenerationStep, byte[] columnWorldCompressionMode) { return new FullDataSourceV2(pos, mapping, data, columnGenerationStep, columnWorldCompressionMode); }
|
||||
private FullDataSourceV2(DhSectionPos pos, FullDataPointIdMap mapping, LongArrayList[] data, byte[] columnGenerationSteps, byte[] columnWorldCompressionMode)
|
||||
{
|
||||
LodUtil.assertTrue(data.length == WIDTH * WIDTH);
|
||||
|
||||
@@ -135,6 +142,7 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
this.isEmpty = false;
|
||||
|
||||
this.columnGenerationSteps = columnGenerationSteps;
|
||||
this.columnWorldCompressionMode = columnWorldCompressionMode;
|
||||
}
|
||||
|
||||
public static FullDataSourceV2 createFromChunk(IChunkWrapper chunkWrapper) { return LodDataBuilder.createGeneratedDataSource(chunkWrapper); }
|
||||
@@ -152,6 +160,7 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
|
||||
// Note: this logic only works if the data point data is the same between both versions
|
||||
byte[] columnGenerationSteps = new byte[WIDTH * WIDTH];
|
||||
byte[] columnWorldCompressionMode = new byte[WIDTH * WIDTH];
|
||||
LongArrayList[] dataPoints = new LongArrayList[WIDTH * WIDTH];
|
||||
for (int x = 0; x < WIDTH; x++)
|
||||
{
|
||||
@@ -197,11 +206,12 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
// the old data sources didn't have a generation step written down
|
||||
// if the column has any data points, assume it's fully generated, otherwise assume it's empty
|
||||
columnGenerationSteps[index] = (columnHasNonAirBlock ? EDhApiWorldGenerationStep.LIGHT.value : EDhApiWorldGenerationStep.EMPTY.value);
|
||||
columnWorldCompressionMode[index] = EDhApiWorldCompressionMode.MERGE_SAME_BLOCKS.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FullDataSourceV2 fullDataSource = FullDataSourceV2.createWithData(legacyData.getSectionPos(), legacyData.mapping, dataPoints, columnGenerationSteps);
|
||||
FullDataSourceV2 fullDataSource = FullDataSourceV2.createWithData(legacyData.getSectionPos(), legacyData.mapping, dataPoints, columnGenerationSteps, columnWorldCompressionMode);
|
||||
|
||||
|
||||
// should only be used if debugging, this is a very expensive operation
|
||||
@@ -361,7 +371,10 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.columnGenerationSteps[index] = inputGenState;
|
||||
// always overwrite the compression mode since we're replacing this column
|
||||
this.columnWorldCompressionMode[index] = inputDataSource.columnWorldCompressionMode[index];
|
||||
this.isEmpty = false;
|
||||
}
|
||||
}
|
||||
@@ -407,6 +420,11 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
this.columnGenerationSteps[recipientIndex] = inputGenStep;
|
||||
|
||||
|
||||
// world compression //
|
||||
byte worldCompressionMode = determineHighestWorldCompressionForTwoByTwoColumn(inputDataSource.columnWorldCompressionMode, x, z);
|
||||
this.columnWorldCompressionMode[recipientIndex] = worldCompressionMode;
|
||||
|
||||
|
||||
|
||||
// data points //
|
||||
LongArrayList mergedInputDataArray = mergeInputTwoByTwoDataColumn(inputDataSource, x, z);
|
||||
@@ -465,6 +483,7 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
*/
|
||||
private static byte determineMinWorldGenStepForTwoByTwoColumn(byte[] columnGenerationSteps, int relX, int relZ)
|
||||
{
|
||||
// TODO merge similar logic with determineHighestWorldCompressionForTwoByTwoColumn
|
||||
byte minWorldGenStepValue = Byte.MAX_VALUE;
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
@@ -477,6 +496,25 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
}
|
||||
return minWorldGenStepValue;
|
||||
}
|
||||
/**
|
||||
* The minimum value is used because we don't want to accidentally record that
|
||||
* something was generated when it wasn't.
|
||||
*/
|
||||
private static byte determineHighestWorldCompressionForTwoByTwoColumn(byte[] columnCompressionMode, int relX, int relZ)
|
||||
{
|
||||
// TODO merge similar logic with determineMinWorldGenStepForTwoByTwoColumn
|
||||
byte minWorldGenStepValue = Byte.MIN_VALUE;
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
for (int z = 0; z < 2; z++)
|
||||
{
|
||||
int index = relativePosToIndex(x + relX, z + relZ);
|
||||
byte worldGenStepValue = columnCompressionMode[index];
|
||||
minWorldGenStepValue = (byte) Math.max(minWorldGenStepValue, worldGenStepValue);
|
||||
}
|
||||
}
|
||||
return minWorldGenStepValue;
|
||||
}
|
||||
private static LongArrayList mergeInputTwoByTwoDataColumn(FullDataSourceV2 inputDataSource, int x, int z)
|
||||
{
|
||||
LongArrayList newColumnList = new LongArrayList();
|
||||
@@ -817,11 +855,12 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
return EDhApiWorldGenerationStep.fromValue(this.columnGenerationSteps[index]);
|
||||
}
|
||||
|
||||
public void setSingleColumn(LongArrayList longArray, int relX, int relZ, EDhApiWorldGenerationStep worldGenStep)
|
||||
public void setSingleColumn(LongArrayList longArray, int relX, int relZ, EDhApiWorldGenerationStep worldGenStep, EDhApiWorldCompressionMode worldCompressionMode)
|
||||
{
|
||||
int index = relativePosToIndex(relX, relZ);
|
||||
this.dataPoints[index] = longArray;
|
||||
this.columnGenerationSteps[index] = worldGenStep.value;
|
||||
this.columnWorldCompressionMode[index] = worldCompressionMode.value;
|
||||
|
||||
|
||||
if (RUN_UPDATE_DEV_VALIDATION)
|
||||
@@ -863,6 +902,7 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
int result = this.pos.hashCode();
|
||||
result = 31 * result + Arrays.deepHashCode(this.dataPoints);
|
||||
result = 17 * result + Arrays.hashCode(this.columnGenerationSteps);
|
||||
result = 43 * result + Arrays.hashCode(this.columnWorldCompressionMode);
|
||||
|
||||
this.cachedHashCode = result;
|
||||
}
|
||||
@@ -938,6 +978,7 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
}
|
||||
|
||||
Arrays.fill(dataSource.columnGenerationSteps, (byte) 0);
|
||||
Arrays.fill(dataSource.columnWorldCompressionMode, (byte) 0);
|
||||
}
|
||||
|
||||
return dataSource;
|
||||
|
||||
+33
-3
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.core.sql.dto;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiDataCompressionMode;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiWorldCompressionMode;
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
@@ -50,6 +51,8 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
|
||||
/** @see EDhApiWorldGenerationStep */
|
||||
public byte[] compressedColumnGenStepByteArray;
|
||||
/** @see EDhApiWorldCompressionMode */
|
||||
public byte[] compressedWorldCompressionModeByteArray;
|
||||
|
||||
public byte[] compressedMappingByteArray;
|
||||
|
||||
@@ -71,11 +74,12 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
{
|
||||
CheckedByteArray checkedDataPointArray = writeDataSourceDataArrayToBlob(dataSource.dataPoints, compressionModeEnum);
|
||||
byte[] compressedWorldGenStepByteArray = writeGenerationStepsToBlob(dataSource.columnGenerationSteps, compressionModeEnum);
|
||||
byte[] compressedWorldCompressionModeByteArray = writeWorldCompressionModeToBlob(dataSource.columnWorldCompressionMode, compressionModeEnum);
|
||||
byte[] mappingByteArray = writeDataMappingToBlob(dataSource.mapping, compressionModeEnum);
|
||||
|
||||
return new FullDataSourceV2DTO(
|
||||
dataSource.getSectionPos(),
|
||||
checkedDataPointArray.checksum, compressedWorldGenStepByteArray, FullDataSourceV2.DATA_FORMAT_VERSION, compressionModeEnum, checkedDataPointArray.byteArray,
|
||||
checkedDataPointArray.checksum, compressedWorldGenStepByteArray, compressedWorldCompressionModeByteArray, FullDataSourceV2.DATA_FORMAT_VERSION, compressionModeEnum, checkedDataPointArray.byteArray,
|
||||
dataSource.lastModifiedUnixDateTime, dataSource.createdUnixDateTime,
|
||||
mappingByteArray, dataSource.applyToParent,
|
||||
dataSource.levelMinY
|
||||
@@ -84,7 +88,7 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
|
||||
public FullDataSourceV2DTO(
|
||||
DhSectionPos pos,
|
||||
int dataChecksum, byte[] compressedColumnGenStepByteArray, byte dataFormatVersion, EDhApiDataCompressionMode compressionModeEnum, byte[] compressedDataByteArray,
|
||||
int dataChecksum, byte[] compressedColumnGenStepByteArray, byte[] compressedWorldCompressionModeByteArray, byte dataFormatVersion, EDhApiDataCompressionMode compressionModeEnum, byte[] compressedDataByteArray,
|
||||
long lastModifiedUnixDateTime, long createdUnixDateTime,
|
||||
byte[] compressedMappingByteArray, boolean applyToParent,
|
||||
int levelMinY)
|
||||
@@ -92,6 +96,7 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
this.pos = pos;
|
||||
this.dataChecksum = dataChecksum;
|
||||
this.compressedColumnGenStepByteArray = compressedColumnGenStepByteArray;
|
||||
this.compressedWorldCompressionModeByteArray = compressedWorldCompressionModeByteArray;
|
||||
|
||||
this.dataFormatVersion = dataFormatVersion;
|
||||
this.compressionModeEnum = compressionModeEnum;
|
||||
@@ -133,10 +138,11 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
{
|
||||
if (FullDataSourceV2.DATA_FORMAT_VERSION != this.dataFormatVersion)
|
||||
{
|
||||
throw new IllegalStateException("There should only be one data format right now anyway.");
|
||||
throw new IllegalStateException("There should only be one data format ["+FullDataSourceV2.DATA_FORMAT_VERSION+"].");
|
||||
}
|
||||
|
||||
dataSource.columnGenerationSteps = readBlobToGenerationSteps(this.compressedColumnGenStepByteArray, this.compressionModeEnum);
|
||||
dataSource.columnWorldCompressionMode = readBlobToGenerationSteps(this.compressedWorldCompressionModeByteArray, this.compressionModeEnum);
|
||||
dataSource.dataPoints = readBlobToDataSourceDataArray(this.compressedDataByteArray, this.compressionModeEnum);
|
||||
|
||||
dataSource.mapping.clear(dataSource.getSectionPos());
|
||||
@@ -260,6 +266,30 @@ public class FullDataSourceV2DTO implements IBaseDTO<DhSectionPos>
|
||||
}
|
||||
|
||||
|
||||
private static byte[] writeWorldCompressionModeToBlob(byte[] worldCompressionModeByteArray, EDhApiDataCompressionMode compressionModeEnum) throws IOException
|
||||
{
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
DhDataOutputStream compressedOut = new DhDataOutputStream(byteArrayOutputStream, compressionModeEnum);
|
||||
|
||||
compressedOut.write(worldCompressionModeByteArray);
|
||||
|
||||
compressedOut.flush();
|
||||
byteArrayOutputStream.close();
|
||||
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
private static byte[] readBlobToWorldCompressionMode(byte[] dataByteArray, EDhApiDataCompressionMode compressionModeEnum) throws IOException, InterruptedException
|
||||
{
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(dataByteArray);
|
||||
DhDataInputStream compressedIn = new DhDataInputStream(byteArrayInputStream, compressionModeEnum);
|
||||
|
||||
byte[] worldCompressionModeByteArray = new byte[FullDataSourceV2.WIDTH * FullDataSourceV2.WIDTH];
|
||||
compressedIn.readFully(worldCompressionModeByteArray);
|
||||
|
||||
return worldCompressionModeByteArray;
|
||||
}
|
||||
|
||||
|
||||
private static byte[] writeDataMappingToBlob(FullDataPointIdMap mapping, EDhApiDataCompressionMode compressionModeEnum) throws IOException
|
||||
{
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
+7
-3
@@ -86,6 +86,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
|
||||
byte[] dataByteArray = (byte[]) objectMap.get("Data");
|
||||
byte[] columnGenStepByteArray = (byte[]) objectMap.get("ColumnGenerationStep");
|
||||
byte[] columnWorldCompressionByteArray = (byte[]) objectMap.get("ColumnWorldCompressionMode");
|
||||
byte[] mappingByteArray = (byte[]) objectMap.get("Mapping");
|
||||
|
||||
|
||||
@@ -100,7 +101,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
|
||||
FullDataSourceV2DTO dto = new FullDataSourceV2DTO(
|
||||
pos,
|
||||
dataChecksum, columnGenStepByteArray, dataFormatVersion, compressionModeEnum, dataByteArray,
|
||||
dataChecksum, columnGenStepByteArray, columnWorldCompressionByteArray, dataFormatVersion, compressionModeEnum, dataByteArray,
|
||||
lastModifiedUnixDateTime, createdUnixDateTime,
|
||||
mappingByteArray, applyToParent,
|
||||
minY);
|
||||
@@ -114,13 +115,13 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
"INSERT INTO "+this.getTableName() + " (\n" +
|
||||
" DetailLevel, PosX, PosZ, \n" +
|
||||
" MinY, DataChecksum, \n" +
|
||||
" Data, ColumnGenerationStep, Mapping, \n" +
|
||||
" Data, ColumnGenerationStep, ColumnWorldCompressionMode, Mapping, \n" +
|
||||
" DataFormatVersion, CompressionMode, ApplyToParent, \n" +
|
||||
" LastModifiedUnixDateTime, CreatedUnixDateTime) \n" +
|
||||
"VALUES( \n" +
|
||||
" ?, ?, ?, \n" +
|
||||
" ?, ?, \n" +
|
||||
" ?, ?, ?, \n" +
|
||||
" ?, ?, ?, ?, \n" +
|
||||
" ?, ?, ?, \n" +
|
||||
" ?, ? \n" +
|
||||
");";
|
||||
@@ -136,6 +137,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
|
||||
statement.setObject(i++, dto.compressedDataByteArray);
|
||||
statement.setObject(i++, dto.compressedColumnGenStepByteArray);
|
||||
statement.setObject(i++, dto.compressedWorldCompressionModeByteArray);
|
||||
statement.setObject(i++, dto.compressedMappingByteArray);
|
||||
|
||||
statement.setObject(i++, dto.dataFormatVersion);
|
||||
@@ -159,6 +161,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
|
||||
" ,Data = ? \n" +
|
||||
" ,ColumnGenerationStep = ? \n" +
|
||||
" ,ColumnWorldCompressionMode = ? \n" +
|
||||
" ,Mapping = ? \n" +
|
||||
|
||||
" ,DataFormatVersion = ? \n" +
|
||||
@@ -177,6 +180,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<DhSectionPos, FullDataS
|
||||
|
||||
statement.setObject(i++, dto.compressedDataByteArray);
|
||||
statement.setObject(i++, dto.compressedColumnGenStepByteArray);
|
||||
statement.setObject(i++, dto.compressedWorldCompressionModeByteArray);
|
||||
statement.setObject(i++, dto.compressedMappingByteArray);
|
||||
|
||||
statement.setObject(i++, dto.dataFormatVersion);
|
||||
|
||||
@@ -770,18 +770,18 @@
|
||||
"Full",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiDataCompressionMode.UNCOMPRESSED":
|
||||
"Uncompressed",
|
||||
"1. Uncompressed",
|
||||
"distanthorizons.config.enum.EDhApiDataCompressionMode.LZ4":
|
||||
"LZ4",
|
||||
"2. LZ4",
|
||||
"distanthorizons.config.enum.EDhApiDataCompressionMode.Z_STD":
|
||||
"Zstd",
|
||||
"3. Zstd",
|
||||
"distanthorizons.config.enum.EDhApiDataCompressionMode.LZMA2":
|
||||
"LZMA2",
|
||||
"4. LZMA2",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiWorldCompressionMode.UNCOMPRESSED":
|
||||
"Uncompressed",
|
||||
"distanthorizons.config.enum.EDhApiWorldCompressionMode.MERGE_SAME_BLOCKS":
|
||||
"1. Merge Same Blocks",
|
||||
"distanthorizons.config.enum.EDhApiWorldCompressionMode.VISUALLY_EQUAL":
|
||||
"Visually Equal",
|
||||
"2. Visually Equal",
|
||||
|
||||
"distanthorizons.config.enum.ELightGenerationMode.DISTANT_HORIZONS":
|
||||
"Distant Horizons",
|
||||
|
||||
@@ -24,6 +24,7 @@ CREATE TABLE FullData (
|
||||
|
||||
,Data BLOB NULL
|
||||
,ColumnGenerationStep BLOB NULL
|
||||
,ColumnWorldCompressionMode BLOB NULL
|
||||
,Mapping BLOB NULL
|
||||
|
||||
,DataFormatVersion TINYINT NULL
|
||||
|
||||
Reference in New Issue
Block a user