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.
This commit is contained in:
opfromthestart 2021-09-10 13:51:37 -04:00
parent 46bcb85044
commit 2820e01974

View File

@ -4,9 +4,8 @@ import static ru.windcorp.progressia.test.region.TestWorldDiskIO.REGION_DIAMETER
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.util.HashMap; import java.nio.ByteBuffer;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.logging.log4j.LogManager; 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 MAX_CHUNK_SIZE = 4 * 1024 * 1024;
private static final int SECTORS_BYTES = Short.BYTES; 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_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]; final byte endBytes[] = new byte[SECTOR_SIZE];
private Map<Integer, Vec3i> isFilledMap = new HashMap(); // TODO ill do this at the same time I finish the new confirmheaderhealth public static enum SectorType
public enum SectorType
{ {
Ending (0), // Just an empty block Ending (0), // Just an empty block
Data (1), // has a byte counting up in position 1, and then Data (1), // has a byte counting up in position 1, and then
@ -62,40 +59,61 @@ public class RegionFile {
int maxUsed = 0; int maxUsed = 0;
final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER; final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER;
file.seek(0);
if (file.length() < HEADER_SIZE) { if (file.length() < HEADER_SIZE) {
throw new IOException("File is too short to contain a header"); 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 for (int i = 0; i < chunksPerRegion; i++) {
// int offset = file.readInt(); file.seek(i*DEFINITION_SIZE);
// int offset = file.readInt();
// if (offset == 0) {
// continue; if (offset == 0) {
// } continue;
// }
// Vec3i pos = new Vec3i();
// pos.x = i / REGION_DIAMETER / REGION_DIAMETER; Vec3i pos = new Vec3i();
// pos.y = (i / REGION_DIAMETER) % REGION_DIAMETER; pos.x = i / REGION_DIAMETER / REGION_DIAMETER;
// pos.z = i % REGION_DIAMETER; pos.y = (i / REGION_DIAMETER) % REGION_DIAMETER;
// pos.z = i % REGION_DIAMETER;
// offsets.put(pos, offset);
// offsets.put(pos, offset);
// boolean shouldEnd = false;
// while (!shouldEnd) boolean shouldEnd = false;
// { byte counter = 0;
// if (offset > maxUsed) while (!shouldEnd)
// { {
// maxUsed = offset; if (offset > maxUsed)
// } {
// maxUsed = offset;
// if (!used.add(offset)) { }
// throw new IOException("A sector is used twice");
// } 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); LogManager.getLogger("Region").debug("Efficiency of {}", (double) used.size()/maxUsed);
} }
@ -116,14 +134,30 @@ public class RegionFile {
boolean isDone = false; boolean isDone = false;
while (!isDone) 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[0] = 1;
tempBuffer[1] = counter; tempBuffer[1] = counter;
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<buffer.length) if (loc*(SECTOR_SIZE-SECTOR_HEADER_SIZE-1) + i<buffer.length)
{ {
tempBuffer[i+SECTOR_HEADER_LENGTH+1] = buffer[loc*(SECTOR_SIZE-SECTOR_HEADER_LENGTH-1) + i]; tempBuffer[i+SECTOR_HEADER_SIZE+1] = buffer[loc*(SECTOR_SIZE-SECTOR_HEADER_SIZE-1) + i];
} }
else else
{ {
@ -134,6 +168,8 @@ public class RegionFile {
loc++; loc++;
if (file.getFilePointer()<256) if (file.getFilePointer()<256)
LogManager.getLogger("Region").debug("at {}, ({},{},{}), {}", file.getFilePointer(),pos.x,pos.y,pos.z, dataOffset); LogManager.getLogger("Region").debug("at {}, ({},{},{}), {}", file.getFilePointer(),pos.x,pos.y,pos.z, dataOffset);
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
dataOffset++;
file.write(tempBuffer); file.write(tempBuffer);
} }
@ -153,6 +189,17 @@ public class RegionFile {
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE); file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
return dataOffset; return dataOffset;
} }
private int allocateEmptySector() throws IOException
{
int outputLen = (int) file.length();
int dataOffset = (int) (outputLen - HEADER_SIZE) / SECTOR_SIZE + 1;
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
return dataOffset;
}
public byte[] readBuffer(int dataOffset) throws IOException { public byte[] readBuffer(int dataOffset) throws IOException {
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset); file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
@ -166,7 +213,7 @@ public class RegionFile {
while (!reachedEnd) while (!reachedEnd)
{ {
int bytesRead = file.read(tempBuffer, 0, SECTOR_SIZE); int bytesRead = file.read(tempBuffer, 0, SECTOR_SIZE);
if (bytesRead==0) if (bytesRead<0)
{ {
reachedEnd = true; reachedEnd = true;
continue; continue;
@ -178,7 +225,7 @@ public class RegionFile {
throw new IOException("Sectors were read out of order\nExpected chunk number "+Byte.toString(counter)+" but encountered number " + Byte.toString(tempBuffer[1])); throw new IOException("Sectors were read out of order\nExpected chunk number "+Byte.toString(counter)+" but encountered number " + Byte.toString(tempBuffer[1]));
} }
counter++; counter++;
if (buffer.length - bufferPos < SECTOR_SIZE-SECTOR_HEADER_LENGTH-1) if (buffer.length - bufferPos < SECTOR_SIZE-SECTOR_HEADER_SIZE-1)
{ {
byte newBuffer[] = new byte[buffer.length + SECTOR_SIZE*16]; byte newBuffer[] = new byte[buffer.length + SECTOR_SIZE*16];
for (int i=0;i<buffer.length;i++) // TODO dedicated copy, java-y at least for (int i=0;i<buffer.length;i++) // TODO dedicated copy, java-y at least
@ -187,11 +234,11 @@ public class RegionFile {
} }
buffer = newBuffer; buffer = newBuffer;
} }
for (int i=0;i<SECTOR_SIZE-SECTOR_HEADER_LENGTH-1;i++) for (int i=0;i<SECTOR_SIZE-SECTOR_HEADER_SIZE-1;i++)
{ {
buffer[bufferPos+i] = tempBuffer[i+2]; buffer[bufferPos+i] = tempBuffer[i+2];
} }
bufferPos += SECTOR_SIZE-SECTOR_HEADER_LENGTH-1; bufferPos += SECTOR_SIZE-SECTOR_HEADER_SIZE-1;
} }
else if (tempBuffer[0] == SectorType.Ending.data) else if (tempBuffer[0] == SectorType.Ending.data)
{ {
@ -199,7 +246,8 @@ public class RegionFile {
} }
else if (tempBuffer[0] == SectorType.PartitionLink.data) else if (tempBuffer[0] == SectorType.PartitionLink.data)
{ {
int newOffset = ((tempBuffer[4]*256 + tempBuffer[3])*256 + tempBuffer[2])*256 + tempBuffer[1]; ByteBuffer intBuffer = ByteBuffer.wrap(tempBuffer);
int newOffset = intBuffer.getInt(1);
file.seek(HEADER_SIZE + SECTOR_SIZE * newOffset); file.seek(HEADER_SIZE + SECTOR_SIZE * newOffset);
} }
else else