All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.lucene.util.FixedLengthBytesRefArray Maven / Gradle / Ivy

There is a newer version: 6.4.2_1
Show newest version
/*
 * 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;

import java.util.Comparator;
import java.util.Objects;

/**
 * Just like {@link BytesRefArray} except all values have the same length.
 *
 * 

Note: This class is not Thread-Safe! * * @lucene.internal * @lucene.experimental */ public final class FixedLengthBytesRefArray implements SortableBytesRefArray { private final int valueLength; private final int valuesPerBlock; /** How many values have been appended */ private int size; /** How many blocks are used */ private int currentBlock = -1; private int nextEntry; private byte[][] blocks; /** Creates a new {@link BytesRefArray} with a counter to track allocated bytes */ public FixedLengthBytesRefArray(int valueLength) { this.valueLength = valueLength; // ~32K per page, unless each value is > 32K: valuesPerBlock = Math.max(1, 32768 / valueLength); nextEntry = valuesPerBlock; blocks = new byte[0][]; } /** Clears this {@link BytesRefArray} */ @Override public void clear() { size = 0; blocks = new byte[0][]; currentBlock = -1; nextEntry = valuesPerBlock; } /** * Appends a copy of the given {@link BytesRef} to this {@link BytesRefArray}. * * @param bytes the bytes to append * @return the index of the appended bytes */ @Override public int append(BytesRef bytes) { if (bytes.length != valueLength) { throw new IllegalArgumentException( "value length is " + bytes.length + " but is supposed to always be " + valueLength); } if (nextEntry == valuesPerBlock) { currentBlock++; if (currentBlock == blocks.length) { int size = ArrayUtil.oversize(currentBlock + 1, RamUsageEstimator.NUM_BYTES_OBJECT_REF); byte[][] next = new byte[size][]; System.arraycopy(blocks, 0, next, 0, blocks.length); blocks = next; } blocks[currentBlock] = new byte[valuesPerBlock * valueLength]; nextEntry = 0; } System.arraycopy( bytes.bytes, bytes.offset, blocks[currentBlock], nextEntry * valueLength, valueLength); nextEntry++; return size++; } /** * Returns the n'th element of this {@link FixedLengthBytesRefArray} * * @param spare a spare {@link BytesRef} instance. The length of this spare should be equal to the * fixed length. * @param index the elements index to retrieve * @return the n'th element of this {@link FixedLengthBytesRefArray} */ public BytesRef get(BytesRef spare, int index) { Objects.checkIndex(index, size); assert spare.length == valueLength; final int block = index / valuesPerBlock; final int pos = index % valuesPerBlock; spare.bytes = blocks[block]; spare.offset = pos * valueLength; return spare; } /** * Returns the current size of this {@link FixedLengthBytesRefArray} * * @return the current size of this {@link FixedLengthBytesRefArray} */ @Override public int size() { return size; } private int[] sort(final Comparator comp) { final int[] orderedEntries = new int[size()]; for (int i = 0; i < orderedEntries.length; i++) { orderedEntries[i] = i; } new StringSorter(comp) { { scratchBytes1.length = valueLength; scratchBytes2.length = valueLength; pivot.length = valueLength; } @Override protected void get(BytesRefBuilder builder, BytesRef result, int i) { final int index = orderedEntries[i]; result.bytes = blocks[index / valuesPerBlock]; result.offset = (index % valuesPerBlock) * valueLength; } @Override protected void swap(int i, int j) { int o = orderedEntries[i]; orderedEntries[i] = orderedEntries[j]; orderedEntries[j] = o; } }.sort(0, size()); return orderedEntries; } /** * Returns a {@link BytesRefIterator} with point in time semantics. The iterator provides access * to all so far appended {@link BytesRef} instances. * *

The iterator will iterate the byte values in the order specified by the comparator. * *

This is a non-destructive operation. */ @Override public BytesRefIterator iterator(final Comparator comp) { final BytesRef result = new BytesRef(); result.length = valueLength; final int size = size(); final int[] indices = sort(comp); return new BytesRefIterator() { int pos = 0; @Override public BytesRef next() { if (pos < size) { int index = indices[pos]; pos++; result.bytes = blocks[index / valuesPerBlock]; result.offset = (index % valuesPerBlock) * valueLength; return result; } return null; } }; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy