class FieldCacheSanityChecker {
/**
* 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.
*
* @see InsanityType#SUBREADER
*/
private Collection checkSubreaders(MapOfSets valIdToItems,
MapOfSets readerFieldToValIds) {
final List insanity = new ArrayList(23);
Map badChildren = new HashMap(17);
MapOfSets badKids = new MapOfSets(badChildren); // wrapper
Map viToItemSets = valIdToItems.getMap();
Map rfToValIdSets = readerFieldToValIds.getMap();
Set seen = new HashSet(17);
Set readerFields = rfToValIdSets.keySet();
Iterator rfIter = readerFields.iterator();
while (rfIter.hasNext()) {
ReaderField rf = (ReaderField) rfIter.next();
if (seen.contains(rf)) continue;
List kids = getAllDecendentReaderKeys(rf.readerKey);
for (int i = 0; i < kids.size(); i++) {
ReaderField kid = new ReaderField(kids.get(i), 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, (Collection)badChildren.get(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
Iterator parentsIter = badChildren.keySet().iterator();
while (parentsIter.hasNext()) {
ReaderField parent = (ReaderField) parentsIter.next();
Set kids = (Set) badChildren.get(parent);
List badEntries = new ArrayList(kids.size() * 2);
// put parent entr(ies) in first
{
Iterator valIter =((Set)rfToValIdSets.get(parent)).iterator();
while (valIter.hasNext()) {
badEntries.addAll((Set)viToItemSets.get(valIter.next()));
}
}
// now the entries for the descendants
Iterator kidsIter = kids.iterator();
while (kidsIter.hasNext()) {
ReaderField kid = (ReaderField) kidsIter.next();
Iterator valIter =((Set)rfToValIdSets.get(kid)).iterator();
while (valIter.hasNext()) {
badEntries.addAll((Set)viToItemSets.get(valIter.next()));
}
}
CacheEntry[] badness = new CacheEntry[badEntries.size()];
badness = (CacheEntry[]) badEntries.toArray(badness);
insanity.add(new Insanity(InsanityType.SUBREADER,
"Found caches for decendents of " +
parent.toString(),
badness));
}
return insanity;
}
}