Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
BufferedDeletes.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System.Collections.Generic;
19 using Lucene.Net.Search;
20 using Lucene.Net.Support;
21 
22 namespace Lucene.Net.Index
23 {
24 
25  /// <summary>Holds buffered deletes, by docID, term or query. We
26  /// hold two instances of this class: one for the deletes
27  /// prior to the last flush, the other for deletes after
28  /// the last flush. This is so if we need to abort
29  /// (discard all buffered docs) we can also discard the
30  /// buffered deletes yet keep the deletes done during
31  /// previously flushed segments.
32  /// </summary>
34  {
35  internal int numTerms;
36  internal IDictionary<Term,Num> terms = null;
37  internal IDictionary<Query, int> queries = new HashMap<Query, int>();
38  internal List<int> docIDs = new List<int>();
39  internal long bytesUsed;
40  internal bool doTermSort;
41 
42  public BufferedDeletes(bool doTermSort)
43  {
44  this.doTermSort = doTermSort;
45  if (doTermSort)
46  {
47  //TODO: Used in place of TreeMap
48  terms = new SortedDictionary<Term, Num>();
49  }
50  else
51  {
52  terms = new HashMap<Term, Num>();
53  }
54  }
55 
56 
57  // Number of documents a delete term applies to.
58  internal sealed class Num
59  {
60  internal int num;
61 
62  internal Num(int num)
63  {
64  this.num = num;
65  }
66 
67  internal int GetNum()
68  {
69  return num;
70  }
71 
72  internal void SetNum(int num)
73  {
74  // Only record the new number if it's greater than the
75  // current one. This is important because if multiple
76  // threads are replacing the same doc at nearly the
77  // same time, it's possible that one thread that got a
78  // higher docID is scheduled before the other
79  // threads.
80  if (num > this.num)
81  this.num = num;
82  }
83  }
84 
85  internal virtual int Size()
86  {
87  // We use numTerms not terms.size() intentionally, so
88  // that deletes by the same term multiple times "count",
89  // ie if you ask to flush every 1000 deletes then even
90  // dup'd terms are counted towards that 1000
91  return numTerms + queries.Count + docIDs.Count;
92  }
93 
94  internal virtual void Update(BufferedDeletes @in)
95  {
96  numTerms += @in.numTerms;
97  bytesUsed += @in.bytesUsed;
98  foreach (KeyValuePair<Term, Num> term in @in.terms)
99  {
100  terms[term.Key] = term.Value;
101  }
102  foreach (KeyValuePair<Query, int> term in @in.queries)
103  {
104  queries[term.Key] = term.Value;
105  }
106 
107  docIDs.AddRange(@in.docIDs);
108  @in.Clear();
109  }
110 
111  internal virtual void Clear()
112  {
113  terms.Clear();
114  queries.Clear();
115  docIDs.Clear();
116  numTerms = 0;
117  bytesUsed = 0;
118  }
119 
120  internal virtual void AddBytesUsed(long b)
121  {
122  bytesUsed += b;
123  }
124 
125  internal virtual bool Any()
126  {
127  return terms.Count > 0 || docIDs.Count > 0 || queries.Count > 0;
128  }
129 
130  // Remaps all buffered deletes based on a completed
131  // merge
132  internal virtual void Remap(MergeDocIDRemapper mapper, SegmentInfos infos, int[][] docMaps, int[] delCounts, MergePolicy.OneMerge merge, int mergeDocCount)
133  {
134  lock (this)
135  {
136  IDictionary<Term, Num> newDeleteTerms;
137 
138  // Remap delete-by-term
139  if (terms.Count > 0)
140  {
141  if (doTermSort)
142  {
143  newDeleteTerms = new SortedDictionary<Term, Num>();
144  }
145  else
146  {
147  newDeleteTerms = new HashMap<Term, Num>();
148  }
149  foreach(var entry in terms)
150  {
151  Num num = entry.Value;
152  newDeleteTerms[entry.Key] = new Num(mapper.Remap(num.GetNum()));
153  }
154  }
155  else
156  newDeleteTerms = null;
157 
158  // Remap delete-by-docID
159  List<int> newDeleteDocIDs;
160 
161  if (docIDs.Count > 0)
162  {
163  newDeleteDocIDs = new List<int>(docIDs.Count);
164  foreach(int num in docIDs)
165  {
166  newDeleteDocIDs.Add(mapper.Remap(num));
167  }
168  }
169  else
170  newDeleteDocIDs = null;
171 
172  // Remap delete-by-query
173  HashMap<Query, int> newDeleteQueries;
174 
175  if (queries.Count > 0)
176  {
177  newDeleteQueries = new HashMap<Query, int>(queries.Count);
178  foreach(var entry in queries)
179  {
180  int num = entry.Value;
181  newDeleteQueries[entry.Key] = mapper.Remap(num);
182  }
183  }
184  else
185  newDeleteQueries = null;
186 
187  if (newDeleteTerms != null)
188  terms = newDeleteTerms;
189  if (newDeleteDocIDs != null)
190  docIDs = newDeleteDocIDs;
191  if (newDeleteQueries != null)
192  queries = newDeleteQueries;
193  }
194  }
195  }
196 }