/// <summary> /// Internal helper method used by check that iterates over /// the keys of readerFieldToValIds and generates a Collection /// of Insanity instances whenever two (or more) ReaderField instances are /// found that have an ancestry relationships. /// </summary> /// <seealso cref= InsanityType#SUBREADER </seealso> private ICollection<Insanity> CheckSubreaders(MapOfSets<int, FieldCache_Fields.CacheEntry> valIdToItems, MapOfSets<ReaderField, int> readerFieldToValIds) { List<Insanity> insanity = new List<Insanity>(23); Dictionary<ReaderField, HashSet<ReaderField>> badChildren = new Dictionary<ReaderField, HashSet<ReaderField>>(17); MapOfSets<ReaderField, ReaderField> badKids = new MapOfSets<ReaderField, ReaderField>(badChildren); // wrapper IDictionary<int, HashSet<FieldCache_Fields.CacheEntry>> viToItemSets = valIdToItems.Map; IDictionary<ReaderField, HashSet<int>> rfToValIdSets = readerFieldToValIds.Map; HashSet<ReaderField> seen = new HashSet<ReaderField>(); //IDictionary<ReaderField, ISet<int>>.KeyCollection readerFields = rfToValIdSets.Keys; foreach (ReaderField rf in rfToValIdSets.Keys) { if (seen.Contains(rf)) { continue; } IList<object> kids = GetAllDescendantReaderKeys(rf.ReaderKey); foreach (object kidKey in kids) { ReaderField kid = new ReaderField(kidKey, rf.FieldName); if (badChildren.ContainsKey(kid)) { // we've already process this kid as RF and found other problems // track those problems as our own badKids.Put(rf, kid); badKids.PutAll(rf, badChildren[kid]); badChildren.Remove(kid); } else if (rfToValIdSets.ContainsKey(kid)) { // we have cache entries for the kid badKids.Put(rf, kid); } seen.Add(kid); } seen.Add(rf); } // every mapping in badKids represents an Insanity foreach (ReaderField parent in badChildren.Keys) { HashSet<ReaderField> kids = badChildren[parent]; List<FieldCache_Fields.CacheEntry> badEntries = new List<FieldCache_Fields.CacheEntry>(kids.Count * 2); // put parent entr(ies) in first { foreach (int value in rfToValIdSets[parent]) { badEntries.AddRange(viToItemSets[value]); } } // now the entries for the descendants foreach (ReaderField kid in kids) { foreach (int value in rfToValIdSets[kid]) { badEntries.AddRange(viToItemSets[value]); } } FieldCache_Fields.CacheEntry[] badness = new FieldCache_Fields.CacheEntry[badEntries.Count]; badness = badEntries.ToArray();//LUCENE TO-DO had param of badness first insanity.Add(new Insanity(InsanityType.SUBREADER, "Found caches for descendants of " + parent.ToString(), badness)); } return insanity; }
/// <summary> /// Internal helper method used by check that iterates over /// valMismatchKeys and generates a Collection of Insanity /// instances accordingly. The MapOfSets are used to populate /// the Insanity objects. </summary> /// <seealso cref= InsanityType#VALUEMISMATCH </seealso> private ICollection<Insanity> CheckValueMismatch(MapOfSets<int, FieldCache_Fields.CacheEntry> valIdToItems, MapOfSets<ReaderField, int> readerFieldToValIds, ISet<ReaderField> valMismatchKeys) { List<Insanity> insanity = new List<Insanity>(valMismatchKeys.Count * 3); if (valMismatchKeys.Count != 0) { // we have multiple values for some ReaderFields IDictionary<ReaderField, HashSet<int>> rfMap = readerFieldToValIds.Map; IDictionary<int, HashSet<FieldCache_Fields.CacheEntry>> valMap = valIdToItems.Map; foreach (ReaderField rf in valMismatchKeys) { IList<FieldCache_Fields.CacheEntry> badEntries = new List<FieldCache_Fields.CacheEntry>(valMismatchKeys.Count * 2); foreach (int value in rfMap[rf]) { foreach (FieldCache_Fields.CacheEntry cacheEntry in valMap[value]) { badEntries.Add(cacheEntry); } } FieldCache_Fields.CacheEntry[] badness = new FieldCache_Fields.CacheEntry[badEntries.Count]; badness = badEntries.ToArray(); //LUCENE TO-DO had param of badness before insanity.Add(new Insanity(InsanityType.VALUEMISMATCH, "Multiple distinct value objects for " + rf.ToString(), badness)); } } return insanity; }