@Override public IndexInput clone() { LZFCompressedIndexInput cloned = (LZFCompressedIndexInput) super.clone(); cloned.inputBuffer = new byte[LZFChunk.MAX_CHUNK_LEN]; return cloned; }
@Override public void readBytes(byte[] b, int offset, int len) throws IOException { int result = read(b, offset, len, true /* we want to have full reads, thats the contract... */); if (result < len) { throw new EOFException(); } }
@Override public byte readByte() throws IOException { if (!readyBuffer()) { throw new EOFException(); } return uncompressed[position++]; }
@Override public void close() throws IOException { position = valid = 0; if (!closed) { closed = true; doClose(); in.close(); } }
protected boolean readyBuffer() throws IOException { if (position < valid) { return true; } if (closed) { return false; } // we reached the end... if (currentOffsetIdx + 1 >= offsets.size()) { return false; } valid = uncompress(in, uncompressed); if (valid < 0) { return false; } currentOffsetIdx++; currentUncompressedChunkPointer = ((long) currentOffsetIdx) * uncompressedLength; position = 0; return (position < valid); }
public CompressedIndexInput(IndexInput in) throws IOException { super("compressed(" + in.toString() + ")"); this.in = in; readHeader(in); this.version = in.readInt(); long metaDataPosition = in.readLong(); long headerLength = in.getFilePointer(); in.seek(metaDataPosition); this.totalUncompressedLength = in.readVLong(); int size = in.readVInt(); offsets = BigArrays.NON_RECYCLING_INSTANCE.newLongArray(size); for (int i = 0; i < size; i++) { offsets.set(i, in.readVLong()); } this.currentOffsetIdx = -1; this.currentUncompressedChunkPointer = 0; in.seek(headerLength); }
public int read(byte[] buffer, int offset, int length, boolean fullRead) throws IOException { if (length < 1) { return 0; } if (!readyBuffer()) { return -1; } // First let's read however much data we happen to have... int chunkLength = Math.min(valid - position, length); System.arraycopy(uncompressed, position, buffer, offset, chunkLength); position += chunkLength; if (chunkLength == length || !fullRead) { return chunkLength; } // Need more data, then int totalRead = chunkLength; do { offset += chunkLength; if (!readyBuffer()) { break; } chunkLength = Math.min(valid - position, (length - totalRead)); System.arraycopy(uncompressed, position, buffer, offset, chunkLength); position += chunkLength; totalRead += chunkLength; } while (totalRead < length); return totalRead; }
@Override public void seek(long pos) throws IOException { int idx = (int) (pos / uncompressedLength); if (idx >= offsets.size()) { // set the next "readyBuffer" to EOF currentOffsetIdx = idx; position = 0; valid = 0; return; } // TODO: optimize so we won't have to readyBuffer on seek, can keep the position around, and set it on readyBuffer in this case if (idx != currentOffsetIdx) { long pointer = offsets.get(idx); in.seek(pointer); position = 0; valid = 0; currentOffsetIdx = idx - 1; // we are going to increase it in readyBuffer... readyBuffer(); } position = (int) (pos % uncompressedLength); }