2 * Copyright 2004 The Apache Software Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using Directory
= Lucene
.Net
.Store
.Directory
;
19 using IndexOutput
= Lucene
.Net
.Store
.IndexOutput
;
20 using StringHelper
= Lucene
.Net
.Util
.StringHelper
;
22 namespace Lucene
.Net
.Index
25 /// <summary>This stores a monotonically increasing set of <Term, TermInfo> pairs in a
26 /// Directory. A TermInfos can be written once, in order.
29 public sealed class TermInfosWriter
31 /// <summary>The file format version, a negative number. </summary>
32 public const int FORMAT
= - 2;
34 private FieldInfos fieldInfos
;
35 private IndexOutput output
;
36 private Term lastTerm
= new Term("", "");
37 private TermInfo lastTi
= new TermInfo();
38 private long size
= 0;
40 // TODO: the default values for these two parameters should be settable from
41 // IndexWriter. However, once that's done, folks will start setting them to
42 // ridiculous values and complaining that things don't work well, as with
43 // mergeFactor. So, let's wait until a number of folks find that alternate
44 // values work better. Note that both of these values are stored in the
45 // segment, so that it's safe to change these w/o rebuilding all indexes.
47 /// <summary>Expert: The fraction of terms in the "dictionary" which should be stored
48 /// in RAM. Smaller values use more memory, but make searching slightly
49 /// faster, while larger values use less memory and make searching slightly
50 /// slower. Searching is typically not dominated by dictionary lookup, so
51 /// tweaking this is rarely useful.
53 internal int indexInterval
= 128;
55 /// <summary>Expert: The fraction of {@link TermDocs} entries stored in skip tables,
56 /// used to accellerate {@link TermDocs#SkipTo(int)}. Larger values result in
57 /// smaller indexes, greater acceleration, but fewer accelerable cases, while
58 /// smaller values result in bigger indexes, less acceleration and more
59 /// accelerable cases. More detailed experiments would be useful here.
61 internal int skipInterval
= 16;
63 private long lastIndexPointer
= 0;
64 private bool isIndex
= false;
66 private TermInfosWriter other
= null;
68 public /*internal*/ TermInfosWriter(Directory directory
, System
.String segment
, FieldInfos fis
, int interval
)
70 Initialize(directory
, segment
, fis
, interval
, false);
71 other
= new TermInfosWriter(directory
, segment
, fis
, interval
, true);
75 private TermInfosWriter(Directory directory
, System
.String segment
, FieldInfos fis
, int interval
, bool isIndex
)
77 Initialize(directory
, segment
, fis
, interval
, isIndex
);
80 private void Initialize(Directory directory
, System
.String segment
, FieldInfos fis
, int interval
, bool isi
)
82 indexInterval
= interval
;
85 output
= directory
.CreateOutput(segment
+ (isIndex
? ".tii" : ".tis"));
86 output
.WriteInt(FORMAT
); // write format
87 output
.WriteLong(0); // leave space for size
88 output
.WriteInt(indexInterval
); // write indexInterval
89 output
.WriteInt(skipInterval
); // write skipInterval
92 /// <summary>Adds a new <Term, TermInfo> pair to the set.
93 /// Term must be lexicographically greater than all previous Terms added.
94 /// TermInfo pointers must be positive and greater than all previous.
96 public /*internal*/ void Add(Term term
, TermInfo ti
)
98 if (!isIndex
&& term
.CompareTo(lastTerm
) <= 0)
99 throw new System
.IO
.IOException("term out of order");
100 if (ti
.freqPointer
< lastTi
.freqPointer
)
101 throw new System
.IO
.IOException("freqPointer out of order");
102 if (ti
.proxPointer
< lastTi
.proxPointer
)
103 throw new System
.IO
.IOException("proxPointer out of order");
105 if (!isIndex
&& size
% indexInterval
== 0)
106 other
.Add(lastTerm
, lastTi
); // add an index term
108 WriteTerm(term
); // write term
109 output
.WriteVInt(ti
.docFreq
); // write doc freq
110 output
.WriteVLong(ti
.freqPointer
- lastTi
.freqPointer
); // write pointers
111 output
.WriteVLong(ti
.proxPointer
- lastTi
.proxPointer
);
113 if (ti
.docFreq
>= skipInterval
)
115 output
.WriteVInt(ti
.skipOffset
);
120 output
.WriteVLong(other
.output
.GetFilePointer() - lastIndexPointer
);
121 lastIndexPointer
= other
.output
.GetFilePointer(); // write pointer
128 private void WriteTerm(Term term
)
130 int start
= StringHelper
.StringDifference(lastTerm
.text
, term
.text
);
131 int length
= term
.text
.Length
- start
;
133 output
.WriteVInt(start
); // write shared prefix length
134 output
.WriteVInt(length
); // write delta length
135 output
.WriteChars(term
.text
, start
, length
); // write delta chars
137 output
.WriteVInt(fieldInfos
.FieldNumber(term
.field
)); // write field num
144 /// <summary>Called to complete TermInfos creation. </summary>
145 public /*internal*/ void Close()
147 output
.Seek(4); // write size after format
148 output
.WriteLong(size
);