blob: c4dfe9f3d982bfda4047d58273a0500d19c1124e [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;
/**
* 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);
}
}
}