diff --git a/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java b/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java index e513b52..b94f79d 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java +++ b/src/main/java/ru/windcorp/progressia/common/util/HashableVec3i.java @@ -20,7 +20,16 @@ public class HashableVec3i { @Override public boolean equals(Object comparee) { - return hashCode() == comparee.hashCode(); + if (comparee == null) + { + return false; + } + if (comparee.getClass() != HashableVec3i.class) + { + return false; + } + HashableVec3i compareeCast = (HashableVec3i) comparee; + return compareeCast.value == value; } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java index 7122c25..6859028 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java +++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java @@ -25,12 +25,15 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.RandomAccessFile; -import java.nio.channels.Channels; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -57,7 +60,7 @@ public class TestWorldDiskIO { private static final String formatFile = "world.format"; private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO"); - private static HashMap randomAccessMap; + private static HashMap mappedByteMap; private static final boolean ENABLE = true; private static int maxSize = 1048576; @@ -75,8 +78,8 @@ public class TestWorldDiskIO { private static int natFromInt(int loc) { if (loc < 0) - return (-loc) << 1 + 1; - return loc << 1; + return -2*loc - 1; + return 2*loc; } /* @@ -89,10 +92,40 @@ public class TestWorldDiskIO { */ private static Vec3i getRegion(Vec3i chunkLoc) { + int x = chunkLoc.x; + if (x<0) + { + x /= regionSize.x; + x--; + } + else + { + x /= regionSize.x; + } + int y = chunkLoc.y; + if (y<0) + { + y /= regionSize.y; + y--; + } + else + { + y /= regionSize.y; + } + int z = chunkLoc.z; + if (z<0) + { + z /= regionSize.z; + z--; + } + else + { + z /= regionSize.z; + } return new Vec3i( - natFromInt(chunkLoc.x / regionSize.x), - natFromInt(chunkLoc.y / regionSize.y), - natFromInt(chunkLoc.z / regionSize.z) + natFromInt(x), + natFromInt(y), + natFromInt(z) ); } @@ -115,9 +148,19 @@ public class TestWorldDiskIO { // regions.put(new Vec3i(0,0,0), new Vec3i(1,1,1)); } + + public static int getAvailableSector(MappedByteBuffer mbb) + { + int sectorsUsed = 0; + for (int i=offsetBytes; i<(offsetBytes+1)*chunksPerRegion; i+= (offsetBytes+1)) + { + sectorsUsed += mbb.get(i); + } + return sectorsUsed; + } private static void setRegionSize(int format) { - randomAccessMap = new HashMap(); + mappedByteMap = new HashMap(); switch (format) { case 0: case 1: @@ -232,38 +275,54 @@ public class TestWorldDiskIO { */ - RandomAccessFile output = randomAccessMap.get(new HashableVec3i(saveCoords)); + MappedByteBuffer output = mappedByteMap.get(new HashableVec3i(saveCoords)); + LOG.info("saveCoords {},{},{}", saveCoords.x, saveCoords.y, saveCoords.z); if (output == null) { - output = new RandomAccessFile(path.toFile(), "rw"); - randomAccessMap.put(new HashableVec3i(saveCoords), output); + output = makeNew(path, new HashableVec3i(saveCoords)); } // LOG.debug(output.read()); - if (output.read() < 0) { + if (output.get() < 0) { LOG.info("Making header"); - output.writeChars("\0".repeat((offsetBytes + 1) * chunksPerRegion)); + ByteBuffer headerBytes = ByteBuffer.allocate((offsetBytes + 1) * chunksPerRegion); + for (int i=0;i<(offsetBytes + 1) * chunksPerRegion;i++) + { + headerBytes.put(i, (byte) 0); + } + output.put(headerBytes); } Vec3i pos = getRegionLoc(chunk.getPosition()); int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x)); int fullOffset = (offsetBytes + 1) * (chunksPerRegion); - output.seek(shortOffset); - int offset = output.readInt(); - int sectorLength = offset & 255; - offset = offset >> 8; + output.position(shortOffset); + int offset = 0; + for (int i = 0; i < offsetBytes; i++) { + offset *= 256; + offset += output.get(); + } + ByteBuffer readOffset = ByteBuffer.allocate(offsetBytes); + int sectorLength = output.get(); if (sectorLength == 0) { - int outputLen = (int) output.length(); - offset = (int) (outputLen - fullOffset) / sectorSize + 1; - output.seek(shortOffset); - output.writeInt(offset << 8); - output.seek(outputLen); - /* - * while (output.length()