diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index ef172696315..c0887b4a752 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -333,6 +333,10 @@ Bug Fixes in strings since those characters are not valid in javascript strings (although they are valid in JSON strings). (yonik) +* SOLR-2536: Add ReloadCacheRequestHandler to fix ExternalFileField bug (if reopenReaders + set to true and no index segments have been changed, commit cannot trigger reload + external file). (koji) + Other Changes ---------------------- diff --git a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java index daeb10c3a94..3e25cd301c7 100755 --- a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java +++ b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java @@ -16,23 +16,38 @@ */ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + import org.apache.lucene.index.DocsEnum; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.MultiFields; +import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; -import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.index.MultiFields; +import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.StringHelper; -import org.apache.lucene.util.BytesRef; import org.apache.solr.core.SolrCore; -import org.apache.solr.schema.SchemaField; +import org.apache.solr.handler.RequestHandlerBase; +import org.apache.solr.handler.RequestHandlerUtils; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.SchemaField; import org.apache.solr.search.QParser; +import org.apache.solr.update.processor.UpdateRequestProcessor; import org.apache.solr.util.VersionedFile; - -import java.io.*; -import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Obtains float field values from an external file. @@ -99,6 +114,10 @@ public class FileFloatSource extends ValueSource { + ",defVal="+defVal+",dataDir="+dataDir+")"; } + + public static void resetCache(){ + floatCache.resetCache(); + } private final float[] getCachedFloats(IndexReader reader) { return (float[])floatCache.get(reader, new Entry(this)); @@ -150,6 +169,14 @@ public class FileFloatSource extends ValueSource { return value; } + + public void resetCache(){ + synchronized(readerCache){ + // Map.clear() is optional and can throw UnsipportedOperationException, + // but readerCache is WeakHashMap and it supports clear(). + readerCache.clear(); + } + } } static Object onlyForTesting; // set to the last value @@ -272,5 +299,44 @@ public class FileFloatSource extends ValueSource { return vals; } + public static class ReloadCacheRequestHandler extends RequestHandlerBase { + + static final Logger log = LoggerFactory.getLogger(ReloadCacheRequestHandler.class); + @Override + public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) + throws Exception { + FileFloatSource.resetCache(); + log.debug("readerCache has been reset."); + + UpdateRequestProcessor processor = + req.getCore().getUpdateProcessingChain(null).createProcessor(req, rsp); + try{ + RequestHandlerUtils.handleCommit(req, processor, req.getParams(), true); + } + finally{ + processor.finish(); + } + } + + @Override + public String getDescription() { + return "Reload readerCache request handler"; + } + + @Override + public String getSource() { + return "$URL$"; + } + + @Override + public String getSourceId() { + return "$Id$"; + } + + @Override + public String getVersion() { + return "$Revision$"; + } + } } diff --git a/solr/src/test-files/solr/conf/solrconfig-functionquery.xml b/solr/src/test-files/solr/conf/solrconfig-functionquery.xml index 0276195c762..461b31713c5 100755 --- a/solr/src/test-files/solr/conf/solrconfig-functionquery.xml +++ b/solr/src/test-files/solr/conf/solrconfig-functionquery.xml @@ -30,6 +30,9 @@ + + 0.0 diff --git a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java index 28f427f82d6..1bf6dd8edfc 100755 --- a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -22,6 +22,8 @@ import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.Similarity; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; import org.junit.BeforeClass; import org.junit.Test; import org.junit.Ignore; @@ -191,7 +193,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { } @Test - public void testExternalField() { + public void testExternalField() throws Exception { String field = "foo_extf"; float[] ids = {100,-4,0,10,25,5,77,23,55,-78,-45,-24,63,78,94,22,34,54321,261,-627}; @@ -210,8 +212,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { assertTrue(orig == FileFloatSource.onlyForTesting); makeExternalFile(field, "0=1","UTF-8"); - assertU(adoc("id", "10000")); // will get same reader if no index change - assertU(commit()); + assertU(h.query("/reloadCache",lrf.makeRequest("",""))); singleTest(field, "sqrt(\0)"); assertTrue(orig != FileFloatSource.onlyForTesting); @@ -247,8 +248,7 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { makeExternalFile(field, sb.toString(),"UTF-8"); // make it visible - assertU(adoc("id", "10001")); // will get same reader if no index change - assertU(commit()); + assertU(h.query("/reloadCache",lrf.makeRequest("",""))); // test it float[] answers = new float[ids.length*2];