Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 806979) +++ CHANGES.txt (working copy) @@ -719,6 +719,11 @@ ValueSource, but takes care when composite (multi-segment) are passed to not double RAM usage in the FieldCache. (Chris Hostetter, Mark Miller, Mike McCandless) + +37. LUCENE-1798: Added FieldCache.set/getInfoStream, which uses + FieldCacheSanityChecker to detect when a new cache entry has + caused additional insanity, printing the details at the time that + it happens. (Chris Hostetter, Mike McCandless) Optimizations Index: src/test/org/apache/lucene/search/TestFieldCache.java =================================================================== --- src/test/org/apache/lucene/search/TestFieldCache.java (revision 806979) +++ src/test/org/apache/lucene/search/TestFieldCache.java (working copy) @@ -25,6 +25,8 @@ import org.apache.lucene.util.LuceneTestCase; import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; public class TestFieldCache extends LuceneTestCase { protected IndexReader reader; @@ -58,6 +60,18 @@ reader = IndexReader.open(directory); } + public void testInfoStream() throws Exception { + try { + FieldCache cache = FieldCache.DEFAULT; + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); + cache.setInfoStream(new PrintStream(bos)); + double [] doubles = cache.getDoubles(reader, "theDouble"); + float [] floats = cache.getFloats(reader, "theDouble"); + assertTrue(bos.toString().indexOf("WARNING") != -1); + } finally { + FieldCache.DEFAULT.purgeAllCaches(); + } + } public void test() throws IOException { FieldCache cache = FieldCache.DEFAULT; Index: src/java/org/apache/lucene/search/FieldCache.java =================================================================== --- src/java/org/apache/lucene/search/FieldCache.java (revision 806979) +++ src/java/org/apache/lucene/search/FieldCache.java (working copy) @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.Serializable; +import java.io.PrintStream; import java.text.DecimalFormat; @@ -615,5 +616,13 @@ */ public abstract void purgeAllCaches(); + /** + * If non-null, FieldCacheImpl will warn whenever + * entries are created that are not sane according to + * {@link FieldCacheSanityChecker}. + */ + public void setInfoStream(PrintStream stream); + /** @see setInfoStream */ + public PrintStream getInfoStream(); } Index: src/java/org/apache/lucene/search/FieldCacheImpl.java =================================================================== --- src/java/org/apache/lucene/search/FieldCacheImpl.java (revision 806979) +++ src/java/org/apache/lucene/search/FieldCacheImpl.java (working copy) @@ -18,21 +18,22 @@ */ import java.io.IOException; +import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.WeakHashMap; -import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.NumericField; // javadoc import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermDocs; import org.apache.lucene.index.TermEnum; import org.apache.lucene.util.StringHelper; +import org.apache.lucene.util.FieldCacheSanityChecker; /** * Expert: The default cache implementation, storing all values in memory. @@ -208,12 +209,43 @@ synchronized (readerCache) { innerCache.put(key, progress.value); } + + // Only check if key.custom (the parser) is + // non-null; else, we check twice for a single + // call to FieldCache.getXXX + if (key.custom != null && wrapper != null) { + final PrintStream infoStream = wrapper.getInfoStream(); + if (infoStream != null) { + printNewInsanity(infoStream, progress.value); + } + } } return progress.value; } } return value; } + + private void printNewInsanity(PrintStream infoStream, Object value) { + final FieldCacheSanityChecker.Insanity[] insanities = FieldCacheSanityChecker.checkSanity(wrapper); + for(int i=0;i