| using Lucene.Net.Support; |
| using System.Runtime.CompilerServices; |
| |
| namespace Lucene.Net.Codecs.Lucene41 |
| { |
| /* |
| * 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 IndexOutput = Lucene.Net.Store.IndexOutput; |
| |
| /// <summary> |
| /// Write skip lists with multiple levels, and support skip within block ints. |
| /// <para/> |
| /// Assume that docFreq = 28, skipInterval = blockSize = 12 |
| /// |
| /// | block#0 | | block#1 | |vInts| |
| /// d d d d d d d d d d d d d d d d d d d d d d d d d d d d (posting list) |
| /// ^ ^ (level 0 skip point) |
| /// <para/> |
| /// Note that skipWriter will ignore first document in block#0, since |
| /// it is useless as a skip point. Also, we'll never skip into the vInts |
| /// block, only record skip data at the start its start point(if it exist). |
| /// <para/> |
| /// For each skip point, we will record: |
| /// 1. docID in former position, i.e. for position 12, record docID[11], etc. |
| /// 2. its related file points(position, payload), |
| /// 3. related numbers or uptos(position, payload). |
| /// 4. start offset. |
| /// </summary> |
| internal sealed class Lucene41SkipWriter : MultiLevelSkipListWriter |
| { |
| // private boolean DEBUG = Lucene41PostingsReader.DEBUG; |
| |
| private readonly int[] lastSkipDoc; // LUCENENET: marked readonly |
| private readonly long[] lastSkipDocPointer; // LUCENENET: marked readonly |
| private readonly long[] lastSkipPosPointer; // LUCENENET: marked readonly |
| private readonly long[] lastSkipPayPointer; // LUCENENET: marked readonly |
| private readonly int[] lastPayloadByteUpto; // LUCENENET: marked readonly |
| |
| private readonly IndexOutput docOut; |
| private readonly IndexOutput posOut; |
| private readonly IndexOutput payOut; |
| |
| private int curDoc; |
| private long curDocPointer; |
| private long curPosPointer; |
| private long curPayPointer; |
| private int curPosBufferUpto; |
| private int curPayloadByteUpto; |
| private bool fieldHasPositions; |
| private bool fieldHasOffsets; |
| private bool fieldHasPayloads; |
| |
| public Lucene41SkipWriter(int maxSkipLevels, int blockSize, int docCount, IndexOutput docOut, IndexOutput posOut, IndexOutput payOut) |
| : base(blockSize, 8, maxSkipLevels, docCount) |
| { |
| this.docOut = docOut; |
| this.posOut = posOut; |
| this.payOut = payOut; |
| |
| lastSkipDoc = new int[maxSkipLevels]; |
| lastSkipDocPointer = new long[maxSkipLevels]; |
| if (posOut != null) |
| { |
| lastSkipPosPointer = new long[maxSkipLevels]; |
| if (payOut != null) |
| { |
| lastSkipPayPointer = new long[maxSkipLevels]; |
| } |
| lastPayloadByteUpto = new int[maxSkipLevels]; |
| } |
| } |
| |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| public void SetField(bool fieldHasPositions, bool fieldHasOffsets, bool fieldHasPayloads) |
| { |
| this.fieldHasPositions = fieldHasPositions; |
| this.fieldHasOffsets = fieldHasOffsets; |
| this.fieldHasPayloads = fieldHasPayloads; |
| } |
| |
| public override void ResetSkip() |
| { |
| base.ResetSkip(); |
| Arrays.Fill(lastSkipDoc, 0); |
| Arrays.Fill(lastSkipDocPointer, docOut.GetFilePointer()); |
| if (fieldHasPositions) |
| { |
| Arrays.Fill(lastSkipPosPointer, posOut.GetFilePointer()); |
| if (fieldHasPayloads) |
| { |
| Arrays.Fill(lastPayloadByteUpto, 0); |
| } |
| if (fieldHasOffsets || fieldHasPayloads) |
| { |
| Arrays.Fill(lastSkipPayPointer, payOut.GetFilePointer()); |
| } |
| } |
| } |
| |
| /// <summary> |
| /// Sets the values for the current skip data. |
| /// </summary> |
| public void BufferSkip(int doc, int numDocs, long posFP, long payFP, int posBufferUpto, int payloadByteUpto) |
| { |
| this.curDoc = doc; |
| this.curDocPointer = docOut.GetFilePointer(); |
| this.curPosPointer = posFP; |
| this.curPayPointer = payFP; |
| this.curPosBufferUpto = posBufferUpto; |
| this.curPayloadByteUpto = payloadByteUpto; |
| BufferSkip(numDocs); |
| } |
| |
| protected override void WriteSkipData(int level, IndexOutput skipBuffer) |
| { |
| int delta = curDoc - lastSkipDoc[level]; |
| // if (DEBUG) { |
| // System.out.println("writeSkipData level=" + level + " lastDoc=" + curDoc + " delta=" + delta + " curDocPointer=" + curDocPointer); |
| // } |
| skipBuffer.WriteVInt32(delta); |
| lastSkipDoc[level] = curDoc; |
| |
| skipBuffer.WriteVInt32((int)(curDocPointer - lastSkipDocPointer[level])); |
| lastSkipDocPointer[level] = curDocPointer; |
| |
| if (fieldHasPositions) |
| { |
| // if (DEBUG) { |
| // System.out.println(" curPosPointer=" + curPosPointer + " curPosBufferUpto=" + curPosBufferUpto); |
| // } |
| skipBuffer.WriteVInt32((int)(curPosPointer - lastSkipPosPointer[level])); |
| lastSkipPosPointer[level] = curPosPointer; |
| skipBuffer.WriteVInt32(curPosBufferUpto); |
| |
| if (fieldHasPayloads) |
| { |
| skipBuffer.WriteVInt32(curPayloadByteUpto); |
| } |
| |
| if (fieldHasOffsets || fieldHasPayloads) |
| { |
| skipBuffer.WriteVInt32((int)(curPayPointer - lastSkipPayPointer[level])); |
| lastSkipPayPointer[level] = curPayPointer; |
| } |
| } |
| } |
| } |
| } |