diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataPointIdMap.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataPointIdMap.java index 61a29f3e5..0cb0df50f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataPointIdMap.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataPointIdMap.java @@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.dataObjects.fullData; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataOutputStream; @@ -118,6 +119,8 @@ public class FullDataPointIdMap /** @return -1 if the list is empty */ public int getMaxValidId() { return this.entryList.size() - 1; } + public int size() { return this.entryList.size(); } + public boolean isEmpty() { return this.entryList.isEmpty(); } public DhSectionPos getPos() { return this.pos; } @@ -169,9 +172,67 @@ public class FullDataPointIdMap } } + /** allows for adding duplicate {@link Entry} */ + private void add(Entry biomeBlockStateEntry, boolean useWriteLocks) + { + try + { + if (useWriteLocks) + { + this.readWriteLock.writeLock().lock(); + } + + + int id = this.entryList.size(); + this.entryList.add(biomeBlockStateEntry); + this.idMap.put(biomeBlockStateEntry, id); + } + finally + { + if (useWriteLocks) + { + this.readWriteLock.writeLock().unlock(); + } + } + } + /** - * Adds each entry from the given map to this map. + * Adds every {@link Entry} from inputMap into this map.
+ * Allows duplicate entries.

+ * + * Allowing duplicate entries should be done if a datasource is just being read in and + * a merge step isn't being done afterwards. If duplicates are removed it may cause + * the ID's to get out of sync since everything will be shifted down after the removed + * ID(s). + */ + public void addAll(FullDataPointIdMap inputMap) + { + try + { + //LOGGER.trace("adding {" + this.pos + ", " + this.entryList.size() + "} and {" + inputMap.pos + ", " + inputMap.entryList.size() + "}"); + + inputMap.readWriteLock.readLock().lock(); + this.readWriteLock.writeLock().lock(); + + ArrayList entriesToMerge = inputMap.entryList; + for (int i = 0; i < entriesToMerge.size(); i++) + { + Entry entity = entriesToMerge.get(i); + this.add(entity, false); + } + } + finally + { + this.readWriteLock.writeLock().unlock(); + inputMap.readWriteLock.readLock().unlock(); + + //LOGGER.trace("finished merging {" + this.pos + ", " + this.entryList.size() + "} and {" + inputMap.pos + ", " + inputMap.entryList.size() + "}"); + } + } + + /** + * Adds each entry from the given map to this map.

* * Note: when using this function be careful about re-mapping the * same data source multiple times. @@ -302,6 +363,12 @@ public class FullDataPointIdMap //LOGGER.trace("deserialized " + pos + " " + newMap.entryList.size() + "-" + entityCount); + if (newMap.size() != entityCount) + { + // if the mappings are out of sync then the LODs will render incorrectly due to IDs being wrong + LodUtil.assertNotReach("ID maps failed to deserialize for pos: "+pos+", incorrect entity count. Expected count ["+entityCount+"], actual count ["+newMap.size()+"]"); + } + return newMap; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/sql/dto/FullDataSourceV2DTO.java b/core/src/main/java/com/seibel/distanthorizons/core/sql/dto/FullDataSourceV2DTO.java index 728a6d350..99ba7e88a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/sql/dto/FullDataSourceV2DTO.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/sql/dto/FullDataSourceV2DTO.java @@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.util.FullDataPointUtil; +import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataOutputStream; @@ -171,7 +172,13 @@ public class FullDataSourceV2DTO implements IBaseDTO throw new NullPointerException("No level wrapper present, unable to deserialize data map. This should only be used for unit tests."); } - dataSource.mapping.mergeAndReturnRemappedEntityIds(readBlobToDataMapping(this.compressedMappingByteArray, dataSource.getPos(), levelWrapper, compressionModeEnum)); + FullDataPointIdMap newMap = readBlobToDataMapping(this.compressedMappingByteArray, dataSource.getPos(), levelWrapper, compressionModeEnum); + dataSource.mapping.addAll(newMap); + if (dataSource.mapping.size() != newMap.size()) + { + // if the mappings are out of sync then the LODs will render incorrectly due to IDs being wrong + LodUtil.assertNotReach("ID maps out of sync for pos: "+this.pos); + } } dataSource.lastModifiedUnixDateTime = this.lastModifiedUnixDateTime;