/* * 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; } }