public static ObjectFile createObjectFileDisk(String filename) { BufferChannel file = BufferChannelFile.create(filename) ; return new ObjectFileStorage(file) ; }
@Override public long write(ByteBuffer bb) { log("W") ; if ( inAllocWrite ) Log.error(this, "In the middle of an alloc-write") ; inAllocWrite = false ; if ( writeBuffer == null ) { long x = rawWrite(bb) ; log("W -> 0x%X", x) ; return x ; } int len = bb.limit() - bb.position() ; int spaceNeeded = len + SizeOfInt ; if ( writeBuffer.position() + spaceNeeded > writeBuffer.capacity() ) // No room - flush. flushOutputBuffer() ; if ( writeBuffer.position() + spaceNeeded > writeBuffer.capacity() ) { long x = rawWrite(bb) ; if ( logging ) log("W -> 0x%X", x) ; return x ; } long loc = writeBuffer.position() + filesize ; writeBuffer.putInt(len) ; writeBuffer.put(bb) ; if ( logging ) log("W -> 0x%X", loc) ; return loc ; }
@Override public void reposition(long posn) { if ( inAllocWrite ) throw new FileException("In the middle of an alloc-write") ; if ( posn < 0 || posn > position() ) throw new IllegalArgumentException("reposition: Bad location: " + posn) ; flushOutputBuffer() ; file.truncate(posn) ; filesize = posn ; }
flushOutputBuffer() ; log("AW: %s->0x%X", state(), allocLocation) ; return allocBlock ;
private void flushOutputBuffer() { if ( logging ) log("Flush") ; if ( writeBuffer == null ) return ; if ( writeBuffer.position() == 0 ) return ; if ( false ) { String x = getLabel() ; if ( x.contains("nodes") ) { long x1 = filesize ; long x2 = writeBuffer.position() ; long x3 = x1 + x2 ; System.out.printf("Flush(%s) : %d/0x%04X (%d/0x%04X) %d/0x%04X\n", getLabel(), x1, x1, x2, x2, x3, x3) ; } } long location = filesize ; writeBuffer.flip() ; int x = file.write(writeBuffer) ; filesize += x ; writeBuffer.clear() ; }
@Override public void close() { flushOutputBuffer() ; file.close() ; }
@Override public void truncate(long size) { // System.out.println("truncate: "+size+" ("+filesize+","+writeBuffer.position()+")") // ; reposition(size) ; }
@Override public long length() { return position() ; }
private void log(String fmt, Object... args) { if ( !logging ) return ; log.debug(state() + " " + String.format(fmt, args)) ; }
private String state() { if ( writeBuffer == null ) return String.format(getLabel() + ": filesize=0x%X, file=(0x%X, 0x%X)", filesize, file.position(), file.size()) ; else return String.format(getLabel() + ": filesize=0x%X, file=(0x%X, 0x%X), writeBuffer=(0x%X,0x%X)", filesize, file.position(), file.size(), writeBuffer.position(), writeBuffer.limit()) ; }
@Override public Pair<Long, ByteBuffer> next() { // read, but reserving the file position. long x = current ; long filePosn = file.position() ; ByteBuffer bb = read(current) ; file.position(filePosn) ; current = current + bb.limit() + 4 ; return new Pair<>(x, bb) ; }
private long rawWrite(ByteBuffer bb) { if ( logging ) log("RW %s", bb) ; int len = bb.limit() - bb.position() ; lengthBuffer.rewind() ; lengthBuffer.putInt(len) ; lengthBuffer.flip() ; long location = file.position() ; file.write(lengthBuffer) ; int x = file.write(bb) ; if ( x != len ) throw new FileException() ; filesize = filesize + x + SizeOfInt ; if ( logging ) { log("Posn: %d", file.position()) ; log("RW ->0x%X", location) ; } return location ; }
@Override public void sync() { flushOutputBuffer() ; file.sync() ; }
public static ObjectFile createObjectFileMem(String filename) { BufferChannel file = BufferChannelMem.create(filename) ; return new ObjectFileStorage(file) ; }
public ObjectFileStorage(BufferChannel file, int bufferSize) { this.file = file ; filesize = file.size() ; this.file.position(filesize) ; // End of file. log("File size: 0x%X, posn: 0x%X", filesize, file.position()) ; writeBuffer = (bufferSize >= 0) ? ByteBuffer.allocate(bufferSize) : null ; }
@Override public Iterator<Pair<Long, ByteBuffer>> all() { flushOutputBuffer() ; // file.position(0) ; ObjectIterator iter = new ObjectIterator(0, filesize) ; // return iter ; if ( writeBuffer == null || writeBuffer.position() == 0 ) return iter ; return Iter.concat(iter, new BufferIterator(writeBuffer)) ; }
protected ObjectFile make(int bufferSize) { BufferChannel chan = BufferChannelMem.create() ; return new ObjectFileStorage(chan, bufferSize) ; }
@Override public ByteBuffer read(long loc) { if ( logging ) log("R(0x%X)", loc) ;
@Override protected ObjectFile make() { FileOps.deleteSilent(filename) ; BufferChannel chan = BufferChannelFile.create(filename) ; // No buffering. return new ObjectFileStorage(chan, -1) ; }