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
IndexSets.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;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Collections.Specialized;
22 using System.Configuration;
23 using System.IO;
24 using System.Xml;
25 using Lucene.Net.Distributed;
26 using Lucene.Net.Distributed.Configuration;
27 
28 namespace Lucene.Net.Distributed.Indexing
29 {
30  /// <summary>
31  /// Definition of configurable search indexes managed by the
32  /// LuceneUpdater windows service.
33  ///
34  /// An example configuration would look like the following:
35  /// <code>
36  /// <indexsets CompoundFile="true" DeltaDirectory="c:\indexes\indexdocuments">
37  /// <indexSet id="1" action="1" analyzer="1">
38  /// <add key="localpath" value="c:\lucene\masterindex\index1" />
39  /// <copy>
40  /// <targetPath indexA="\\LuceneServer\lucene\indexA\index1" indexB="\\LuceneServer\lucene\indexA\index1" />
41  /// <statusDir value="\\LuceneServer\lucene\statusfile\" />
42  /// </copy>
43  /// <add key="bottomid" value="1"/>
44  /// <add key="topid" value="1000"/>
45  /// <add key="idcolumn" value="pkId"/>
46  /// </indexSet>
47  /// </indexsets>
48  /// </code>
49  /// </summary>
50  public class IndexSets
51  {
52  private bool _bCompoundFile;
53  private string _strDeltaDirectory;
54  private IndexSet[] _arIndexSet;
55 
56  /// <summary>
57  /// Accessor method for the configurable master indexes.
58  /// </summary>
59  public static IndexSets GetConfig
60  {
61  get { return (IndexSets)ConfigurationManager.GetSection("IndexSets"); }
62  }
63 
64  /// <summary>
65  /// Strongly-typed array of IndexSet objects as defined in a configuration section.
66  /// </summary>
67  /// <param name="node">XmlNode definition for a given IndexSet</param>
68  public void LoadIndexSetArray(XmlNode node)
69  {
70  XmlAttributeCollection attributeCollection = node.Attributes;
71 
72  try
73  {
74  this._bCompoundFile = Convert.ToBoolean(attributeCollection["CompoundFile"].Value);
75  }
76  catch (Exception)
77  {
78  throw new ConfigurationErrorsException("CompoundFile invalid: " + Environment.NewLine + node.OuterXml);
79  }
80 
81  try
82  {
83  this._strDeltaDirectory = attributeCollection["DeltaDirectory"].Value;
84  }
85  catch (Exception)
86  {
87  throw new ConfigurationErrorsException("DeltaDirectory invalid: " + Environment.NewLine + node.OuterXml);
88  }
89 
90  if (node.ChildNodes.Count == 0)
91  throw new ConfigurationErrorsException("No indexset definitions found " + Environment.NewLine + node.OuterXml);
92  this._arIndexSet = new IndexSet[node.ChildNodes.Count];
93 
94  int x=0;
95  foreach (XmlNode c in node.ChildNodes)
96  {
97  if (c.Name.ToLower()=="IndexSet")
98  {
99  IndexSet idxSet = new IndexSet(c);
100  this._arIndexSet[x] = idxSet;
101  x++;
102  }
103 
104  }
105  }
106 
107  /// <summary>
108  /// Public constructor for IndexSets. An IndexSet is defined in XML configuration
109  /// and is loaded via a custom configuration handler.
110  /// </summary>
111  public IndexSets()
112  {
113  }
114 
115  /// <summary>
116  /// Indicates if the indexes under configuration should be built in the Compound format.
117  /// </summary>
118  public bool CompoundFile
119  {
120  get {return this._bCompoundFile;}
121  }
122 
123  /// <summary>
124  /// Filesystem location of where pending update IndexDocuments are retrieved.
125  /// </summary>
126  public string DeltaDirectory
127  {
128  get {return this._strDeltaDirectory;}
129  }
130 
131  /// <summary>
132  /// Strongly-typed array of IndexSet objects as defined in a configuration section.
133  /// </summary>
134  public IndexSet[] IndexSetArray
135  {
136  get {return this._arIndexSet;}
137  }
138 
139  /// <summary>
140  /// Returns an IndexSet object for a given IndexDocument id value
141  /// </summary>
142  /// <param name="deleteId">Id value of the IndexDocument</param>
143  /// <returns>The IndexSet containing the referenced IndexDocument</returns>
144  public IndexSet GetIndexSet(int deleteId)
145  {
146  IndexSet getSet=null;
147  foreach(IndexSet idxSet in this._arIndexSet)
148  {
149  if ((deleteId>=idxSet.BottomId)&&(deleteId<=idxSet.TopId))
150  getSet=idxSet;
151  }
152  return getSet;
153  }
154 
155  /// <summary>
156  /// Queries the DeltaDirectory to access any IndexDocument files. All IndexDocuments
157  /// stored in the DeltaDirectory have been serialized to a file; the files are deserialized,
158  /// evaluated for their id value (idcolumn) and added to the pending additions for the associated
159  /// IndexSet.
160  /// </summary>
161  /// <param name="sourceDir">Filesystem path to the DeltaDirectory</param>
162  public void LoadIndexDocuments(string sourceDir)
163  {
164  DirectoryInfo oDirectoryInfo = new DirectoryInfo(sourceDir);
165  FileInfo[] arFiles = oDirectoryInfo.GetFiles("*.bin");
166  Array.Sort(arFiles, new FileNameComparer());
167  IndexSet idxSet;
168 
169  foreach (FileInfo fi in arFiles)
170  {
171  FileStream fs = new FileStream(fi.FullName, FileMode.Open);
172  IndexDocument iDoc = (IndexDocument)IndexDocument.Formatter.Deserialize(fs);
173 
174  idxSet = this.GetIndexSet(iDoc.RecordId);
175  if (idxSet != null)
176  {
177  idxSet.FileSystemDocuments.Add(fi.FullName);
178  if (idxSet.IndexDocuments.ContainsKey(iDoc.RecordId))
179  {
180  IndexDocument curDoc = (IndexDocument)idxSet.IndexDocuments[iDoc.RecordId];
181  idxSet.IndexDocuments.Add(iDoc.RecordId, iDoc);
182  }
183  else
184  idxSet.IndexDocuments.Add(iDoc.RecordId, iDoc);
185  }
186  else
187  {
188  //Handling exceptions -- write file out somewhere else?
189  if (ConfigurationManager.AppSettings["ExceptionsBasePath"] != null)
190  iDoc.Save(ConfigurationManager.AppSettings["ExceptionsBasePath"]);
191  }
192  fs.Close();
193  }
194  oDirectoryInfo=null;
195  arFiles=null;
196  }
197 
198  /// <summary>
199  /// Method to apply pending updates (additions & deletions) for all configured IndexSet objects.
200  /// </summary>
201  public void ProcessIndexDocuments()
202  {
203  foreach(IndexSet idxSet in this._arIndexSet)
204  {
205  if (idxSet.IndexDocuments.Count>0)
206  {
208  idxSet.CurrentIndex.ProcessLocalIndexAdditions(idxSet.Analzyer, idxSet.Documents, this.CompoundFile);
209  }
210  }
211  }
212 
213  /// <summary>
214  /// Method to apply updated index files from master index to slave indexes
215  /// </summary>
216  public void CopyUpdatedFiles()
217  {
218  Hashtable htUpdates = new Hashtable();
219  bool bCopy=false;
220  foreach (IndexSet idxSet in this._arIndexSet)
221  {
222  bCopy=false;
223  if (idxSet.CurrentIndex!=null && idxSet.CurrentIndex.CanCopy)
224  bCopy=idxSet.CurrentIndex.CopyIncremental();
225  if (bCopy && !htUpdates.ContainsKey(idxSet.CurrentIndex.StatusDirectory))
226  htUpdates.Add(idxSet.CurrentIndex.StatusDirectory, idxSet.CurrentIndex);
227  }
228 
229  foreach(DictionaryEntry de in htUpdates)
230  {
231  string sTargetDir = de.Key.ToString();
232  CurrentIndex ci = (CurrentIndex)de.Value;
233  ci.UpdateRefresh();
234  }
235  }
236 
237  /// <summary>
238  /// Method to apply updated index files from master index to slave indexes
239  /// </summary>
240  /// <returns>Hashtable of updated indexes</returns>
241  public Hashtable CopyAllFiles()
242  {
243  Hashtable htUpdates = new Hashtable();
244  bool bCopy = false;
245  foreach (IndexSet idxSet in this._arIndexSet)
246  {
247  bCopy = false;
248  if (idxSet.CurrentIndex != null && idxSet.CurrentIndex.CanCopy)
249  bCopy = idxSet.CurrentIndex.Copy();
250  if (bCopy && !htUpdates.ContainsKey(idxSet.CurrentIndex.StatusDirectory))
251  htUpdates.Add(idxSet.CurrentIndex.StatusDirectory, idxSet.CurrentIndex);
252  }
253 
254  foreach (DictionaryEntry de in htUpdates)
255  {
256  string sTargetDir = de.Key.ToString();
257  CurrentIndex ci = (CurrentIndex)de.Value;
258  ci.UpdateRefresh();
259  }
260 
261  return htUpdates;
262  }
263 
264  /// <summary>
265  /// Method to execute an index optimization for each configured IndexSet object
266  /// </summary>
267  public void OptimizeIndexes()
268  {
269  foreach (IndexSet idxSet in this._arIndexSet)
270  idxSet.Optimize();
271  }
272 
273  /// <summary>
274  /// Method to finalize update process for each IndexSet object
275  /// </summary>
276  public void CompleteUpdate()
277  {
278  foreach (IndexSet idxSet in this._arIndexSet)
279  {
280  if (idxSet.FileSystemDocuments.Count>0)
281  {
282  foreach(string s in idxSet.FileSystemDocuments)
283  {
284  FileInfo fi = new FileInfo(s);
285  fi.Delete();
286  }
287  idxSet.Reset();
288  }
289  }
290  }
291 
292  }
293 }