| /* |
| * 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 System; |
| using IndexOutput = Lucene.Net.Store.IndexOutput; |
| using UnicodeUtil = Lucene.Net.Util.UnicodeUtil; |
| |
| namespace Lucene.Net.Index |
| { |
| /// <summary>Consumes doc and freq, writing them using the current |
| /// index file format |
| /// </summary> |
| sealed class FormatPostingsDocsWriter : FormatPostingsDocsConsumer, IDisposable |
| { |
| |
| internal IndexOutput out_Renamed; |
| internal FormatPostingsTermsWriter parent; |
| internal FormatPostingsPositionsWriter posWriter; |
| internal DefaultSkipListWriter skipListWriter; |
| internal int skipInterval; |
| internal int totalNumDocs; |
| |
| internal bool omitTermFreqAndPositions; |
| internal bool storePayloads; |
| internal long freqStart; |
| internal FieldInfo fieldInfo; |
| |
| internal FormatPostingsDocsWriter(SegmentWriteState state, FormatPostingsTermsWriter parent):base() |
| { |
| this.parent = parent; |
| System.String fileName = IndexFileNames.SegmentFileName(parent.parent.segment, IndexFileNames.FREQ_EXTENSION); |
| state.flushedFiles.Add(fileName); |
| out_Renamed = parent.parent.dir.CreateOutput(fileName); |
| totalNumDocs = parent.parent.totalNumDocs; |
| |
| // TODO: abstraction violation |
| skipInterval = parent.parent.termsOut.skipInterval; |
| skipListWriter = parent.parent.skipListWriter; |
| skipListWriter.SetFreqOutput(out_Renamed); |
| |
| posWriter = new FormatPostingsPositionsWriter(state, this); |
| } |
| |
| internal void SetField(FieldInfo fieldInfo) |
| { |
| this.fieldInfo = fieldInfo; |
| omitTermFreqAndPositions = fieldInfo.omitTermFreqAndPositions; |
| storePayloads = fieldInfo.storePayloads; |
| posWriter.SetField(fieldInfo); |
| } |
| |
| internal int lastDocID; |
| internal int df; |
| |
| /// <summary>Adds a new doc in this term. If this returns null |
| /// then we just skip consuming positions/payloads. |
| /// </summary> |
| internal override FormatPostingsPositionsConsumer AddDoc(int docID, int termDocFreq) |
| { |
| |
| int delta = docID - lastDocID; |
| |
| if (docID < 0 || (df > 0 && delta <= 0)) |
| throw new CorruptIndexException("docs out of order (" + docID + " <= " + lastDocID + " )"); |
| |
| if ((++df % skipInterval) == 0) |
| { |
| // TODO: abstraction violation |
| skipListWriter.SetSkipData(lastDocID, storePayloads, posWriter.lastPayloadLength); |
| skipListWriter.BufferSkip(df); |
| } |
| |
| System.Diagnostics.Debug.Assert(docID < totalNumDocs, "docID=" + docID + " totalNumDocs=" + totalNumDocs); |
| |
| lastDocID = docID; |
| if (omitTermFreqAndPositions) |
| out_Renamed.WriteVInt(delta); |
| else if (1 == termDocFreq) |
| out_Renamed.WriteVInt((delta << 1) | 1); |
| else |
| { |
| out_Renamed.WriteVInt(delta << 1); |
| out_Renamed.WriteVInt(termDocFreq); |
| } |
| |
| return posWriter; |
| } |
| |
| private TermInfo termInfo = new TermInfo(); // minimize consing |
| internal UnicodeUtil.UTF8Result utf8 = new UnicodeUtil.UTF8Result(); |
| |
| /// <summary>Called when we are done adding docs to this term </summary> |
| internal override void Finish() |
| { |
| long skipPointer = skipListWriter.WriteSkip(out_Renamed); |
| |
| // TODO: this is abstraction violation -- we should not |
| // peek up into parents terms encoding format |
| termInfo.Set(df, parent.freqStart, parent.proxStart, (int) (skipPointer - parent.freqStart)); |
| |
| // TODO: we could do this incrementally |
| UnicodeUtil.UTF16toUTF8(parent.currentTerm, parent.currentTermStart, utf8); |
| |
| if (df > 0) |
| { |
| parent.termsOut.Add(fieldInfo.number, utf8.result, utf8.length, termInfo); |
| } |
| |
| lastDocID = 0; |
| df = 0; |
| } |
| |
| public void Dispose() |
| { |
| // Move to protected method if class becomes unsealed |
| out_Renamed.Dispose(); |
| posWriter.Dispose(); |
| } |
| } |
| } |