From 2820e019741b23f6b43c96a9dc364f2b2a3c2d24 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Fri, 10 Sep 2021 13:51:37 -0400 Subject: [PATCH] Finished Partition Logic Note: it still does waste a lot of space, I will work on that next -Added back the confirmHeaderHealth logic -Checks to make sure it will not overwrite important chunks -Uses PartitionLink chunks to move to a different part of the file -Added allocateEmptySector() to allow for the file size to be increased without moving the origin point of the chunk. --- .../progressia/test/region/RegionFile.java | 136 ++++++++++++------ 1 file changed, 92 insertions(+), 44 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/region/RegionFile.java b/src/main/java/ru/windcorp/progressia/test/region/RegionFile.java index f37aaa4..385d97d 100644 --- a/src/main/java/ru/windcorp/progressia/test/region/RegionFile.java +++ b/src/main/java/ru/windcorp/progressia/test/region/RegionFile.java @@ -4,9 +4,8 @@ import static ru.windcorp.progressia.test.region.TestWorldDiskIO.REGION_DIAMETER import java.io.IOException; import java.io.RandomAccessFile; -import java.util.HashMap; +import java.nio.ByteBuffer; import java.util.HashSet; -import java.util.Map; import java.util.Set; import org.apache.logging.log4j.LogManager; @@ -23,13 +22,11 @@ public class RegionFile { private static final int MAX_CHUNK_SIZE = 4 * 1024 * 1024; private static final int SECTORS_BYTES = Short.BYTES; private static final int SECTOR_SIZE = MAX_CHUNK_SIZE >> (SECTORS_BYTES*8); - private static final int SECTOR_HEADER_LENGTH = 1; + private static final int SECTOR_HEADER_SIZE = 1; final byte endBytes[] = new byte[SECTOR_SIZE]; - private Map isFilledMap = new HashMap(); // TODO ill do this at the same time I finish the new confirmheaderhealth - - public enum SectorType + public static enum SectorType { Ending (0), // Just an empty block Data (1), // has a byte counting up in position 1, and then @@ -62,40 +59,61 @@ public class RegionFile { int maxUsed = 0; final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER; - file.seek(0); - if (file.length() < HEADER_SIZE) { throw new IOException("File is too short to contain a header"); } -// for (int i = 0; i < chunksPerRegion; i++) { // TODO ill make the rest in a bit -// int offset = file.readInt(); -// -// if (offset == 0) { -// continue; -// } -// -// Vec3i pos = new Vec3i(); -// pos.x = i / REGION_DIAMETER / REGION_DIAMETER; -// pos.y = (i / REGION_DIAMETER) % REGION_DIAMETER; -// pos.z = i % REGION_DIAMETER; -// -// offsets.put(pos, offset); -// -// boolean shouldEnd = false; -// while (!shouldEnd) -// { -// if (offset > maxUsed) -// { -// maxUsed = offset; -// } -// -// if (!used.add(offset)) { -// throw new IOException("A sector is used twice"); -// } -// -// } -// } + for (int i = 0; i < chunksPerRegion; i++) { + file.seek(i*DEFINITION_SIZE); + int offset = file.readInt(); + + if (offset == 0) { + continue; + } + + Vec3i pos = new Vec3i(); + pos.x = i / REGION_DIAMETER / REGION_DIAMETER; + pos.y = (i / REGION_DIAMETER) % REGION_DIAMETER; + pos.z = i % REGION_DIAMETER; + + offsets.put(pos, offset); + + boolean shouldEnd = false; + byte counter = 0; + while (!shouldEnd) + { + if (offset > maxUsed) + { + maxUsed = offset; + } + + if (!used.add(offset)) { + throw new IOException("A sector is used twice"); + } + + file.seek(HEADER_SIZE + SECTOR_SIZE*offset); + byte type = file.readByte(); + + if (type == SectorType.Data.data) + { + byte fileCounter = file.readByte(); + if (fileCounter != counter) + { + throw new IOException("An unexpected block was found"); + } + counter++; + offset++; + } + else if (type == SectorType.Ending.data) { + shouldEnd = true; + } + else if (type == SectorType.PartitionLink.data) + { + offset = file.readInt(); + } + + } + } LogManager.getLogger("Region").debug("Efficiency of {}", (double) used.size()/maxUsed); } @@ -116,14 +134,30 @@ public class RegionFile { boolean isDone = false; while (!isDone) { + if (file.length() > HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1)) { + file.seek(HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1)); + byte header = file.readByte(); + if (header == SectorType.Data.data) { + byte fileCounter = file.readByte(); + if (fileCounter != counter+1) // This makes the actual + // partition place + { + int newOffset = allocateEmptySector(); + file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset); + file.write(2); + file.writeInt(newOffset); + dataOffset = newOffset; + } + } + } tempBuffer[0] = 1; tempBuffer[1] = counter; counter++; - for (int i=0;i<(SECTOR_SIZE-SECTOR_HEADER_LENGTH-1);i++) + for (int i=0;i<(SECTOR_SIZE-SECTOR_HEADER_SIZE-1);i++) { - if (loc*(SECTOR_SIZE-SECTOR_HEADER_LENGTH-1) + i