MMapIndexInput( String resourceDescription, RandomAccessFile raf, long offset, long length, int chunkSizePower) throws IOException { super(resourceDescription); this.length = length; this.chunkSizePower = chunkSizePower; this.chunkSize = 1L << chunkSizePower; this.chunkSizeMask = chunkSize - 1L; if (chunkSizePower < 0 || chunkSizePower > 30) throw new IllegalArgumentException( "Invalid chunkSizePower used for ByteBuffer size: " + chunkSizePower); if ((length >>> chunkSizePower) >= Integer.MAX_VALUE) throw new IllegalArgumentException( "RandomAccessFile too big for chunk size: " + raf.toString()); // we always allocate one more buffer, the last one may be a 0 byte one final int nrBuffers = (int) (length >>> chunkSizePower) + 1; // System.out.println("length="+length+", chunkSizePower=" + chunkSizePower + ", // chunkSizeMask=" + chunkSizeMask + ", nrBuffers=" + nrBuffers); this.buffers = new ByteBuffer[nrBuffers]; long bufferStart = 0L; FileChannel rafc = raf.getChannel(); for (int bufNr = 0; bufNr < nrBuffers; bufNr++) { int bufSize = (int) ((length > (bufferStart + chunkSize)) ? chunkSize : (length - bufferStart)); this.buffers[bufNr] = rafc.map(MapMode.READ_ONLY, offset + bufferStart, bufSize); bufferStart += bufSize; } seek(0L); }