!include once #1027304 // Eclipse Collections import java.nio.*; import java.nio.channels.*; // read-only, so far. should be thread-safe // reads whole file into huge byte arrays on start final sclass RAMByteMemory64 implements IByteMemory64, AutoCloseable { File file; // the file we loaded long size; // file size in ints bool bigEndian = true; bool debug; // byte buffers int arrayShift = 30; // each buffer is 1 GB int arraySize = 1 << arrayShift; byte[][] arrays; *() {} *(File file) { load(file); } void load(File file) ctex { this.file = file; size = fileSize(file); temp RandomAccessFile raf = newRandomAccessFile(file, "r"); arrays = new byte[toInt(rightShift_ceil(size, arrayShift))][]; FileChannel channel = raf.getChannel(); print("Allocating " + n2(size) + " bytes"); for i over arrays: { long pos = (long) i << arrayShift; int len = toInt(min(1 << arrayShift, size-pos)); arrays[i] = new byte[len]; } for i over arrays: { long pos = (long) i << arrayShift; int len = l(arrays[i]); print("Loading bytes " + longToHex(pos) + "-" + longToHex(pos+len) + " of " + file); MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, pos, len); byteBuffer.get(arrays[i]); } print(size + " bytes loaded"); } public void close {} public byte getByte(long idx) { rangeCheck(idx, size); ret arrays[(int) (idx >> arrayShift)][(((int) idx) & (arraySize-1))]; } public int getInt(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 { fail("read-only"); } public long size() { ret size; } public void ensureSize(int size) { this.size = max(this.size, size); } void importVirtual(virtual RAMByteMemory64 mem) { copyFields(mem, this); } }