blob: 1020ac93947c7555d2cc7650c50580eecd5f66ae [file] [log] [blame]
using Lucene.Net.Support;
using System;
using System.Diagnostics;
// this file has been automatically generated, DO NOT EDIT
namespace Lucene.Net.Util.Packed
{
/*
* 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.
*/
using DataInput = Lucene.Net.Store.DataInput;
/// <summary>
/// This class is similar to <see cref="Packed64"/> except that it trades space for
/// speed by ensuring that a single block needs to be read/written in order to
/// read/write a value.
/// </summary>
internal abstract class Packed64SingleBlock : PackedInt32s.MutableImpl
{
public const int MAX_SUPPORTED_BITS_PER_VALUE = 32;
private static readonly int[] SUPPORTED_BITS_PER_VALUE = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 21, 32 };
public static bool IsSupported(int bitsPerValue)
{
return Array.BinarySearch(SUPPORTED_BITS_PER_VALUE, bitsPerValue) >= 0;
}
private static int RequiredCapacity(int valueCount, int valuesPerBlock)
{
return valueCount / valuesPerBlock + (valueCount % valuesPerBlock == 0 ? 0 : 1);
}
internal readonly long[] blocks;
internal Packed64SingleBlock(int valueCount, int bitsPerValue)
: base(valueCount, bitsPerValue)
{
Debug.Assert(IsSupported(bitsPerValue));
int valuesPerBlock = 64 / bitsPerValue;
blocks = new long[RequiredCapacity(valueCount, valuesPerBlock)];
}
public override void Clear()
{
Arrays.Fill(blocks, 0L);
}
public override long RamBytesUsed()
{
return RamUsageEstimator.AlignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
+ 2 * RamUsageEstimator.NUM_BYTES_INT32 // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // blocks ref
+ RamUsageEstimator.SizeOf(blocks);
}
public override int Get(int index, long[] arr, int off, int len)
{
Debug.Assert(len > 0, "len must be > 0 (got " + len + ")");
Debug.Assert(index >= 0 && index < m_valueCount);
len = Math.Min(len, m_valueCount - index);
Debug.Assert(off + len <= arr.Length);
int originalIndex = index;
// go to the next block boundary
int valuesPerBlock = 64 / m_bitsPerValue;
int offsetInBlock = index % valuesPerBlock;
if (offsetInBlock != 0)
{
for (int i = offsetInBlock; i < valuesPerBlock && len > 0; ++i)
{
arr[off++] = Get(index++);
--len;
}
if (len == 0)
{
return index - originalIndex;
}
}
// bulk get
Debug.Assert(index % valuesPerBlock == 0);
PackedInt32s.IDecoder decoder = BulkOperation.Of(PackedInt32s.Format.PACKED_SINGLE_BLOCK, m_bitsPerValue);
Debug.Assert(decoder.Int64BlockCount == 1);
Debug.Assert(decoder.Int64ValueCount == valuesPerBlock);
int blockIndex = index / valuesPerBlock;
int nblocks = (index + len) / valuesPerBlock - blockIndex;
decoder.Decode(blocks, blockIndex, arr, off, nblocks);
int diff = nblocks * valuesPerBlock;
index += diff;
len -= diff;
if (index > originalIndex)
{
// stay at the block boundary
return index - originalIndex;
}
else
{
// no progress so far => already at a block boundary but no full block to
// get
Debug.Assert(index == originalIndex);
return base.Get(index, arr, off, len);
}
}
public override int Set(int index, long[] arr, int off, int len)
{
Debug.Assert(len > 0, "len must be > 0 (got " + len + ")");
Debug.Assert(index >= 0 && index < m_valueCount);
len = Math.Min(len, m_valueCount - index);
Debug.Assert(off + len <= arr.Length);
int originalIndex = index;
// go to the next block boundary
int valuesPerBlock = 64 / m_bitsPerValue;
int offsetInBlock = index % valuesPerBlock;
if (offsetInBlock != 0)
{
for (int i = offsetInBlock; i < valuesPerBlock && len > 0; ++i)
{
Set(index++, arr[off++]);
--len;
}
if (len == 0)
{
return index - originalIndex;
}
}
// bulk set
Debug.Assert(index % valuesPerBlock == 0);
BulkOperation op = BulkOperation.Of(PackedInt32s.Format.PACKED_SINGLE_BLOCK, m_bitsPerValue);
Debug.Assert(op.Int64BlockCount == 1);
Debug.Assert(op.Int64ValueCount == valuesPerBlock);
int blockIndex = index / valuesPerBlock;
int nblocks = (index + len) / valuesPerBlock - blockIndex;
op.Encode(arr, off, blocks, blockIndex, nblocks);
int diff = nblocks * valuesPerBlock;
index += diff;
len -= diff;
if (index > originalIndex)
{
// stay at the block boundary
return index - originalIndex;
}
else
{
// no progress so far => already at a block boundary but no full block to
// set
Debug.Assert(index == originalIndex);
return base.Set(index, arr, off, len);
}
}
public override void Fill(int fromIndex, int toIndex, long val)
{
Debug.Assert(fromIndex >= 0);
Debug.Assert(fromIndex <= toIndex);
Debug.Assert(PackedInt32s.BitsRequired(val) <= m_bitsPerValue);
int valuesPerBlock = 64 / m_bitsPerValue;
if (toIndex - fromIndex <= valuesPerBlock << 1)
{
// there needs to be at least one full block to set for the block
// approach to be worth trying
base.Fill(fromIndex, toIndex, val);
return;
}
// set values naively until the next block start
int fromOffsetInBlock = fromIndex % valuesPerBlock;
if (fromOffsetInBlock != 0)
{
for (int i = fromOffsetInBlock; i < valuesPerBlock; ++i)
{
Set(fromIndex++, val);
}
Debug.Assert(fromIndex % valuesPerBlock == 0);
}
// bulk set of the inner blocks
int fromBlock = fromIndex / valuesPerBlock;
int toBlock = toIndex / valuesPerBlock;
Debug.Assert(fromBlock * valuesPerBlock == fromIndex);
long blockValue = 0L;
for (int i = 0; i < valuesPerBlock; ++i)
{
blockValue = blockValue | (val << (i * m_bitsPerValue));
}
Arrays.Fill(blocks, fromBlock, toBlock, blockValue);
// fill the gap
for (int i = valuesPerBlock * toBlock; i < toIndex; ++i)
{
Set(i, val);
}
}
internal override PackedInt32s.Format Format
{
get
{
return PackedInt32s.Format.PACKED_SINGLE_BLOCK;
}
}
public override string ToString()
{
return this.GetType().Name + "(bitsPerValue=" + m_bitsPerValue + ", size=" + Count + ", elements.length=" + blocks.Length + ")";
}
public static Packed64SingleBlock Create(DataInput @in, int valueCount, int bitsPerValue)
{
Packed64SingleBlock reader = Create(valueCount, bitsPerValue);
for (int i = 0; i < reader.blocks.Length; ++i)
{
reader.blocks[i] = @in.ReadInt64();
}
return reader;
}
public static Packed64SingleBlock Create(int valueCount, int bitsPerValue)
{
switch (bitsPerValue)
{
case 1:
return new Packed64SingleBlock1(valueCount);
case 2:
return new Packed64SingleBlock2(valueCount);
case 3:
return new Packed64SingleBlock3(valueCount);
case 4:
return new Packed64SingleBlock4(valueCount);
case 5:
return new Packed64SingleBlock5(valueCount);
case 6:
return new Packed64SingleBlock6(valueCount);
case 7:
return new Packed64SingleBlock7(valueCount);
case 8:
return new Packed64SingleBlock8(valueCount);
case 9:
return new Packed64SingleBlock9(valueCount);
case 10:
return new Packed64SingleBlock10(valueCount);
case 12:
return new Packed64SingleBlock12(valueCount);
case 16:
return new Packed64SingleBlock16(valueCount);
case 21:
return new Packed64SingleBlock21(valueCount);
case 32:
return new Packed64SingleBlock32(valueCount);
default:
throw new System.ArgumentException("Unsupported number of bits per value: " + 32);
}
}
internal class Packed64SingleBlock1 : Packed64SingleBlock
{
internal Packed64SingleBlock1(int valueCount)
: base(valueCount, 1)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 6);
int b = index & 63;
int shift = b << 0;
return ((long)((ulong)blocks[o] >> shift)) & 1L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 6);
int b = index & 63;
int shift = b << 0;
blocks[o] = (blocks[o] & ~(1L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock2 : Packed64SingleBlock
{
internal Packed64SingleBlock2(int valueCount)
: base(valueCount, 2)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 5);
int b = index & 31;
int shift = b << 1;
return ((long)((ulong)blocks[o] >> shift)) & 3L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 5);
int b = index & 31;
int shift = b << 1;
blocks[o] = (blocks[o] & ~(3L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock3 : Packed64SingleBlock
{
internal Packed64SingleBlock3(int valueCount)
: base(valueCount, 3)
{
}
public override long Get(int index)
{
int o = index / 21;
int b = index % 21;
int shift = b * 3;
return ((long)((ulong)blocks[o] >> shift)) & 7L;
}
public override void Set(int index, long value)
{
int o = index / 21;
int b = index % 21;
int shift = b * 3;
blocks[o] = (blocks[o] & ~(7L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock4 : Packed64SingleBlock
{
internal Packed64SingleBlock4(int valueCount)
: base(valueCount, 4)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 4);
int b = index & 15;
int shift = b << 2;
return ((long)((ulong)blocks[o] >> shift)) & 15L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 4);
int b = index & 15;
int shift = b << 2;
blocks[o] = (blocks[o] & ~(15L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock5 : Packed64SingleBlock
{
internal Packed64SingleBlock5(int valueCount)
: base(valueCount, 5)
{
}
public override long Get(int index)
{
int o = index / 12;
int b = index % 12;
int shift = b * 5;
return ((long)((ulong)blocks[o] >> shift)) & 31L;
}
public override void Set(int index, long value)
{
int o = index / 12;
int b = index % 12;
int shift = b * 5;
blocks[o] = (blocks[o] & ~(31L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock6 : Packed64SingleBlock
{
internal Packed64SingleBlock6(int valueCount)
: base(valueCount, 6)
{
}
public override long Get(int index)
{
int o = index / 10;
int b = index % 10;
int shift = b * 6;
return ((long)((ulong)blocks[o] >> shift)) & 63L;
}
public override void Set(int index, long value)
{
int o = index / 10;
int b = index % 10;
int shift = b * 6;
blocks[o] = (blocks[o] & ~(63L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock7 : Packed64SingleBlock
{
internal Packed64SingleBlock7(int valueCount)
: base(valueCount, 7)
{
}
public override long Get(int index)
{
int o = index / 9;
int b = index % 9;
int shift = b * 7;
return ((long)((ulong)blocks[o] >> shift)) & 127L;
}
public override void Set(int index, long value)
{
int o = index / 9;
int b = index % 9;
int shift = b * 7;
blocks[o] = (blocks[o] & ~(127L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock8 : Packed64SingleBlock
{
internal Packed64SingleBlock8(int valueCount)
: base(valueCount, 8)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 3);
int b = index & 7;
int shift = b << 3;
return ((long)((ulong)blocks[o] >> shift)) & 255L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 3);
int b = index & 7;
int shift = b << 3;
blocks[o] = (blocks[o] & ~(255L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock9 : Packed64SingleBlock
{
internal Packed64SingleBlock9(int valueCount)
: base(valueCount, 9)
{
}
public override long Get(int index)
{
int o = index / 7;
int b = index % 7;
int shift = b * 9;
return ((long)((ulong)blocks[o] >> shift)) & 511L;
}
public override void Set(int index, long value)
{
int o = index / 7;
int b = index % 7;
int shift = b * 9;
blocks[o] = (blocks[o] & ~(511L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock10 : Packed64SingleBlock
{
internal Packed64SingleBlock10(int valueCount)
: base(valueCount, 10)
{
}
public override long Get(int index)
{
int o = index / 6;
int b = index % 6;
int shift = b * 10;
return ((long)((ulong)blocks[o] >> shift)) & 1023L;
}
public override void Set(int index, long value)
{
int o = index / 6;
int b = index % 6;
int shift = b * 10;
blocks[o] = (blocks[o] & ~(1023L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock12 : Packed64SingleBlock
{
internal Packed64SingleBlock12(int valueCount)
: base(valueCount, 12)
{
}
public override long Get(int index)
{
int o = index / 5;
int b = index % 5;
int shift = b * 12;
return ((long)((ulong)blocks[o] >> shift)) & 4095L;
}
public override void Set(int index, long value)
{
int o = index / 5;
int b = index % 5;
int shift = b * 12;
blocks[o] = (blocks[o] & ~(4095L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock16 : Packed64SingleBlock
{
internal Packed64SingleBlock16(int valueCount)
: base(valueCount, 16)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 2);
int b = index & 3;
int shift = b << 4;
return ((long)((ulong)blocks[o] >> shift)) & 65535L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 2);
int b = index & 3;
int shift = b << 4;
blocks[o] = (blocks[o] & ~(65535L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock21 : Packed64SingleBlock
{
internal Packed64SingleBlock21(int valueCount)
: base(valueCount, 21)
{
}
public override long Get(int index)
{
int o = index / 3;
int b = index % 3;
int shift = b * 21;
return ((long)((ulong)blocks[o] >> shift)) & 2097151L;
}
public override void Set(int index, long value)
{
int o = index / 3;
int b = index % 3;
int shift = b * 21;
blocks[o] = (blocks[o] & ~(2097151L << shift)) | (value << shift);
}
}
internal class Packed64SingleBlock32 : Packed64SingleBlock
{
internal Packed64SingleBlock32(int valueCount)
: base(valueCount, 32)
{
}
public override long Get(int index)
{
int o = (int)((uint)index >> 1);
int b = index & 1;
int shift = b << 5;
return ((long)((ulong)blocks[o] >> shift)) & 4294967295L;
}
public override void Set(int index, long value)
{
int o = (int)((uint)index >> 1);
int b = index & 1;
int shift = b << 5;
blocks[o] = (blocks[o] & ~(4294967295L << shift)) | (value << shift);
}
}
}
}