Exemple #1
0
        private void WriteBlock()
        {
            Debug.Assert(BlockChunks > 0);
            FieldsIndexOut.WriteVInt(BlockChunks);

            // The trick here is that we only store the difference from the average start
            // pointer or doc base, this helps save bits per value.
            // And in order to prevent a few chunks that would be far from the average to
            // raise the number of bits per value for all of them, we only encode blocks
            // of 1024 chunks at once
            // See LUCENE-4512

            // doc bases
            int avgChunkDocs;

            if (BlockChunks == 1)
            {
                avgChunkDocs = 0;
            }
            else
            {
                avgChunkDocs = (int)Math.Round((float)(BlockDocs - DocBaseDeltas[BlockChunks - 1]) / (BlockChunks - 1));
            }
            FieldsIndexOut.WriteVInt(TotalDocs - BlockDocs); // docBase
            FieldsIndexOut.WriteVInt(avgChunkDocs);
            int  docBase  = 0;
            long maxDelta = 0;

            for (int i = 0; i < BlockChunks; ++i)
            {
                int delta = docBase - avgChunkDocs * i;
                maxDelta |= MoveSignToLowOrderBit(delta);
                docBase  += DocBaseDeltas[i];
            }

            int bitsPerDocBase = PackedInts.BitsRequired(maxDelta);

            FieldsIndexOut.WriteVInt(bitsPerDocBase);
            PackedInts.Writer writer = PackedInts.GetWriterNoHeader(FieldsIndexOut, PackedInts.Format.PACKED, BlockChunks, bitsPerDocBase, 1);
            docBase = 0;
            for (int i = 0; i < BlockChunks; ++i)
            {
                long delta = docBase - avgChunkDocs * i;
                Debug.Assert(PackedInts.BitsRequired(MoveSignToLowOrderBit(delta)) <= writer.BitsPerValue());
                writer.Add(MoveSignToLowOrderBit(delta));
                docBase += DocBaseDeltas[i];
            }
            writer.Finish();

            // start pointers
            FieldsIndexOut.WriteVLong(FirstStartPointer);
            long avgChunkSize;

            if (BlockChunks == 1)
            {
                avgChunkSize = 0;
            }
            else
            {
                avgChunkSize = (MaxStartPointer - FirstStartPointer) / (BlockChunks - 1);
            }
            FieldsIndexOut.WriteVLong(avgChunkSize);
            long startPointer = 0;

            maxDelta = 0;
            for (int i = 0; i < BlockChunks; ++i)
            {
                startPointer += StartPointerDeltas[i];
                long delta = startPointer - avgChunkSize * i;
                maxDelta |= MoveSignToLowOrderBit(delta);
            }

            int bitsPerStartPointer = PackedInts.BitsRequired(maxDelta);

            FieldsIndexOut.WriteVInt(bitsPerStartPointer);
            writer       = PackedInts.GetWriterNoHeader(FieldsIndexOut, PackedInts.Format.PACKED, BlockChunks, bitsPerStartPointer, 1);
            startPointer = 0;
            for (int i = 0; i < BlockChunks; ++i)
            {
                startPointer += StartPointerDeltas[i];
                long delta = startPointer - avgChunkSize * i;
                Debug.Assert(PackedInts.BitsRequired(MoveSignToLowOrderBit(delta)) <= writer.BitsPerValue());
                writer.Add(MoveSignToLowOrderBit(delta));
            }
            writer.Finish();
        }