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.
17 using IndexReader
= Lucene
.Net
.Index
.IndexReader
;
18 using Term
= Lucene
.Net
.Index
.Term
;
19 using TermDocs
= Lucene
.Net
.Index
.TermDocs
;
20 using TermEnum
= Lucene
.Net
.Index
.TermEnum
;
21 namespace Lucene
.Net
.Search
24 /// <summary> Expert: The default cache implementation, storing all values in memory.
25 /// A WeakHashMap is used for storage.
27 /// <p>Created: May 19, 2004 4:40:36 PM
30 /// <author> Tim Jones (Nacimiento Software)
32 /// <since> lucene 1.4
34 /// <version> $Id: FieldCacheImpl.cs,v 1.1 2005/01/17 19:54:30 joeshaw Exp $
36 class FieldCacheImpl
: FieldCache
39 /// <summary>Expert: Every key in the internal cache is of this type. </summary>
42 internal System
.String field
; // which Field
43 internal int type
; // which SortField type
44 internal System
.Object custom
; // which custom comparator
46 /// <summary>Creates one of these objects. </summary>
47 internal Entry(System
.String field
, int type
)
49 this.field
= String
.Intern(field
);
54 /// <summary>Creates one of these objects for a custom comparator. </summary>
55 internal Entry(System
.String field
, System
.Object custom
)
57 this.field
= String
.Intern(field
);
58 this.type
= SortField
.CUSTOM
;
62 /// <summary>Two of these are equal iff they reference the same field and type. </summary>
63 public override bool Equals(System
.Object o
)
67 Entry other
= (Entry
) o
;
68 if ((System
.Object
) other
.field
== (System
.Object
) field
&& other
.type
== type
)
70 if (other
.custom
== null)
75 else if (other
.custom
.Equals(custom
))
84 /// <summary>Composes a hashcode based on the field and type. </summary>
85 public override int GetHashCode()
87 return field
.GetHashCode() ^ type ^
(custom
== null ? 0 : custom
.GetHashCode());
92 /// <summary>The internal cache. Maps Entry to array of interpreted term values. *</summary>
93 internal System
.Collections
.IDictionary cache
= new System
.Collections
.Hashtable();
95 /// <summary>See if an object is in the cache. </summary>
96 internal virtual System
.Object
Lookup(IndexReader reader
, System
.String field
, int type
)
98 Entry entry
= new Entry(field
, type
);
101 System
.Collections
.Hashtable readerCache
= (System
.Collections
.Hashtable
) cache
[reader
];
102 if (readerCache
== null)
104 return readerCache
[entry
];
108 /// <summary>See if a custom object is in the cache. </summary>
109 internal virtual System
.Object
Lookup(IndexReader reader
, System
.String field
, System
.Object comparer
)
111 Entry entry
= new Entry(field
, comparer
);
114 System
.Collections
.Hashtable readerCache
= (System
.Collections
.Hashtable
) cache
[reader
];
115 if (readerCache
== null)
117 return readerCache
[entry
];
121 /// <summary>Put an object into the cache. </summary>
122 internal virtual System
.Object
Store(IndexReader reader
, System
.String field
, int type
, System
.Object value_Renamed
)
124 Entry entry
= new Entry(field
, type
);
127 System
.Collections
.Hashtable readerCache
= (System
.Collections
.Hashtable
) cache
[reader
];
128 if (readerCache
== null)
130 readerCache
= new System
.Collections
.Hashtable();
131 cache
[reader
] = readerCache
;
133 System
.Object tempObject
;
134 tempObject
= readerCache
[entry
];
135 readerCache
[entry
] = value_Renamed
;
140 /// <summary>Put a custom object into the cache. </summary>
141 internal virtual System
.Object
Store(IndexReader reader
, System
.String field
, System
.Object comparer
, System
.Object value_Renamed
)
143 Entry entry
= new Entry(field
, comparer
);
146 System
.Collections
.Hashtable readerCache
= (System
.Collections
.Hashtable
) cache
[reader
];
147 if (readerCache
== null)
149 readerCache
= new System
.Collections
.Hashtable();
150 cache
[reader
] = readerCache
;
152 System
.Object tempObject
;
153 tempObject
= readerCache
[entry
];
154 readerCache
[entry
] = value_Renamed
;
160 public virtual int[] GetInts(IndexReader reader
, System
.String field
)
162 field
= String
.Intern(field
);
163 System
.Object ret
= Lookup(reader
, field
, SortField
.INT
);
166 int[] retArray
= new int[reader
.MaxDoc()];
167 if (retArray
.Length
> 0)
169 TermDocs termDocs
= reader
.TermDocs();
170 TermEnum termEnum
= reader
.Terms(new Term(field
, ""));
173 if (termEnum
.Term() == null)
175 throw new System
.SystemException("no terms in Field " + field
);
179 Term term
= termEnum
.Term();
180 if ((System
.Object
) term
.Field() != (System
.Object
) field
)
182 int termval
= System
.Int32
.Parse(term
.Text());
183 termDocs
.Seek(termEnum
);
184 while (termDocs
.Next())
186 retArray
[termDocs
.Doc()] = termval
;
189 while (termEnum
.Next());
197 Store(reader
, field
, SortField
.INT
, retArray
);
204 public virtual float[] GetFloats(IndexReader reader
, System
.String field
)
206 field
= String
.Intern(field
);
207 System
.Object ret
= Lookup(reader
, field
, SortField
.FLOAT
);
210 float[] retArray
= new float[reader
.MaxDoc()];
211 if (retArray
.Length
> 0)
213 TermDocs termDocs
= reader
.TermDocs();
214 TermEnum termEnum
= reader
.Terms(new Term(field
, ""));
217 if (termEnum
.Term() == null)
219 throw new System
.SystemException("no terms in Field " + field
);
223 Term term
= termEnum
.Term();
224 if ((System
.Object
) term
.Field() != (System
.Object
) field
)
229 termval
= SupportClass
.Single
.Parse(term
.Text());
235 termDocs
.Seek(termEnum
);
236 while (termDocs
.Next())
238 retArray
[termDocs
.Doc()] = termval
;
241 while (termEnum
.Next());
249 Store(reader
, field
, SortField
.FLOAT
, retArray
);
252 return (float[]) ret
;
256 public virtual System
.String
[] GetStrings(IndexReader reader
, System
.String field
)
258 field
= String
.Intern(field
);
259 System
.Object ret
= Lookup(reader
, field
, SortField
.STRING
);
262 System
.String
[] retArray
= new System
.String
[reader
.MaxDoc()];
263 if (retArray
.Length
> 0)
265 TermDocs termDocs
= reader
.TermDocs();
266 TermEnum termEnum
= reader
.Terms(new Term(field
, ""));
269 if (termEnum
.Term() == null)
271 throw new System
.SystemException("no terms in Field " + field
);
275 Term term
= termEnum
.Term();
276 if ((System
.Object
) term
.Field() != (System
.Object
) field
)
278 System
.String termval
= term
.Text();
279 termDocs
.Seek(termEnum
);
280 while (termDocs
.Next())
282 retArray
[termDocs
.Doc()] = termval
;
285 while (termEnum
.Next());
293 Store(reader
, field
, SortField
.STRING
, retArray
);
296 return (System
.String
[]) ret
;
300 public virtual StringIndex
GetStringIndex(IndexReader reader
, System
.String field
)
302 field
= String
.Intern(field
);
303 System
.Object ret
= Lookup(reader
, field
, Lucene
.Net
.Search
.FieldCache_Fields
.STRING_INDEX
);
306 int[] retArray
= new int[reader
.MaxDoc()];
307 System
.String
[] mterms
= new System
.String
[reader
.MaxDoc() + 1];
308 if (retArray
.Length
> 0)
310 TermDocs termDocs
= reader
.TermDocs();
311 TermEnum termEnum
= reader
.Terms(new Term(field
, ""));
312 int t
= 0; // current term number
314 // an entry for documents that have no terms in this Field
315 // should a document with no terms be at top or bottom?
316 // this puts them at the top - if it is changed, FieldDocSortedHitQueue
317 // needs to change as well.
322 if (termEnum
.Term() == null)
324 throw new System
.SystemException("no terms in Field " + field
);
328 Term term
= termEnum
.Term();
329 if ((System
.Object
) term
.Field() != (System
.Object
) field
)
333 // we expect that there is at most one term per document
334 if (t
>= mterms
.Length
)
335 throw new System
.SystemException("there are more terms than documents in Field \"" + field
+ "\"");
336 mterms
[t
] = term
.Text();
338 termDocs
.Seek(termEnum
);
339 while (termDocs
.Next())
341 retArray
[termDocs
.Doc()] = t
;
346 while (termEnum
.Next());
356 // if there are no terms, make the term array
357 // have a single null entry
358 mterms
= new System
.String
[1];
360 else if (t
< mterms
.Length
)
362 // if there are less terms than documents,
363 // trim off the dead array space
364 System
.String
[] terms
= new System
.String
[t
];
365 Array
.Copy(mterms
, 0, terms
, 0, t
);
369 StringIndex value_Renamed
= new StringIndex(retArray
, mterms
);
370 Store(reader
, field
, Lucene
.Net
.Search
.FieldCache_Fields
.STRING_INDEX
, value_Renamed
);
371 return value_Renamed
;
373 return (StringIndex
) ret
;
376 /// <summary>The pattern used to detect integer values in a Field </summary>
377 /// <summary>removed for java 1.3 compatibility
378 /// protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
382 /// <summary>The pattern used to detect float values in a Field </summary>
383 /// <summary> removed for java 1.3 compatibility
384 /// protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
388 public virtual System
.Object
GetAuto(IndexReader reader
, System
.String field
)
390 field
= String
.Intern(field
);
391 System
.Object ret
= Lookup(reader
, field
, SortField
.AUTO
);
394 TermEnum enumerator
= reader
.Terms(new Term(field
, ""));
397 Term term
= enumerator
.Term();
400 throw new System
.SystemException("no terms in Field " + field
+ " - cannot determine sort type");
402 if ((System
.Object
) term
.Field() == (System
.Object
) field
)
404 System
.String termtext
= term
.Text().Trim();
406 /// <summary> Java 1.4 level code:
407 /// if (pIntegers.matcher(termtext).matches())
408 /// return IntegerSortedHitQueue.comparator (reader, enumerator, Field);
409 /// else if (pFloats.matcher(termtext).matches())
410 /// return FloatSortedHitQueue.comparator (reader, enumerator, Field);
413 // Java 1.3 level code:
416 System
.Int32
.Parse(termtext
);
417 ret
= GetInts(reader
, field
);
419 catch (System
.FormatException nfe1
)
423 System
.Single
.Parse(termtext
);
424 ret
= GetFloats(reader
, field
);
426 catch (System
.FormatException nfe2
)
428 ret
= GetStringIndex(reader
, field
);
433 Store(reader
, field
, SortField
.AUTO
, ret
);
438 throw new System
.SystemException("Field \"" + field
+ "\" does not appear to be indexed");
450 public virtual System
.IComparable
[] GetCustom(IndexReader reader
, System
.String field
, SortComparator comparator
)
452 field
= String
.Intern(field
);
453 System
.Object ret
= Lookup(reader
, field
, comparator
);
456 System
.IComparable
[] retArray
= new System
.IComparable
[reader
.MaxDoc()];
457 if (retArray
.Length
> 0)
459 TermDocs termDocs
= reader
.TermDocs();
460 TermEnum termEnum
= reader
.Terms(new Term(field
, ""));
463 if (termEnum
.Term() == null)
465 throw new System
.SystemException("no terms in Field " + field
);
469 Term term
= termEnum
.Term();
470 if ((System
.Object
) term
.Field() != (System
.Object
) field
)
472 System
.IComparable termval
= comparator
.GetComparable(term
.Text());
473 termDocs
.Seek(termEnum
);
474 while (termDocs
.Next())
476 retArray
[termDocs
.Doc()] = termval
;
479 while (termEnum
.Next());
487 Store(reader
, field
, SortField
.CUSTOM
, retArray
);
490 return (System
.IComparable
[]) ret
;