blob: 798325b6044e0e43c12557edc089076e7fe5bfea [file] [log] [blame]
/*
* 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.
*/
package org.apache.lucene.util.packed;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.util.LongsRef;
final class PackedReaderIterator extends PackedInts.ReaderIteratorImpl {
final int packedIntsVersion;
final PackedInts.Format format;
final BulkOperation bulkOperation;
final byte[] nextBlocks;
final LongsRef nextValues;
final int iterations;
int position;
PackedReaderIterator(PackedInts.Format format, int packedIntsVersion, int valueCount, int bitsPerValue, DataInput in, int mem) {
super(valueCount, bitsPerValue, in);
this.format = format;
this.packedIntsVersion = packedIntsVersion;
bulkOperation = BulkOperation.of(format, bitsPerValue);
iterations = bulkOperation.computeIterations(valueCount, mem);
assert valueCount == 0 || iterations > 0;
nextBlocks = new byte[iterations * bulkOperation.byteBlockCount()];
nextValues = new LongsRef(new long[iterations * bulkOperation.byteValueCount()], 0, 0);
nextValues.offset = nextValues.longs.length;
position = -1;
}
@Override
public LongsRef next(int count) throws IOException {
assert nextValues.length >= 0;
assert count > 0;
assert nextValues.offset + nextValues.length <= nextValues.longs.length;
nextValues.offset += nextValues.length;
final int remaining = valueCount - position - 1;
if (remaining <= 0) {
throw new EOFException();
}
count = Math.min(remaining, count);
if (nextValues.offset == nextValues.longs.length) {
final long remainingBlocks = format.byteCount(packedIntsVersion, remaining, bitsPerValue);
final int blocksToRead = (int) Math.min(remainingBlocks, nextBlocks.length);
in.readBytes(nextBlocks, 0, blocksToRead);
if (blocksToRead < nextBlocks.length) {
Arrays.fill(nextBlocks, blocksToRead, nextBlocks.length, (byte) 0);
}
bulkOperation.decode(nextBlocks, 0, nextValues.longs, 0, iterations);
nextValues.offset = 0;
}
nextValues.length = Math.min(nextValues.longs.length - nextValues.offset, count);
position += nextValues.length;
return nextValues;
}
@Override
public int ord() {
return position;
}
}