!include once #1027304 // Eclipse Collections import java.nio.*; import java.nio.channels.*; // read-only, so far. should be thread-safe final sclass BufferedDiskByteMemory64 implements IIntMemory64, AutoCloseable { File file; long size; // file size in ints RandomAccessFile raf; bool bigEndian = true; bool writable = true; bool debug; // byte buffers int byteBufferShift = 30; // each buffer is 1 GB long byteBufferSize = 1 << byteBufferShift; MappedByteBuffer[] byteBuffers; *(File *file) { this(file, false); } *(File *file, bool *writable) { this(); load(file, writable); } void load(File file, bool writable default false) ctex { this.file = file; this.writable = writable; size = fileSize(file)/4; 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+2); int len = toInt(min(1 << (byteBufferShift+2), size*4-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 synchronized void close { dispose raf; } ifndef BufferedDiskByteMemory64_unsynchronized synchronized endifndef public int get(long idx) { rangeCheck(idx, size); if (l1cache == null) ret get_raw(idx); long val = l1cache.getIfAbsent(idx, Long.MAX_VALUE); if (val == Long.MAX_VALUE) l1cache.put(idx, val = get_raw(idx)); ret (int) val; } public byte getByte(long idx) { ret byteBuffers[(int) (idx >> byteBufferShift)].getByte((int) (idx & (byteBufferSize-1))); } public byte getInt(long idx) { // TODO: check if we hit a buffer boundary ret byteBuffers[(int) (idx >> byteBufferShift)].getInt((int) (idx & (byteBufferSize-1))); } public synchronized void set(long idx, int val) { checkWritable(); rangeCheck(idx, size); CacheEntry e = loadCell(idx); e.data[(int) idx & (pageSize-1)] = val; e.dirty = true; } void checkWritable { if (!writable) fail("read-only"); } public long size() { ret size; } public synchronized void ensureSize(int size) { this.size = max(this.size, size); } }