Fixes n Speed n Stuff
-Better comparison for HashableVec3i -Changed RandomAccessFile to MappedByteBuffer -natFromInt now works properly -better region selection -Changes to make different strategies work
This commit is contained in:
parent
e4ced6507e
commit
fae09edb16
@ -20,7 +20,16 @@ public class HashableVec3i {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object comparee)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,15 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
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.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -57,7 +60,7 @@ public class TestWorldDiskIO {
|
|||||||
private static final String formatFile = "world.format";
|
private static final String formatFile = "world.format";
|
||||||
private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO");
|
private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO");
|
||||||
|
|
||||||
private static HashMap<HashableVec3i, RandomAccessFile> randomAccessMap;
|
private static HashMap<HashableVec3i, MappedByteBuffer> mappedByteMap;
|
||||||
private static final boolean ENABLE = true;
|
private static final boolean ENABLE = true;
|
||||||
|
|
||||||
private static int maxSize = 1048576;
|
private static int maxSize = 1048576;
|
||||||
@ -75,8 +78,8 @@ public class TestWorldDiskIO {
|
|||||||
|
|
||||||
private static int natFromInt(int loc) {
|
private static int natFromInt(int loc) {
|
||||||
if (loc < 0)
|
if (loc < 0)
|
||||||
return (-loc) << 1 + 1;
|
return -2*loc - 1;
|
||||||
return loc << 1;
|
return 2*loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -89,10 +92,40 @@ public class TestWorldDiskIO {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private static Vec3i getRegion(Vec3i chunkLoc) {
|
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(
|
return new Vec3i(
|
||||||
natFromInt(chunkLoc.x / regionSize.x),
|
natFromInt(x),
|
||||||
natFromInt(chunkLoc.y / regionSize.y),
|
natFromInt(y),
|
||||||
natFromInt(chunkLoc.z / regionSize.z)
|
natFromInt(z)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,9 +148,19 @@ public class TestWorldDiskIO {
|
|||||||
|
|
||||||
// regions.put(new Vec3i(0,0,0), new Vec3i(1,1,1));
|
// 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) {
|
private static void setRegionSize(int format) {
|
||||||
randomAccessMap = new HashMap<HashableVec3i, RandomAccessFile>();
|
mappedByteMap = new HashMap<HashableVec3i, MappedByteBuffer>();
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
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)
|
if (output == null)
|
||||||
{
|
{
|
||||||
output = new RandomAccessFile(path.toFile(), "rw");
|
output = makeNew(path, new HashableVec3i(saveCoords));
|
||||||
randomAccessMap.put(new HashableVec3i(saveCoords), output);
|
|
||||||
}
|
}
|
||||||
// LOG.debug(output.read());
|
// LOG.debug(output.read());
|
||||||
if (output.read() < 0) {
|
if (output.get() < 0) {
|
||||||
LOG.info("Making header");
|
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());
|
Vec3i pos = getRegionLoc(chunk.getPosition());
|
||||||
int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
|
int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
|
||||||
int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
|
int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
|
||||||
output.seek(shortOffset);
|
output.position(shortOffset);
|
||||||
int offset = output.readInt();
|
int offset = 0;
|
||||||
int sectorLength = offset & 255;
|
for (int i = 0; i < offsetBytes; i++) {
|
||||||
offset = offset >> 8;
|
offset *= 256;
|
||||||
|
offset += output.get();
|
||||||
|
}
|
||||||
|
ByteBuffer readOffset = ByteBuffer.allocate(offsetBytes);
|
||||||
|
int sectorLength = output.get();
|
||||||
if (sectorLength == 0) {
|
if (sectorLength == 0) {
|
||||||
int outputLen = (int) output.length();
|
//int outputLen = (int) output.size();
|
||||||
offset = (int) (outputLen - fullOffset) / sectorSize + 1;
|
//offset = (int) (outputLen - fullOffset) / sectorSize + 1;
|
||||||
output.seek(shortOffset);
|
offset = getAvailableSector(output);
|
||||||
output.writeInt(offset << 8);
|
output.position(shortOffset);
|
||||||
output.seek(outputLen);
|
|
||||||
/*
|
//readInt.putInt(offset<<8);
|
||||||
* while (output.length()<fullOffset+sectorSize*offset)
|
for (int i=0;i<offsetBytes;i++)
|
||||||
* {
|
{
|
||||||
* output.write((int) (output.length()%256));
|
readOffset.put(offsetBytes-i-1, (byte) (offset<<8));
|
||||||
* }
|
}
|
||||||
*/
|
output.put(readOffset);
|
||||||
output.setLength(fullOffset + offset * sectorSize);
|
/*output.position(outputLen);
|
||||||
|
|
||||||
|
while (output.size()<fullOffset+sectorSize*offset)
|
||||||
|
{
|
||||||
|
output.write(ByteBuffer.wrap( new byte[]{0} ));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//output.setLength(fullOffset + offset * sectorSize);
|
||||||
// output.write(200);
|
// output.write(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,11 +360,11 @@ public class TestWorldDiskIO {
|
|||||||
|
|
||||||
byte tempData[] = tempDataStream.toByteArray();
|
byte tempData[] = tempDataStream.toByteArray();
|
||||||
|
|
||||||
output.seek((long) fullOffset + sectorSize * offset);
|
output.position( fullOffset + sectorSize * offset);
|
||||||
output.write(tempData);
|
output.put(ByteBuffer.wrap( tempData));
|
||||||
|
|
||||||
output.seek(shortOffset + offsetBytes);
|
output.position(shortOffset + offsetBytes);
|
||||||
output.write((int) tempData.length / sectorSize + 1);
|
output.put(ByteBuffer.wrap( new byte[] {(byte) (tempData.length / sectorSize + 1)}));
|
||||||
// LOG.info("Used {} sectors",(int)
|
// LOG.info("Used {} sectors",(int)
|
||||||
// tempData.length/sectorSize + 1);
|
// tempData.length/sectorSize + 1);
|
||||||
|
|
||||||
@ -316,6 +375,23 @@ public class TestWorldDiskIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MappedByteBuffer makeNew(Path path, Object hashObj) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");
|
||||||
|
FileChannel fc = raf.getChannel();
|
||||||
|
MappedByteBuffer output = fc.map(FileChannel.MapMode.READ_WRITE, 0, maxSize*chunksPerRegion);
|
||||||
|
output.limit(maxSize*chunksPerRegion);
|
||||||
|
mappedByteMap.put((HashableVec3i) hashObj, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
LOG.warn("bad things");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void writeGenerationHint(ChunkData chunk, DataOutputStream output, Server server)
|
private static void writeGenerationHint(ChunkData chunk, DataOutputStream output, Server server)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint());
|
server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint());
|
||||||
@ -535,13 +611,17 @@ public class TestWorldDiskIO {
|
|||||||
private static ChunkData loadRegion(Path path, Vec3i chunkPos, WorldData world, Server server)
|
private static ChunkData loadRegion(Path path, Vec3i chunkPos, WorldData world, Server server)
|
||||||
throws IOException,
|
throws IOException,
|
||||||
DecodingException {
|
DecodingException {
|
||||||
|
try
|
||||||
|
{
|
||||||
Vec3i streamCoords = getRegion(chunkPos);
|
Vec3i streamCoords = getRegion(chunkPos);
|
||||||
|
|
||||||
RandomAccessFile input = randomAccessMap.get(new HashableVec3i(streamCoords));
|
MappedByteBuffer input = mappedByteMap.get(new HashableVec3i(streamCoords));
|
||||||
|
LOG.info("streamCoords {},{},{}", streamCoords.x,streamCoords.y,streamCoords.z);
|
||||||
if (input == null)
|
if (input == null)
|
||||||
{
|
{
|
||||||
input = new RandomAccessFile(path.toFile(), "rw");
|
//input = new RandomAccessFile(path.toFile(), "rw");
|
||||||
randomAccessMap.put(new HashableVec3i(streamCoords), input);
|
//input = Files.newByteChannel(path);
|
||||||
|
input = makeNew(path, new HashableVec3i(streamCoords));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOG.info(path.toString());
|
// LOG.info(path.toString());
|
||||||
@ -549,19 +629,19 @@ public class TestWorldDiskIO {
|
|||||||
|
|
||||||
int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
|
int shortOffset = (offsetBytes + 1) * (pos.z + regionSize.z * (pos.y + regionSize.y * pos.x));
|
||||||
int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
|
int fullOffset = (offsetBytes + 1) * (chunksPerRegion);
|
||||||
input.seek(shortOffset);
|
input.position(shortOffset);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (int i = 0; i < offsetBytes; i++) {
|
for (int i = 0; i < offsetBytes; i++) {
|
||||||
offset *= 256;
|
offset *= 256;
|
||||||
offset += input.read();
|
offset += input.get();
|
||||||
}
|
}
|
||||||
int sectorLength = input.read();
|
int sectorLength = input.get();
|
||||||
input.seek(fullOffset + sectorSize * offset);
|
input.position(fullOffset + sectorSize * offset);
|
||||||
|
|
||||||
// LOG.info("Read {} sectors", sectorLength);
|
// LOG.info("Read {} sectors", sectorLength);
|
||||||
|
|
||||||
byte tempData[] = new byte[sectorSize * sectorLength];
|
byte tempData[] = new byte[sectorSize * sectorLength];
|
||||||
input.read(tempData);
|
input.get(tempData);
|
||||||
|
|
||||||
DataInputStream trueInput = new DataInputStream(
|
DataInputStream trueInput = new DataInputStream(
|
||||||
new InflaterInputStream(new BufferedInputStream(new ByteArrayInputStream(tempData)))
|
new InflaterInputStream(new BufferedInputStream(new ByteArrayInputStream(tempData)))
|
||||||
@ -569,6 +649,13 @@ public class TestWorldDiskIO {
|
|||||||
ChunkData chunk = ChunkIO.load(world, chunkPos, trueInput, IOContext.SAVE);
|
ChunkData chunk = ChunkIO.load(world, chunkPos, trueInput, IOContext.SAVE);
|
||||||
readGenerationHint(chunk, trueInput, server);
|
readGenerationHint(chunk, trueInput, server);
|
||||||
return chunk;
|
return chunk;
|
||||||
|
}
|
||||||
|
catch (EOFException e)
|
||||||
|
{
|
||||||
|
LOG.warn("Reached end of file");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void readGenerationHint(ChunkData chunk, DataInputStream input, Server server)
|
private static void readGenerationHint(ChunkData chunk, DataInputStream input, Server server)
|
||||||
|
Reference in New Issue
Block a user