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 < valueCount); len = Math.Min(len, valueCount - index); Debug.Assert(off + len <= arr.Length); int originalIndex = index; // go to the next block boundary int valuesPerBlock = 64 / 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); PackedInts.Decoder decoder = BulkOperation.Of(PackedInts.Format.PACKED_SINGLE_BLOCK, bitsPerValue); Debug.Assert(decoder.LongBlockCount() == 1); Debug.Assert(decoder.LongValueCount() == 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)); } }
/*/// <param name="index"> the position of the value. </param> * /// <returns> the value at the given index. </returns> * public override long Get(int index) * { * // The abstract index in a bit stream * long majorBitPos = (long)index * bitsPerValue; * // The index in the backing long-array * int elementPos = (int)((long)((ulong)majorBitPos >> BLOCK_BITS)); * // The number of value-bits in the second long * long endBits = (majorBitPos & MOD_MASK) + BpvMinusBlockSize; * * if (endBits <= 0) // Single block * { * var mod = (long) ((ulong) (Blocks[elementPos]) >> (int) (-endBits)) & MaskRight; * var og = ((long) ((ulong) Blocks[elementPos] >> (int) -endBits)) & MaskRight; * Debug.Assert(mod == og); * * //return (long)((ulong)(Blocks[elementPos]) >> (int)(-endBits)) & MaskRight; * return ((long)((ulong)Blocks[elementPos] >> (int)-endBits)) & MaskRight; * } * // Two blocks * var a = (((Blocks[elementPos] << (int)endBits) | (long)(((ulong)(Blocks[elementPos + 1])) >> (int)(BLOCK_SIZE - endBits))) & MaskRight); * var b = ((Blocks[elementPos] << (int)endBits) | ((long)((ulong)Blocks[elementPos + 1] >> (int)(BLOCK_SIZE - endBits)))) & MaskRight; * * Debug.Assert(a == b); * * //return (((Blocks[elementPos] << (int)endBits) | (long)(((ulong)(Blocks[elementPos + 1])) >> (int)(BLOCK_SIZE - endBits))) & MaskRight); * return ((Blocks[elementPos] << (int)endBits) | ((long)((ulong)Blocks[elementPos + 1] >> (int)(BLOCK_SIZE - endBits)))) & MaskRight; * }*/ 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 < valueCount); len = Math.Min(len, valueCount - index); Debug.Assert(off + len <= arr.Length); int originalIndex = index; PackedInts.Decoder decoder = BulkOperation.Of(PackedInts.Format.PACKED, bitsPerValue); // go to the next block where the value does not span across two blocks int offsetInBlocks = index % decoder.LongValueCount(); if (offsetInBlocks != 0) { for (int i = offsetInBlocks; i < decoder.LongValueCount() && len > 0; ++i) { arr[off++] = Get(index++); --len; } if (len == 0) { return(index - originalIndex); } } // bulk get Debug.Assert(index % decoder.LongValueCount() == 0); int blockIndex = (int)((ulong)((long)index * bitsPerValue) >> BLOCK_BITS); Debug.Assert((((long)index * bitsPerValue) & MOD_MASK) == 0); int iterations = len / decoder.LongValueCount(); decoder.Decode(Blocks, blockIndex, arr, off, iterations); int gotValues = iterations * decoder.LongValueCount(); index += gotValues; len -= gotValues; Debug.Assert(len >= 0); 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)); } }
private void Refill() { int token = @in.ReadByte() & 0xFF; bool minEquals0 = (token & AbstractBlockPackedWriter.MIN_VALUE_EQUALS_0) != 0; int bitsPerValue = (int)((uint)token >> AbstractBlockPackedWriter.BPV_SHIFT); if (bitsPerValue > 64) { throw new System.IO.IOException("Corrupted"); } long minValue = minEquals0 ? 0L : ZigZagDecode(1L + ReadVLong(@in)); Debug.Assert(minEquals0 || minValue != 0); if (bitsPerValue == 0) { Arrays.Fill(Values, minValue); } else { PackedInts.Decoder decoder = PackedInts.GetDecoder(PackedInts.Format.PACKED, PackedIntsVersion, bitsPerValue); int iterations = BlockSize / decoder.ByteValueCount(); int blocksSize = iterations * decoder.ByteBlockCount(); if (Blocks == null || Blocks.Length < blocksSize) { Blocks = new sbyte[blocksSize]; } int valueCount = (int)Math.Min(this.ValueCount - Ord_Renamed, BlockSize); int blocksCount = (int)PackedInts.Format.PACKED.ByteCount(PackedIntsVersion, valueCount, bitsPerValue); @in.ReadBytes(Blocks, 0, blocksCount); decoder.Decode(Blocks, 0, Values, 0, iterations); if (minValue != 0) { for (int i = 0; i < valueCount; ++i) { Values[i] += minValue; } } } Off = 0; }
static ForUtil() { int maxDataSize = 0; for (int version = PackedInts.VERSION_START; version <= PackedInts.VERSION_CURRENT; version++) { foreach (PackedInts.Format format in PackedInts.Format.Values() /* Enum.GetValues(typeof(PackedInts.Format))*/) { for (int bpv = 1; bpv <= 32; ++bpv) { if (!format.IsSupported(bpv)) { continue; } PackedInts.Decoder decoder = PackedInts.GetDecoder(format, version, bpv); int iterations = ComputeIterations(decoder); maxDataSize = Math.Max(maxDataSize, iterations * decoder.ByteValueCount()); } } } MAX_DATA_SIZE = maxDataSize; }
/// <summary> /// Read the next block of data (<code>For</code> format). /// </summary> /// <param name="in"> the input to use to read data </param> /// <param name="encoded"> a buffer that can be used to store encoded data </param> /// <param name="decoded"> where to write decoded data </param> /// <exception cref="IOException"> If there is a low-level I/O error </exception> public void ReadBlock(IndexInput @in, byte[] encoded, int[] decoded) { int numBits = @in.ReadByte(); Debug.Assert(numBits <= 32, numBits.ToString()); if (numBits == ALL_VALUES_EQUAL) { int value = @in.ReadVInt(); CollectionsHelper.Fill(decoded, 0, Lucene41PostingsFormat.BLOCK_SIZE, value); return; } int encodedSize = EncodedSizes[numBits]; @in.ReadBytes(encoded, 0, encodedSize); PackedInts.Decoder decoder = Decoders[numBits]; int iters = Iterations[numBits]; Debug.Assert(iters * decoder.ByteValueCount() >= Lucene41PostingsFormat.BLOCK_SIZE); decoder.Decode(encoded, 0, decoded, 0, iters); }
/// <summary> /// Compute the number of iterations required to decode <code>BLOCK_SIZE</code> /// values with the provided <seealso cref="Decoder"/>. /// </summary> private static int ComputeIterations(PackedInts.Decoder decoder) { return((int)Math.Ceiling((float)Lucene41PostingsFormat.BLOCK_SIZE / decoder.ByteValueCount())); }