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.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<Integer, Vec3i> 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<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
{
@ -134,6 +168,8 @@ public class RegionFile {
loc++;
if (file.getFilePointer()<256)
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);
}
@ -154,6 +190,17 @@ public class RegionFile {
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 {
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
@ -166,7 +213,7 @@ public class RegionFile {
while (!reachedEnd)
{
int bytesRead = file.read(tempBuffer, 0, SECTOR_SIZE);
if (bytesRead==0)
if (bytesRead<0)
{
reachedEnd = true;
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]));
}
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];
for (int i=0;i<buffer.length;i++) // TODO dedicated copy, java-y at least
@ -187,11 +234,11 @@ public class RegionFile {
}
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];
}
bufferPos += SECTOR_SIZE-SECTOR_HEADER_LENGTH-1;
bufferPos += SECTOR_SIZE-SECTOR_HEADER_SIZE-1;
}
else if (tempBuffer[0] == SectorType.Ending.data)
{
@ -199,7 +246,8 @@ public class RegionFile {
}
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);
}
else