19 using System.Collections.Generic;
22 using Lucene.Net.Support;
25 using Term = Lucene.Net.Index.Term;
29 using Single = Lucene.Net.Support.Single;
32 namespace Lucene.Net.Search
45 private IDictionary<Type, Cache> caches;
55 caches =
new HashMap<Type, Cache>(7);
56 caches[typeof(sbyte)] =
new ByteCache(
this);
57 caches[typeof(
short)] =
new ShortCache(
this);
58 caches[typeof(
int)] =
new IntCache(
this);
59 caches[typeof(
float)] =
new FloatCache(
this);
60 caches[typeof(
long)] =
new LongCache(
this);
61 caches[typeof(
double)] =
new DoubleCache(
this);
62 caches[typeof(
string)] =
new StringCache(
this);
63 caches[typeof(
StringIndex)] =
new StringIndexCache(
this);
70 public virtual void PurgeAllCaches()
85 foreach (Cache c
in caches.Values)
99 IList<CacheEntry> result =
new List<CacheEntry>(17);
100 foreach (var cacheEntry
in caches)
102 var cache = cacheEntry.
Value;
103 var cacheType = cacheEntry.Key;
104 lock (cache.readerCache)
106 foreach (var readerCacheEntry
in cache.readerCache)
108 var readerKey = readerCacheEntry.Key;
109 var innerCache = readerCacheEntry.Value;
110 foreach (var mapEntry
in innerCache)
112 Entry entry = mapEntry.Key;
113 result.Add(
new CacheEntryImpl(readerKey, entry.field, cacheType, entry.custom, mapEntry.Value));
118 return result.ToArray();
122 private sealed
class CacheEntryImpl :
CacheEntry
124 private System.Object readerKey;
125 private System.String fieldName;
126 private System.Type cacheType;
127 private System.Object custom;
128 private System.Object value;
129 internal CacheEntryImpl(System.Object readerKey, System.String fieldName, System.Type cacheType, System.Object custom, System.Object value)
131 this.readerKey = readerKey;
132 this.fieldName = fieldName;
133 this.cacheType = cacheType;
134 this.custom = custom;
143 public override object ReaderKey
145 get {
return readerKey; }
148 public override string FieldName
150 get {
return fieldName; }
153 public override Type CacheType
155 get {
return cacheType; }
158 public override object Custom
160 get {
return custom; }
163 public override object Value
165 get {
return value; }
174 internal sealed
class StopFillCacheException:System.SystemException
179 internal abstract class Cache
188 this.wrapper = wrapper;
193 internal IDictionary<object, IDictionary<Entry, object>> readerCache =
new WeakDictionary<object, IDictionary<Entry, object>>();
195 protected internal abstract System.Object CreateValue(
IndexReader reader,
Entry key);
200 object readerKey = r.FieldCacheKey;
203 readerCache.Remove(readerKey);
209 IDictionary<Entry, object> innerCache;
211 System.Object readerKey = reader.FieldCacheKey;
214 innerCache = readerCache[readerKey];
215 if (innerCache == null)
217 innerCache =
new HashMap<Entry, object>();
218 readerCache[readerKey] = innerCache;
223 value = innerCache[key];
227 value =
new CreationPlaceholder();
228 innerCache[key] = value;
231 if (value is CreationPlaceholder)
235 CreationPlaceholder progress = (CreationPlaceholder) value;
236 if (progress.value_Renamed == null)
238 progress.value_Renamed = CreateValue(reader, key);
241 innerCache[key] = progress.value_Renamed;
247 if (key.custom != null && wrapper != null)
249 System.IO.StreamWriter infoStream = wrapper.InfoStream;
250 if (infoStream != null)
252 PrintNewInsanity(infoStream, progress.value_Renamed);
256 return progress.value_Renamed;
262 private void PrintNewInsanity(System.IO.StreamWriter infoStream, System.Object value_Renamed)
265 for (
int i = 0; i < insanities.Length; i++)
268 CacheEntry[] entries = insanity.GetCacheEntries();
269 for (
int j = 0; j < entries.Length; j++)
271 if (entries[j].Value == value_Renamed)
274 infoStream.WriteLine(
"WARNING: new FieldCache insanity created\nDetails: " + insanity.ToString());
275 infoStream.WriteLine(
"\nStack:\n");
276 infoStream.WriteLine(
new System.Exception());
285 protected internal class Entry
287 internal System.String field;
288 internal System.Object custom;
291 internal Entry(System.String field, System.Object custom)
294 this.custom = custom;
298 public override bool Equals(System.Object o)
302 Entry other = (
Entry) o;
303 if (other.field == field)
305 if (other.custom == null)
310 else if (other.custom.Equals(custom))
320 public override int GetHashCode()
322 return field.GetHashCode() ^ (custom == null?0:custom.GetHashCode());
327 public virtual sbyte[] GetBytes(
IndexReader reader, System.String field)
329 return GetBytes(reader, field, null);
335 return (sbyte[]) caches[typeof(sbyte)].Get(reader,
new Entry(field, parser));
338 internal sealed
class ByteCache:Cache
340 internal ByteCache(
FieldCache wrapper):base(wrapper)
343 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
345 Entry entry = entryKey;
346 System.String field = entry.field;
350 return wrapper.GetBytes(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_BYTE_PARSER);
352 sbyte[] retArray =
new sbyte[reader.MaxDoc];
353 TermDocs termDocs = reader.TermDocs();
359 Term term = termEnum.Term;
360 if (term == null || (System.Object) term.Field != (System.Object) field)
362 sbyte termval = parser.ParseByte(term.Text);
363 termDocs.Seek(termEnum);
364 while (termDocs.Next())
366 retArray[termDocs.Doc] = termval;
369 while (termEnum.Next());
371 catch (StopFillCacheException)
385 public virtual short[] GetShorts(
IndexReader reader, System.String field)
387 return GetShorts(reader, field, null);
393 return (
short[]) caches[typeof(
short)].Get(reader,
new Entry(field, parser));
396 internal sealed
class ShortCache:Cache
398 internal ShortCache(
FieldCache wrapper):base(wrapper)
402 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
404 Entry entry = entryKey;
405 System.String field = entry.field;
409 return wrapper.GetShorts(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_SHORT_PARSER);
411 short[] retArray =
new short[reader.MaxDoc];
412 TermDocs termDocs = reader.TermDocs();
418 Term term = termEnum.Term;
419 if (term == null || (System.Object) term.Field != (System.Object) field)
421 short termval = parser.ParseShort(term.Text);
422 termDocs.Seek(termEnum);
423 while (termDocs.Next())
425 retArray[termDocs.Doc] = termval;
428 while (termEnum.Next());
430 catch (StopFillCacheException)
444 public virtual int[] GetInts(
IndexReader reader, System.String field)
446 return GetInts(reader, field, null);
452 return (
int[]) caches[typeof(
int)].Get(reader,
new Entry(field, parser));
455 internal sealed
class IntCache:Cache
457 internal IntCache(
FieldCache wrapper):base(wrapper)
461 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
463 Entry entry = entryKey;
464 System.String field = entry.field;
470 return wrapper.GetInts(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_INT_PARSER);
472 catch (System.FormatException)
474 return wrapper.GetInts(reader, field, Lucene.Net.Search.FieldCache_Fields.NUMERIC_UTILS_INT_PARSER);
477 int[] retArray = null;
478 TermDocs termDocs = reader.TermDocs();
484 Term term = termEnum.Term;
485 if (term == null || (System.Object) term.Field != (System.Object) field)
487 int termval = parser.ParseInt(term.Text);
488 if (retArray == null)
490 retArray =
new int[reader.MaxDoc];
491 termDocs.Seek(termEnum);
492 while (termDocs.Next())
494 retArray[termDocs.Doc] = termval;
497 while (termEnum.Next());
499 catch (StopFillCacheException)
507 if (retArray == null)
509 retArray =
new int[reader.MaxDoc];
517 public virtual float[] GetFloats(
IndexReader reader, System.String field)
519 return GetFloats(reader, field, null);
526 return (
float[]) caches[typeof(
float)].Get(reader,
new Entry(field, parser));
529 internal sealed
class FloatCache:Cache
531 internal FloatCache(
FieldCache wrapper):base(wrapper)
535 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
537 Entry entry = entryKey;
538 System.String field = entry.field;
544 return wrapper.GetFloats(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_FLOAT_PARSER);
546 catch (System.FormatException)
548 return wrapper.GetFloats(reader, field, Lucene.Net.Search.FieldCache_Fields.NUMERIC_UTILS_FLOAT_PARSER);
551 float[] retArray = null;
552 TermDocs termDocs = reader.TermDocs();
558 Term term = termEnum.Term;
559 if (term == null || (System.Object) term.Field != (System.Object) field)
561 float termval = parser.ParseFloat(term.Text);
562 if (retArray == null)
564 retArray =
new float[reader.MaxDoc];
565 termDocs.Seek(termEnum);
566 while (termDocs.Next())
568 retArray[termDocs.Doc] = termval;
571 while (termEnum.Next());
573 catch (StopFillCacheException)
581 if (retArray == null)
583 retArray =
new float[reader.MaxDoc];
590 public virtual long[] GetLongs(
IndexReader reader, System.String field)
592 return GetLongs(reader, field, null);
596 public virtual long[] GetLongs(
IndexReader reader, System.String field, Lucene.Net.Search.LongParser parser)
598 return (
long[]) caches[typeof(
long)].Get(reader,
new Entry(field, parser));
601 internal sealed
class LongCache:Cache
603 internal LongCache(
FieldCache wrapper):base(wrapper)
607 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
609 Entry entry = entryKey;
610 System.String field = entry.field;
611 Lucene.Net.Search.LongParser parser = (Lucene.Net.Search.LongParser) entry.custom;
616 return wrapper.GetLongs(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_LONG_PARSER);
618 catch (System.FormatException)
620 return wrapper.GetLongs(reader, field, Lucene.Net.Search.FieldCache_Fields.NUMERIC_UTILS_LONG_PARSER);
623 long[] retArray = null;
624 TermDocs termDocs = reader.TermDocs();
630 Term term = termEnum.Term;
631 if (term == null || (System.Object) term.Field != (System.Object) field)
633 long termval = parser.ParseLong(term.Text);
634 if (retArray == null)
636 retArray =
new long[reader.MaxDoc];
637 termDocs.Seek(termEnum);
638 while (termDocs.Next())
640 retArray[termDocs.Doc] = termval;
643 while (termEnum.Next());
645 catch (StopFillCacheException)
653 if (retArray == null)
655 retArray =
new long[reader.MaxDoc];
662 public virtual double[] GetDoubles(
IndexReader reader, System.String field)
664 return GetDoubles(reader, field, null);
668 public virtual double[] GetDoubles(
IndexReader reader, System.String field, Lucene.Net.Search.DoubleParser parser)
670 return (
double[]) caches[typeof(
double)].Get(reader,
new Entry(field, parser));
673 internal sealed
class DoubleCache:Cache
675 internal DoubleCache(
FieldCache wrapper):base(wrapper)
679 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
681 Entry entry = entryKey;
682 System.String field = entry.field;
683 Lucene.Net.Search.DoubleParser parser = (Lucene.Net.Search.DoubleParser) entry.custom;
688 return wrapper.GetDoubles(reader, field, Lucene.Net.Search.FieldCache_Fields.DEFAULT_DOUBLE_PARSER);
690 catch (System.FormatException)
692 return wrapper.GetDoubles(reader, field, Lucene.Net.Search.FieldCache_Fields.NUMERIC_UTILS_DOUBLE_PARSER);
695 double[] retArray = null;
696 TermDocs termDocs = reader.TermDocs();
702 Term term = termEnum.Term;
703 if (term == null || (System.Object) term.Field != (System.Object) field)
705 double termval = parser.ParseDouble(term.Text);
706 if (retArray == null)
708 retArray =
new double[reader.MaxDoc];
709 termDocs.Seek(termEnum);
710 while (termDocs.Next())
712 retArray[termDocs.Doc] = termval;
715 while (termEnum.Next());
717 catch (StopFillCacheException)
725 if (retArray == null)
727 retArray =
new double[reader.MaxDoc];
734 public virtual System.String[] GetStrings(
IndexReader reader, System.String field)
736 return (System.String[]) caches[typeof(
string)].Get(reader,
new Entry(field, (
Parser) null));
739 internal sealed
class StringCache:Cache
741 internal StringCache(
FieldCache wrapper):base(wrapper)
745 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
747 System.String field =
StringHelper.Intern(entryKey.field);
748 System.String[] retArray =
new System.String[reader.MaxDoc];
749 TermDocs termDocs = reader.TermDocs();
755 Term term = termEnum.Term;
756 if (term == null || (System.Object) term.Field != (System.Object) field)
758 System.String termval = term.Text;
759 termDocs.Seek(termEnum);
760 while (termDocs.Next())
762 retArray[termDocs.Doc] = termval;
765 while (termEnum.Next());
783 internal sealed
class StringIndexCache:Cache
785 internal StringIndexCache(
FieldCache wrapper):base(wrapper)
789 protected internal override System.Object CreateValue(
IndexReader reader, Entry entryKey)
791 System.String field =
StringHelper.Intern(entryKey.field);
792 int[] retArray =
new int[reader.MaxDoc];
793 System.String[] mterms =
new System.String[reader.MaxDoc + 1];
794 TermDocs termDocs = reader.TermDocs();
808 Term term = termEnum.Term;
809 if (term == null || term.Field != field || t >= mterms.Length)
break;
812 mterms[t] = term.Text;
814 termDocs.Seek(termEnum);
815 while (termDocs.Next())
817 retArray[termDocs.Doc] = t;
822 while (termEnum.Next());
834 mterms =
new System.String[1];
836 else if (t < mterms.Length)
840 System.String[] terms =
new System.String[t];
841 Array.Copy(mterms, 0, terms, 0, t);
846 return value_Renamed;
850 private volatile System.IO.StreamWriter infoStream;
852 public virtual StreamWriter InfoStream
854 get {
return infoStream; }
855 set { infoStream = value; }