/// <summary> Quick and dirty convenience method that instantiates an instance with /// "good defaults" and uses it to test the CacheEntry[] /// </summary> /// <seealso cref="check"> /// </seealso> public static Insanity[] CheckSanity(CacheEntry[] cacheEntries) { FieldCacheSanityChecker sanityChecker = new FieldCacheSanityChecker(); // doesn't check for interned sanityChecker.SetRamUsageEstimator(new RamUsageEstimator(false)); return sanityChecker.Check(cacheEntries); }
/// <summary> Tests a CacheEntry[] for indication of "insane" cache usage. /// <p/> /// NOTE:FieldCache CreationPlaceholder objects are ignored. /// (:TODO: is this a bad idea? are we masking a real problem?) /// <p/> /// </summary> public Insanity[] Check(params CacheEntry[] cacheEntries) { if (null == cacheEntries || 0 == cacheEntries.Length) { return(new Insanity[0]); } if (null != ramCalc) { for (int i = 0; i < cacheEntries.Length; i++) { cacheEntries[i].EstimateSize(ramCalc); } } // the indirect mapping lets MapOfSet dedup identical valIds for us // // maps the (valId) identityhashCode of cache values to // sets of CacheEntry instances MapOfSets <int, CacheEntry> valIdToItems = new MapOfSets <int, CacheEntry>(new Dictionary <int, HashSet <CacheEntry> >(17)); // maps ReaderField keys to Sets of ValueIds MapOfSets <ReaderField, int> readerFieldToValIds = new MapOfSets <ReaderField, int>(new Dictionary <ReaderField, HashSet <int> >(17)); // // any keys that we know result in more then one valId HashSet <ReaderField> valMismatchKeys = new HashSet <ReaderField>(); // iterate over all the cacheEntries to get the mappings we'll need for (int i = 0; i < cacheEntries.Length; i++) { CacheEntry item = cacheEntries[i]; System.Object val = item.Value; if (val.GetType().IsGenericType&& val.GetType().GetGenericTypeDefinition() == typeof(Lazy <>)) { continue; } ReaderField rf = new ReaderField(item.ReaderKey, item.FieldName); System.Int32 valId = val.GetHashCode(); // indirect mapping, so the MapOfSet will dedup identical valIds for us valIdToItems.Put(valId, item); if (1 < readerFieldToValIds.Put(rf, valId)) { valMismatchKeys.Add(rf); } } List <Insanity> insanity = new List <Insanity>(valMismatchKeys.Count * 3); insanity.AddRange(CheckValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); insanity.AddRange(CheckSubreaders(valIdToItems, readerFieldToValIds)); return(insanity.ToArray()); }
public Insanity(InsanityType type, System.String msg, CacheEntry[] entries) { if (null == type) { throw new System.ArgumentException("Insanity requires non-null InsanityType"); } if (null == entries || 0 == entries.Length) { throw new System.ArgumentException("Insanity requires non-null/non-empty CacheEntry[]"); } this.type = type; this.msg = msg; this.entries = entries; }
/// <summary> Tests a CacheEntry[] for indication of "insane" cache usage. /// <p/> /// NOTE:FieldCache CreationPlaceholder objects are ignored. /// (:TODO: is this a bad idea? are we masking a real problem?) /// <p/> /// </summary> public Insanity[] Check(CacheEntry[] cacheEntries) { if (null == cacheEntries || 0 == cacheEntries.Length) return new Insanity[0]; if (null != ramCalc) { for (int i = 0; i < cacheEntries.Length; i++) { cacheEntries[i].EstimateSize(ramCalc); } } // the indirect mapping lets MapOfSet dedup identical valIds for us // // maps the (valId) identityhashCode of cache values to // sets of CacheEntry instances MapOfSets<int,CacheEntry> valIdToItems = new MapOfSets<int,CacheEntry>(new Dictionary<int,Dictionary<CacheEntry,CacheEntry>>(17)); // maps ReaderField keys to Sets of ValueIds MapOfSets<ReaderField,int> readerFieldToValIds = new MapOfSets<ReaderField,int>(new Dictionary<ReaderField,Dictionary<int,int>>(17)); // // any keys that we know result in more then one valId // TODO: This will be a HashSet<T> when we start using .NET Framework 3.5 Dictionary<ReaderField, ReaderField> valMismatchKeys = new Dictionary<ReaderField, ReaderField>(); // iterate over all the cacheEntries to get the mappings we'll need for (int i = 0; i < cacheEntries.Length; i++) { CacheEntry item = cacheEntries[i]; System.Object val = item.GetValue(); if (val is Lucene.Net.Search.CreationPlaceholder) continue; ReaderField rf = new ReaderField(item.GetReaderKey(), item.GetFieldName()); System.Int32 valId = val.GetHashCode(); // indirect mapping, so the MapOfSet will dedup identical valIds for us valIdToItems.Put(valId, item); if (1 < readerFieldToValIds.Put(rf, valId)) { if (!valMismatchKeys.ContainsKey(rf)) { valMismatchKeys.Add(rf, rf); } } } List<Insanity> insanity = new List<Insanity>(valMismatchKeys.Count * 3); insanity.AddRange(CheckValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); insanity.AddRange(CheckSubreaders(valIdToItems, readerFieldToValIds)); return insanity.ToArray(); }
/// <summary> Tests a CacheEntry[] for indication of "insane" cache usage. /// <p/> /// NOTE:FieldCache CreationPlaceholder objects are ignored. /// (:TODO: is this a bad idea? are we masking a real problem?) /// <p/> /// </summary> public Insanity[] Check(params CacheEntry[] cacheEntries) { if (null == cacheEntries || 0 == cacheEntries.Length) { return(new Insanity[0]); } if (null != ramCalc) { for (int i = 0; i < cacheEntries.Length; i++) { cacheEntries[i].EstimateSize(ramCalc); } } // the indirect mapping lets MapOfSet dedup identical valIds for us // // maps the (valId) identityhashCode of cache values to // sets of CacheEntry instances MapOfSets <int, CacheEntry> valIdToItems = new MapOfSets <int, CacheEntry>(new Dictionary <int, Dictionary <CacheEntry, CacheEntry> >(17)); // maps ReaderField keys to Sets of ValueIds MapOfSets <ReaderField, int> readerFieldToValIds = new MapOfSets <ReaderField, int>(new Dictionary <ReaderField, Dictionary <int, int> >(17)); // // any keys that we know result in more then one valId // TODO: This will be a HashSet<T> when we start using .NET Framework 3.5 Dictionary <ReaderField, ReaderField> valMismatchKeys = new Dictionary <ReaderField, ReaderField>(); // iterate over all the cacheEntries to get the mappings we'll need for (int i = 0; i < cacheEntries.Length; i++) { CacheEntry item = cacheEntries[i]; System.Object val = item.GetValue(); if (val is Lucene.Net.Search.CreationPlaceholder) { continue; } ReaderField rf = new ReaderField(item.GetReaderKey(), item.GetFieldName()); System.Int32 valId = val.GetHashCode(); // indirect mapping, so the MapOfSet will dedup identical valIds for us valIdToItems.Put(valId, item); if (1 < readerFieldToValIds.Put(rf, valId)) { if (!valMismatchKeys.ContainsKey(rf)) { valMismatchKeys.Add(rf, rf); } } } List <Insanity> insanity = new List <Insanity>(valMismatchKeys.Count * 3); insanity.AddRange(CheckValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); insanity.AddRange(CheckSubreaders(valIdToItems, readerFieldToValIds)); return(insanity.ToArray()); }