cvsimport
[beagle.git] / beagled / FileSystemQueryable / LuceneNameResolver.cs
blobc09d7bd6ac3bba6dcf798a6c549717c6f0558c20
1 //
2 // LuceneNameResolver.cs
3 //
4 // Copyright (C) 2005 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.IO;
31 using Lucene.Net.Documents;
32 using Lucene.Net.Index;
33 using LNS = Lucene.Net.Search;
35 using Beagle.Daemon;
36 using Beagle.Util;
38 namespace Beagle.Daemon.FileSystemQueryable {
41 // This is just a LuceneQueryingDriver with the ability to do the
42 // special secondary-index-only queries we need to map internal uris
43 // back to filenames.
46 public class LuceneNameResolver : LuceneQueryingDriver {
48 public class NameInfo {
49 public Guid Id;
50 public Guid ParentId;
51 public string Name;
52 public bool IsDirectory;
55 public LuceneNameResolver (string index_name, int minor_version, bool read_only)
56 : base (index_name, minor_version, read_only)
61 ////////////////////////////////////////////////////////////////
64 private NameInfo DocumentToNameInfo (Document doc)
66 NameInfo info;
67 info = new NameInfo ();
69 string str;
70 str = doc.Get ("Uri");
71 info.Id = GuidFu.FromUriString (str);
73 bool have_name = false;
74 bool have_parent_id = false;
75 bool have_is_dir = false;
77 foreach (Field f in doc.Fields ()) {
78 Property prop;
79 prop = GetPropertyFromDocument (f, doc, false);
80 if (prop == null)
81 continue;
83 switch (prop.Key) {
85 case Property.ExactFilenamePropKey:
86 info.Name = prop.Value;
87 have_name = true;
88 break;
90 case Property.ParentDirUriPropKey:
91 info.ParentId = GuidFu.FromUriString (prop.Value);
92 have_parent_id = true;
93 break;
95 case Property.IsDirectoryPropKey:
96 info.IsDirectory = (prop.Value == "true");
97 have_is_dir = true;
98 break;
101 if (have_name && have_parent_id && have_is_dir)
102 break;
105 return info;
108 ////////////////////////////////////////////////////////////////
110 // Pull a single record out of the index
112 private class SingletonCollector : LNS.HitCollector {
114 public int MatchId = -1;
116 public override void Collect (int id, float score)
118 if (MatchId != -1)
119 Logger.Log.Error ("Duplicate name found: replacing MatchId {0} with {1}",
120 MatchId, id);
122 MatchId = id;
126 public NameInfo GetNameInfoById (Guid id)
128 Uri uri;
129 uri = GuidFu.ToUri (id);
131 LNS.Query query;
132 query = UriQuery ("Uri", uri);
134 SingletonCollector collector;
135 collector = new SingletonCollector ();
137 LNS.IndexSearcher searcher;
138 searcher = LuceneCommon.GetSearcher (SecondaryStore);
139 searcher.Search (query, null, collector);
141 NameInfo info = null;
143 if (collector.MatchId != -1) {
144 Document doc;
145 doc = searcher.Doc (collector.MatchId);
146 info = DocumentToNameInfo (doc);
149 LuceneCommon.ReleaseSearcher (searcher);
151 return info;
154 ////////////////////////////////////////////////////////////////
156 public Guid GetIdByNameAndParentId (string name, Guid parent_id)
158 string parent_uri_str;
159 parent_uri_str = GuidFu.ToUriString (parent_id);
161 string key1;
162 key1 = PropertyToFieldName (PropertyType.Keyword, Property.ParentDirUriPropKey);
164 string key2;
165 key2 = PropertyToFieldName (PropertyType.Keyword, Property.ExactFilenamePropKey);
167 LNS.Query q1;
168 q1 = new LNS.TermQuery (new Term (key1, parent_uri_str));
170 LNS.Query q2;
171 q2 = new LNS.TermQuery (new Term (key2, name.ToLower ()));
173 LNS.BooleanQuery query;
174 query = new LNS.BooleanQuery ();
175 query.Add (q1, true, false);
176 query.Add (q2, true, false);
178 SingletonCollector collector;
179 collector = new SingletonCollector ();
181 LNS.IndexSearcher searcher;
182 searcher = LuceneCommon.GetSearcher (SecondaryStore);
183 searcher.Search (query, null, collector);
185 Guid id;
186 if (collector.MatchId != -1) {
187 Document doc;
188 doc = searcher.Doc (collector.MatchId);
189 id = GuidFu.FromUriString (doc.Get ("Uri"));
190 } else
191 id = Guid.Empty;
193 LuceneCommon.ReleaseSearcher (searcher);
195 return id;
198 ////////////////////////////////////////////////////////////////
200 // Pull all of the directories out of the index and cache them
202 // Not to be confused with LuceneQueryingDriver.BitArrayHitCollector
203 private class BitArrayHitCollector : LNS.HitCollector {
205 private BetterBitArray matches;
207 public BitArrayHitCollector (BetterBitArray matches)
209 this.matches = matches;
212 public override void Collect (int id, float score)
214 matches [id] = true;
218 public ICollection GetAllDirectoryNameInfo ()
220 // First we assemble a query to find all of the directories.
221 string field_name;
222 field_name = PropertyToFieldName (PropertyType.Keyword,
223 Property.IsDirectoryPropKey);
225 LNS.Query query;
226 query = new LNS.TermQuery (new Term (field_name, "true"));
228 // Then we actually run the query
229 LNS.IndexSearcher searcher;
230 //searcher = new LNS.IndexSearcher (SecondaryStore);
231 searcher = LuceneCommon.GetSearcher (SecondaryStore);
233 BetterBitArray matches;
234 matches = new BetterBitArray (searcher.MaxDoc ());
236 BitArrayHitCollector collector;
237 collector = new BitArrayHitCollector (matches);
239 searcher.Search (query, null, collector);
241 // Finally we pull all of the matching documents,
242 // convert them to NameInfo, and store them in a list.
244 ArrayList match_list = new ArrayList ();
245 int i = 0;
246 while (i < matches.Count) {
248 i = matches.GetNextTrueIndex (i);
249 if (i >= matches.Count)
250 break;
252 Document doc;
253 doc = searcher.Doc (i);
255 NameInfo info;
256 info = DocumentToNameInfo (doc);
258 match_list.Add (info);
260 ++i;
263 LuceneCommon.ReleaseSearcher (searcher);
265 return match_list;