2 // LuceneNameResolver.cs
4 // Copyright (C) 2005 Novell, Inc.
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.
28 using System
.Collections
;
31 using Lucene
.Net
.Documents
;
32 using Lucene
.Net
.Index
;
33 using LNS
= Lucene
.Net
.Search
;
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
46 public class LuceneNameResolver
: LuceneQueryingDriver
{
48 public class NameInfo
{
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
)
67 info
= new NameInfo ();
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 ()) {
79 prop
= GetPropertyFromDocument (f
, doc
, false);
85 case Property
.ExactFilenamePropKey
:
86 info
.Name
= prop
.Value
;
90 case Property
.ParentDirUriPropKey
:
91 info
.ParentId
= GuidFu
.FromUriString (prop
.Value
);
92 have_parent_id
= true;
95 case Property
.IsDirectoryPropKey
:
96 info
.IsDirectory
= (prop
.Value
== "true");
101 if (have_name
&& have_parent_id
&& have_is_dir
)
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
)
119 Logger
.Log
.Error ("Duplicate name found: replacing MatchId {0} with {1}",
126 public NameInfo
GetNameInfoById (Guid id
)
129 uri
= GuidFu
.ToUri (id
);
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) {
145 doc
= searcher
.Doc (collector
.MatchId
);
146 info
= DocumentToNameInfo (doc
);
149 LuceneCommon
.ReleaseSearcher (searcher
);
154 ////////////////////////////////////////////////////////////////
156 public Guid
GetIdByNameAndParentId (string name
, Guid parent_id
)
158 string parent_uri_str
;
159 parent_uri_str
= GuidFu
.ToUriString (parent_id
);
162 key1
= PropertyToFieldName (PropertyType
.Keyword
, Property
.ParentDirUriPropKey
);
165 key2
= PropertyToFieldName (PropertyType
.Keyword
, Property
.ExactFilenamePropKey
);
168 q1
= new LNS
.TermQuery (new Term (key1
, parent_uri_str
));
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
);
186 if (collector
.MatchId
!= -1) {
188 doc
= searcher
.Doc (collector
.MatchId
);
189 id
= GuidFu
.FromUriString (doc
.Get ("Uri"));
193 LuceneCommon
.ReleaseSearcher (searcher
);
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
)
218 public ICollection
GetAllDirectoryNameInfo ()
220 // First we assemble a query to find all of the directories.
222 field_name
= PropertyToFieldName (PropertyType
.Keyword
,
223 Property
.IsDirectoryPropKey
);
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 ();
246 while (i
< matches
.Count
) {
248 i
= matches
.GetNextTrueIndex (i
);
249 if (i
>= matches
.Count
)
253 doc
= searcher
.Doc (i
);
256 info
= DocumentToNameInfo (doc
);
258 match_list
.Add (info
);
263 LuceneCommon
.ReleaseSearcher (searcher
);