| /* |
| * 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; |
| |
| |
| /** |
| * Non-specialized {@link BulkOperation} for {@link PackedInts.Format#PACKED_SINGLE_BLOCK}. |
| */ |
| final class BulkOperationPackedSingleBlock extends BulkOperation { |
| |
| private static final int BLOCK_COUNT = 1; |
| |
| private final int bitsPerValue; |
| private final int valueCount; |
| private final long mask; |
| |
| public BulkOperationPackedSingleBlock(int bitsPerValue) { |
| this.bitsPerValue = bitsPerValue; |
| this.valueCount = 64 / bitsPerValue; |
| this.mask = (1L << bitsPerValue) - 1; |
| } |
| |
| @Override |
| public final int longBlockCount() { |
| return BLOCK_COUNT; |
| } |
| |
| @Override |
| public final int byteBlockCount() { |
| return BLOCK_COUNT * 8; |
| } |
| |
| @Override |
| public int longValueCount() { |
| return valueCount; |
| } |
| |
| @Override |
| public final int byteValueCount() { |
| return valueCount; |
| } |
| |
| private static long readLong(byte[] blocks, int blocksOffset) { |
| return (blocks[blocksOffset++] & 0xFFL) << 56 |
| | (blocks[blocksOffset++] & 0xFFL) << 48 |
| | (blocks[blocksOffset++] & 0xFFL) << 40 |
| | (blocks[blocksOffset++] & 0xFFL) << 32 |
| | (blocks[blocksOffset++] & 0xFFL) << 24 |
| | (blocks[blocksOffset++] & 0xFFL) << 16 |
| | (blocks[blocksOffset++] & 0xFFL) << 8 |
| | blocks[blocksOffset++] & 0xFFL; |
| } |
| |
| private int decode(long block, long[] values, int valuesOffset) { |
| values[valuesOffset++] = block & mask; |
| for (int j = 1; j < valueCount; ++j) { |
| block >>>= bitsPerValue; |
| values[valuesOffset++] = block & mask; |
| } |
| return valuesOffset; |
| } |
| |
| private int decode(long block, int[] values, int valuesOffset) { |
| values[valuesOffset++] = (int) (block & mask); |
| for (int j = 1; j < valueCount; ++j) { |
| block >>>= bitsPerValue; |
| values[valuesOffset++] = (int) (block & mask); |
| } |
| return valuesOffset; |
| } |
| |
| private long encode(long[] values, int valuesOffset) { |
| long block = values[valuesOffset++]; |
| for (int j = 1; j < valueCount; ++j) { |
| block |= values[valuesOffset++] << (j * bitsPerValue); |
| } |
| return block; |
| } |
| |
| private long encode(int[] values, int valuesOffset) { |
| long block = values[valuesOffset++] & 0xFFFFFFFFL; |
| for (int j = 1; j < valueCount; ++j) { |
| block |= (values[valuesOffset++] & 0xFFFFFFFFL) << (j * bitsPerValue); |
| } |
| return block; |
| } |
| |
| @Override |
| public void decode(long[] blocks, int blocksOffset, long[] values, |
| int valuesOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| final long block = blocks[blocksOffset++]; |
| valuesOffset = decode(block, values, valuesOffset); |
| } |
| } |
| |
| @Override |
| public void decode(byte[] blocks, int blocksOffset, long[] values, |
| int valuesOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| final long block = readLong(blocks, blocksOffset); |
| blocksOffset += 8; |
| valuesOffset = decode(block, values, valuesOffset); |
| } |
| } |
| |
| @Override |
| public void decode(long[] blocks, int blocksOffset, int[] values, |
| int valuesOffset, int iterations) { |
| if (bitsPerValue > 32) { |
| throw new UnsupportedOperationException("Cannot decode " + bitsPerValue + "-bits values into an int[]"); |
| } |
| for (int i = 0; i < iterations; ++i) { |
| final long block = blocks[blocksOffset++]; |
| valuesOffset = decode(block, values, valuesOffset); |
| } |
| } |
| |
| @Override |
| public void decode(byte[] blocks, int blocksOffset, int[] values, |
| int valuesOffset, int iterations) { |
| if (bitsPerValue > 32) { |
| throw new UnsupportedOperationException("Cannot decode " + bitsPerValue + "-bits values into an int[]"); |
| } |
| for (int i = 0; i < iterations; ++i) { |
| final long block = readLong(blocks, blocksOffset); |
| blocksOffset += 8; |
| valuesOffset = decode(block, values, valuesOffset); |
| } |
| } |
| |
| @Override |
| public void encode(long[] values, int valuesOffset, long[] blocks, |
| int blocksOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| blocks[blocksOffset++] = encode(values, valuesOffset); |
| valuesOffset += valueCount; |
| } |
| } |
| |
| @Override |
| public void encode(int[] values, int valuesOffset, long[] blocks, |
| int blocksOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| blocks[blocksOffset++] = encode(values, valuesOffset); |
| valuesOffset += valueCount; |
| } |
| } |
| |
| @Override |
| public void encode(long[] values, int valuesOffset, byte[] blocks, int blocksOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| final long block = encode(values, valuesOffset); |
| valuesOffset += valueCount; |
| blocksOffset = writeLong(block, blocks, blocksOffset); |
| } |
| } |
| |
| @Override |
| public void encode(int[] values, int valuesOffset, byte[] blocks, |
| int blocksOffset, int iterations) { |
| for (int i = 0; i < iterations; ++i) { |
| final long block = encode(values, valuesOffset); |
| valuesOffset += valueCount; |
| blocksOffset = writeLong(block, blocks, blocksOffset); |
| } |
| } |
| |
| } |