package org.apache.lucene.util.packed;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.store.IndexInput;
import java.io.IOException;
/* Reads directly from disk on each get */
final class DirectPackedReader extends PackedInts.ReaderImpl {
private final IndexInput in;
private final long startPointer;
private static final int BLOCK_BITS = Packed64.BLOCK_BITS;
private static final int MOD_MASK = Packed64.MOD_MASK;
// masks[n-1] masks for bottom n bits
private final long[] masks;
public DirectPackedReader(int bitsPerValue, int valueCount, IndexInput in) {
super(valueCount, bitsPerValue);
this.in = in;
long v = 1;
masks = new long[bitsPerValue];
for (int i = 0; i < bitsPerValue; i++) {
v *= 2;
masks[i] = v - 1;
}
startPointer = in.getFilePointer();
}
@Override
public long get(int index) {
final long majorBitPos = (long)index * bitsPerValue;
final int elementPos = (int)(majorBitPos >>> BLOCK_BITS); // / BLOCK_SIZE
final int bitPos = (int)(majorBitPos & MOD_MASK); // % BLOCK_SIZE);
final long result;
try {
in.seek(startPointer + (elementPos << 3));
final long l1 = in.readLong();
final int bits1 = 64 - bitPos;
if (bits1 >= bitsPerValue) { // not split
result = l1 >> (bits1-bitsPerValue) & masks[bitsPerValue-1];
} else {
final int bits2 = bitsPerValue - bits1;
final long result1 = (l1 & masks[bits1-1]) << bits2;
final long l2 = in.readLong();
final long result2 = l2 >> (64 - bits2) & masks[bits2-1];
result = result1 | result2;
}
return result;
} catch (IOException ioe) {
throw new IllegalStateException("failed", ioe);
}
}
@Override
public long ramBytesUsed() {
return 0;
}
}