Update the thread-local storage patch, to fix #335178
[beagle.git] / beagled / Lucene.Net / Index / TermInfosWriter.cs
blobd662d06cac5b605c7fae5a8c71d0d53ac3306a56
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 using System;
17 using Directory = Lucene.Net.Store.Directory;
18 using IndexOutput = Lucene.Net.Store.IndexOutput;
19 using StringHelper = Lucene.Net.Util.StringHelper;
20 namespace Lucene.Net.Index
23 /// <summary>This stores a monotonically increasing set of <Term, TermInfo> pairs in a
24 /// Directory. A TermInfos can be written once, in order.
25 /// </summary>
27 sealed public class TermInfosWriter
29 /// <summary>The file format version, a negative number. </summary>
30 public const int FORMAT = - 2;
32 private FieldInfos fieldInfos;
33 private IndexOutput output;
34 private Term lastTerm = new Term("", "");
35 private TermInfo lastTi = new TermInfo();
36 private long size = 0;
38 // TODO: the default values for these two parameters should be settable from
39 // IndexWriter. However, once that's done, folks will start setting them to
40 // ridiculous values and complaining that things don't work well, as with
41 // mergeFactor. So, let's wait until a number of folks find that alternate
42 // values work better. Note that both of these values are stored in the
43 // segment, so that it's safe to change these w/o rebuilding all indexes.
45 /// <summary>Expert: The fraction of terms in the "dictionary" which should be stored
46 /// in RAM. Smaller values use more memory, but make searching slightly
47 /// faster, while larger values use less memory and make searching slightly
48 /// slower. Searching is typically not dominated by dictionary lookup, so
49 /// tweaking this is rarely useful.
50 /// </summary>
51 internal int indexInterval = 128;
53 /// <summary>Expert: The fraction of {@link TermDocs} entries stored in skip tables,
54 /// used to accellerate {@link TermDocs#SkipTo(int)}. Larger values result in
55 /// smaller indexes, greater acceleration, but fewer accelerable cases, while
56 /// smaller values result in bigger indexes, less acceleration and more
57 /// accelerable cases. More detailed experiments would be useful here.
58 /// </summary>
59 internal int skipInterval = 16;
61 private long lastIndexPointer = 0;
62 private bool isIndex = false;
64 private TermInfosWriter other = null;
66 public /*internal*/ TermInfosWriter(Directory directory, System.String segment, FieldInfos fis, int interval)
68 Initialize(directory, segment, fis, interval, false);
69 other = new TermInfosWriter(directory, segment, fis, interval, true);
70 other.other = this;
73 private TermInfosWriter(Directory directory, System.String segment, FieldInfos fis, int interval, bool isIndex)
75 Initialize(directory, segment, fis, interval, isIndex);
78 private void Initialize(Directory directory, System.String segment, FieldInfos fis, int interval, bool isi)
80 indexInterval = interval;
81 fieldInfos = fis;
82 isIndex = isi;
83 output = directory.CreateOutput(segment + (isIndex ? ".tii" : ".tis"));
84 output.WriteInt(FORMAT); // write format
85 output.WriteLong(0); // leave space for size
86 output.WriteInt(indexInterval); // write indexInterval
87 output.WriteInt(skipInterval); // write skipInterval
90 /// <summary>Adds a new <Term, TermInfo> pair to the set.
91 /// Term must be lexicographically greater than all previous Terms added.
92 /// TermInfo pointers must be positive and greater than all previous.
93 /// </summary>
94 public /*internal*/ void Add(Term term, TermInfo ti)
96 if (!isIndex && term.CompareTo(lastTerm) <= 0)
97 throw new System.IO.IOException("term out of order");
98 if (ti.freqPointer < lastTi.freqPointer)
99 throw new System.IO.IOException("freqPointer out of order");
100 if (ti.proxPointer < lastTi.proxPointer)
101 throw new System.IO.IOException("proxPointer out of order");
103 if (!isIndex && size % indexInterval == 0)
104 other.Add(lastTerm, lastTi); // add an index term
106 WriteTerm(term); // write term
107 output.WriteVInt(ti.docFreq); // write doc freq
108 output.WriteVLong(ti.freqPointer - lastTi.freqPointer); // write pointers
109 output.WriteVLong(ti.proxPointer - lastTi.proxPointer);
111 if (ti.docFreq >= skipInterval)
113 output.WriteVInt(ti.skipOffset);
116 if (isIndex)
118 output.WriteVLong(other.output.GetFilePointer() - lastIndexPointer);
119 lastIndexPointer = other.output.GetFilePointer(); // write pointer
122 lastTi.Set(ti);
123 size++;
126 private void WriteTerm(Term term)
128 int start = StringHelper.StringDifference(lastTerm.text, term.text);
129 int length = term.text.Length - start;
131 output.WriteVInt(start); // write shared prefix length
132 output.WriteVInt(length); // write delta length
133 output.WriteChars(term.text, start, length); // write delta chars
135 output.WriteVInt(fieldInfos.FieldNumber(term.field)); // write Field num
137 lastTerm = term;
142 /// <summary>Called to complete TermInfos creation. </summary>
143 public /*internal*/ void Close()
145 output.Seek(4); // write size after format
146 output.WriteLong(size);
147 output.Close();
149 if (!isIndex)
150 other.Close();