!include once #1027304 // Eclipse Collections import java.nio.*; import java.nio.channels.*; // read-only, so far. should be thread-safe final sclass BufferedDiskByteMemory64 implements IByteMemory64, AutoCloseable { File file; long size; // file size in ints RandomAccessFile raf; bool bigEndian = true; bool writable = false; bool debug; // byte buffers int byteBufferShift = 30; // each buffer is 1 GB int byteBufferSize = 1 << byteBufferShift; MappedByteBuffer[] byteBuffers; *(File *file) { this(file, false); } *(File *file, bool *writable) { load(file, writable); } void load(File file, bool writable default false) ctex { this.file = file; this.writable = writable; size = fileSize(file); raf = newRandomAccessFile(file, writable ? "rw" : "r"); byteBuffers = new MappedByteBuffer[toInt(rightShift_ceil(size, byteBufferShift))]; FileChannel channel = raf.getChannel(); for i over byteBuffers: { long pos = (long) i << byteBufferShift; int len = toInt(min(1 << byteBufferShift, size-pos)); //print("Mapping bytes " + longToHex(pos) + "-" + longToHex(pos+len)); byteBuffers[i] = channel.map(FileChannel.MapMode.READ_ONLY, pos, len); byteBuffers[i].order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); } } public void close { dispose raf; } public byte getByte(long idx) { rangeCheck(idx, size); ret byteBuffers[(int) (idx >> byteBufferShift)].get(((int) idx) & (byteBufferSize-1)); } public int getInt(long idx) { int ofs = ((int) idx) & (byteBufferSize-1); // check if we are crossing a buffer boundary if (ofs > byteBufferSize-4) ret getInt_manual(idx); try { ret byteBuffers[(int) (idx >> byteBufferShift)].getInt(ofs); } on fail { print(+idx); } } public int getInt_manual(long idx) { assertTrue(+bigEndian); ret ubyteToInt(getByte(idx)) << 24 | ubyteToInt(getByte(idx+1)) << 16 | ubyteToInt(getByte(idx+2)) << 8 | ubyteToInt(getByte(idx+3)); } public void set(long idx, int val) { checkWritable(); fail("todo"); } void checkWritable { if (!writable) fail("read-only"); } public long size() { ret size; } public void ensureSize(int size) { this.size = max(this.size, size); } }