From 3d7ebb0627049d329877f5cca4988d523176b3b7 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 20 Jun 2011 07:17:24 +0000 Subject: [PATCH 01/10] speed up some tests git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137529 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/index/RandomIndexWriter.java | 2 +- .../org/apache/lucene/search/QueryUtils.java | 37 ++++++++++++------- .../index/TestIndexWriterOnJRECrash.java | 4 +- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java b/lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java index 3bdbc369807..acf3585e0aa 100644 --- a/lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java +++ b/lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java @@ -114,7 +114,7 @@ public class RandomIndexWriter implements Closeable { private void switchDoDocValues() { // randomly enable / disable docValues - doDocValues = r.nextInt(10) != 0; + doDocValues = LuceneTestCase.rarely(r); } /** diff --git a/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java b/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java index 699af49f51c..4b13c62112f 100644 --- a/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java @@ -148,23 +148,35 @@ public class QueryUtils { // we can't put deleted docs before the nested reader, because // it will throw off the docIds IndexReader[] readers = new IndexReader[] { - edge < 0 ? r : IndexReader.open(makeEmptyIndex(random, 0), true), - IndexReader.open(makeEmptyIndex(random, 0), true), - new MultiReader(IndexReader.open(makeEmptyIndex(random, edge < 0 ? 4 : 0), true), - IndexReader.open(makeEmptyIndex(random, 0), true), - 0 == edge ? r : IndexReader.open(makeEmptyIndex(random, 0), true)), - IndexReader.open(makeEmptyIndex(random, 0 < edge ? 0 : 7), true), - IndexReader.open(makeEmptyIndex(random, 0), true), - new MultiReader(IndexReader.open(makeEmptyIndex(random, 0 < edge ? 0 : 5), true), - IndexReader.open(makeEmptyIndex(random, 0), true), - 0 < edge ? r : IndexReader.open(makeEmptyIndex(random, 0), true)) + edge < 0 ? r : emptyReaders[0], + emptyReaders[0], + new MultiReader(edge < 0 ? emptyReaders[4] : emptyReaders[0], + emptyReaders[0], + 0 == edge ? r : emptyReaders[0]), + 0 < edge ? emptyReaders[0] : emptyReaders[7], + emptyReaders[0], + new MultiReader(0 < edge ? emptyReaders[0] : emptyReaders[5], + emptyReaders[0], + 0 < edge ? r : emptyReaders[0]) }; IndexSearcher out = LuceneTestCase.newSearcher(new MultiReader(readers)); out.setSimilarityProvider(s.getSimilarityProvider()); return out; } + + static final IndexReader[] emptyReaders = new IndexReader[8]; + static { + try { + emptyReaders[0] = makeEmptyIndex(new Random(0), 0); + emptyReaders[4] = makeEmptyIndex(new Random(0), 4); + emptyReaders[5] = makeEmptyIndex(new Random(0), 5); + emptyReaders[7] = makeEmptyIndex(new Random(0), 7); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } - private static Directory makeEmptyIndex(Random random, final int numDeletedDocs) + private static IndexReader makeEmptyIndex(Random random, final int numDeletedDocs) throws IOException { Directory d = new MockDirectoryWrapper(random, new RAMDirectory()); IndexWriter w = new IndexWriter(d, new IndexWriterConfig( @@ -188,8 +200,7 @@ public class QueryUtils { IndexReader r = IndexReader.open(d, true); Assert.assertEquals("reader has wrong number of deleted docs", numDeletedDocs, r.numDeletedDocs()); - r.close(); - return d; + return r; } /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java b/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java index 6a62d05841e..e09cf3f9cf3 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java @@ -64,7 +64,7 @@ public class TestIndexWriterOnJRECrash extends TestNRTThreads { } } else { // we are the fork, setup a crashing thread - final int crashTime = TEST_NIGHTLY ? _TestUtil.nextInt(random, 500, 4000) : _TestUtil.nextInt(random, 300, 1000); + final int crashTime = _TestUtil.nextInt(random, 3000, 4000); Thread t = new Thread() { @Override public void run() { @@ -93,6 +93,8 @@ public class TestIndexWriterOnJRECrash extends TestNRTThreads { + "java"); cmd.add("-Xmx512m"); cmd.add("-Dtests.crashmode=true"); + // passing NIGHTLY to this test makes it run for much longer, easier to catch it in the act... + cmd.add("-Dtests.nightly=true"); cmd.add("-DtempDir=" + tempDir.getPath()); cmd.add("-Dtests.seed=" + random.nextLong() + ":" + random.nextLong()); cmd.add("-ea"); From 532f443146020845944d65f5460daa23b77d86c6 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Mon, 20 Jun 2011 07:32:12 +0000 Subject: [PATCH 02/10] SOLR-1331 -- Added a srcCore parameter to CoreAdminHandler's mergeindexes action to merge one or more cores' indexes to a target core git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137533 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../solr/common/params/CoreAdminParams.java | 4 ++ .../solr/handler/admin/CoreAdminHandler.java | 71 +++++++++++++++---- .../solr/update/DirectUpdateHandler2.java | 7 +- .../solr/update/MergeIndexesCommand.java | 19 +++-- .../solrj/request/CoreAdminRequest.java | 17 ++++- .../solrj/MergeIndexesExampleTestBase.java | 32 +++++++-- 7 files changed, 120 insertions(+), 33 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3bbe0fbb4b4..be009d6b7b9 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -266,6 +266,9 @@ New Features Karsten Sperling, Michael Gundlach, Oleg Gnatovskiy, Thomas Traeger, Harish Agarwal, yonik, Michael McCandless, Bill Bell) +* SOLR-1331 -- Added a srcCore parameter to CoreAdminHandler's mergeindexes action + to merge one or more cores' indexes to a target core (shalin) + Optimizations ---------------------- diff --git a/solr/src/common/org/apache/solr/common/params/CoreAdminParams.java b/solr/src/common/org/apache/solr/common/params/CoreAdminParams.java index 6171262df07..0691264e240 100644 --- a/solr/src/common/org/apache/solr/common/params/CoreAdminParams.java +++ b/solr/src/common/org/apache/solr/common/params/CoreAdminParams.java @@ -59,6 +59,10 @@ public interface CoreAdminParams * The directories are specified by multiple indexDir parameters. */ public final static String INDEX_DIR = "indexDir"; + /** If you merge indexes, what is the source core's name + * More than one source core can be specified by multiple srcCore parameters */ + public final static String SRC_CORE = "srcCore"; + /** The collection name in solr cloud */ public final static String COLLECTION = "collection"; diff --git a/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java index 39b9a048e22..f004c0ce888 100644 --- a/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java +++ b/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java @@ -17,6 +17,9 @@ package org.apache.solr.handler.admin; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.util.IOUtils; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CoreAdminParams; @@ -42,7 +45,9 @@ import org.apache.lucene.store.Directory; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Date; +import java.util.List; /** * @@ -171,22 +176,53 @@ public class CoreAdminHandler extends RequestHandlerBase { } protected boolean handleMergeAction(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { - boolean doPersist = false; SolrParams params = req.getParams(); - SolrParams required = params.required(); - String cname = required.get(CoreAdminParams.CORE); + String cname = params.required().get(CoreAdminParams.CORE); SolrCore core = coreContainer.getCore(cname); SolrQueryRequest wrappedReq = null; + + SolrCore[] sourceCores = null; + RefCounted[] searchers = null; + // stores readers created from indexDir param values + IndexReader[] readersToBeClosed = null; if (core != null) { try { - doPersist = coreContainer.isPersistent(); + String[] dirNames = params.getParams(CoreAdminParams.INDEX_DIR); + if (dirNames == null || dirNames.length == 0) { + String[] sources = params.getParams("srcCore"); + if (sources == null || sources.length == 0) + throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, + "At least one indexDir or srcCore must be specified"); - String[] dirNames = required.getParams(CoreAdminParams.INDEX_DIR); + sourceCores = new SolrCore[sources.length]; + for (int i = 0; i < sources.length; i++) { + String source = sources[i]; + SolrCore srcCore = coreContainer.getCore(source); + if (srcCore == null) + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, + "Core: " + source + " does not exist"); + sourceCores[i] = srcCore; + } + } else { + readersToBeClosed = new IndexReader[dirNames.length]; + DirectoryFactory dirFactory = core.getDirectoryFactory(); + for (int i = 0; i < dirNames.length; i++) { + readersToBeClosed[i] = IndexReader.open(dirFactory.open(dirNames[i]), true); + } + } - DirectoryFactory dirFactory = core.getDirectoryFactory(); - Directory[] dirs = new Directory[dirNames.length]; - for (int i = 0; i < dirNames.length; i++) { - dirs[i] = dirFactory.open(dirNames[i]); + IndexReader[] readers = null; + if (readersToBeClosed != null) { + readers = readersToBeClosed; + } else { + readers = new IndexReader[sourceCores.length]; + searchers = new RefCounted[sourceCores.length]; + for (int i = 0; i < sourceCores.length; i++) { + SolrCore solrCore = sourceCores[i]; + // record the searchers so that we can decref + searchers[i] = solrCore.getSearcher(); + readers[i] = searchers[i].get().getIndexReader(); + } } UpdateRequestProcessorChain processorChain = @@ -194,13 +230,24 @@ public class CoreAdminHandler extends RequestHandlerBase { wrappedReq = new LocalSolrQueryRequest(core, req.getParams()); UpdateRequestProcessor processor = processorChain.createProcessor(wrappedReq, rsp); - processor.processMergeIndexes(new MergeIndexesCommand(dirs, req)); + processor.processMergeIndexes(new MergeIndexesCommand(readers, req)); } finally { + if (searchers != null) { + for (RefCounted searcher : searchers) { + if (searcher != null) searcher.decref(); + } + } + if (sourceCores != null) { + for (SolrCore solrCore : sourceCores) { + if (solrCore != null) solrCore.close(); + } + } + if (readersToBeClosed != null) IOUtils.closeSafely(true, readersToBeClosed); + if (wrappedReq != null) wrappedReq.close(); core.close(); - wrappedReq.close(); } } - return doPersist; + return coreContainer.isPersistent(); } /** diff --git a/solr/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/src/java/org/apache/solr/update/DirectUpdateHandler2.java index 5106b1cb0aa..69a1454a167 100644 --- a/solr/src/java/org/apache/solr/update/DirectUpdateHandler2.java +++ b/solr/src/java/org/apache/solr/update/DirectUpdateHandler2.java @@ -20,6 +20,7 @@ package org.apache.solr.update; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.ParseException; @@ -277,10 +278,10 @@ public class DirectUpdateHandler2 extends UpdateHandler { try { log.info("start " + cmd); - Directory[] dirs = cmd.dirs; - if (dirs != null && dirs.length > 0) { + IndexReader[] readers = cmd.readers; + if (readers != null && readers.length > 0) { openWriter(); - writer.addIndexes(dirs); + writer.addIndexes(readers); rc = 1; } else { rc = 0; diff --git a/solr/src/java/org/apache/solr/update/MergeIndexesCommand.java b/solr/src/java/org/apache/solr/update/MergeIndexesCommand.java index 412d2887083..1226012f03f 100644 --- a/solr/src/java/org/apache/solr/update/MergeIndexesCommand.java +++ b/solr/src/java/org/apache/solr/update/MergeIndexesCommand.java @@ -17,6 +17,7 @@ package org.apache.solr.update; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.store.Directory; import org.apache.solr.request.SolrQueryRequest; @@ -27,25 +28,21 @@ import org.apache.solr.request.SolrQueryRequest; * */ public class MergeIndexesCommand extends UpdateCommand { - public Directory[] dirs; + public IndexReader[] readers; - public MergeIndexesCommand(SolrQueryRequest req) { - this(null, req); - } - - public MergeIndexesCommand(Directory[] dirs, SolrQueryRequest req) { + public MergeIndexesCommand(IndexReader[] readers, SolrQueryRequest req) { super("mergeIndexes", req); - this.dirs = dirs; + this.readers = readers; } @Override public String toString() { StringBuilder sb = new StringBuilder(commandName); sb.append(':'); - if (dirs != null && dirs.length > 0) { - sb.append(dirs[0]); - for (int i = 1; i < dirs.length; i++) { - sb.append(",").append(dirs[i]); + if (readers != null && readers.length > 0) { + sb.append(readers[0].directory()); + for (int i = 1; i < readers.length; i++) { + sb.append(",").append(readers[i].directory()); } } return sb.toString(); diff --git a/solr/src/solrj/org/apache/solr/client/solrj/request/CoreAdminRequest.java b/solr/src/solrj/org/apache/solr/client/solrj/request/CoreAdminRequest.java index 2e8bfafbdf1..05b4e37f0f1 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/request/CoreAdminRequest.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/request/CoreAdminRequest.java @@ -119,6 +119,7 @@ public class CoreAdminRequest extends SolrRequest public static class MergeIndexes extends CoreAdminRequest { protected List indexDirs; + protected List srcCores; public MergeIndexes() { action = CoreAdminAction.MERGEINDEXES; @@ -132,6 +133,14 @@ public class CoreAdminRequest extends SolrRequest return indexDirs; } + public List getSrcCores() { + return srcCores; + } + + public void setSrcCores(List srcCores) { + this.srcCores = srcCores; + } + @Override public SolrParams getParams() { if (action == null) { @@ -145,6 +154,11 @@ public class CoreAdminRequest extends SolrRequest params.set(CoreAdminParams.INDEX_DIR, indexDir); } } + if (srcCores != null) { + for (String srcCore : srcCores) { + params.set(CoreAdminParams.SRC_CORE, srcCore); + } + } return params; } } @@ -289,11 +303,12 @@ public class CoreAdminRequest extends SolrRequest } public static CoreAdminResponse mergeIndexes(String name, - String[] indexDirs, SolrServer server) throws SolrServerException, + String[] indexDirs, String[] srcCores, SolrServer server) throws SolrServerException, IOException { CoreAdminRequest.MergeIndexes req = new CoreAdminRequest.MergeIndexes(); req.setCoreName(name); req.setIndexDirs(Arrays.asList(indexDirs)); + req.setSrcCores(Arrays.asList(srcCores)); return req.process(server); } } diff --git a/solr/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java b/solr/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java index b3361030009..95f408057ef 100644 --- a/solr/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java +++ b/solr/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java @@ -17,6 +17,7 @@ package org.apache.solr.client.solrj; +import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -26,6 +27,8 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; import org.apache.solr.util.ExternalPaths; +import java.io.IOException; + /** * Abstract base class for testing merge indexes command * @@ -79,9 +82,9 @@ public abstract class MergeIndexesExampleTestBase extends SolrExampleTestBase { protected abstract String getIndexDirCore1(); - public void testMergeIndexes() throws Exception { + private UpdateRequest setupCores() throws SolrServerException, IOException { UpdateRequest up = new UpdateRequest(); - up.setAction(ACTION.COMMIT, true, true); + up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true); up.deleteByQuery("*:*"); up.process(getSolrCore0()); up.process(getSolrCore1()); @@ -119,11 +122,28 @@ public abstract class MergeIndexesExampleTestBase extends SolrExampleTestBase { assertEquals(1, getSolrCore1().query(new SolrQuery("id:BBB")).getResults().size()); + return up; + } + + public void testMergeIndexesByDirName() throws Exception { + UpdateRequest up = setupCores(); + // Now get the index directory of core1 and merge with core0 - String indexDir = getIndexDirCore1(); - String name = "core0"; - SolrServer coreadmin = getSolrAdmin(); - CoreAdminRequest.mergeIndexes(name, new String[] { indexDir }, coreadmin); + CoreAdminRequest.mergeIndexes("core0", new String[] {getIndexDirCore1()}, new String[0], getSolrAdmin()); + + // Now commit the merged index + up.clear(); // just do commit + up.process(getSolrCore0()); + + assertEquals(1, + getSolrCore0().query(new SolrQuery("id:AAA")).getResults().size()); + assertEquals(1, + getSolrCore0().query(new SolrQuery("id:BBB")).getResults().size()); + } + + public void testMergeIndexesByCoreName() throws Exception { + UpdateRequest up = setupCores(); + CoreAdminRequest.mergeIndexes("core0", new String[0], new String[] {"core1"}, getSolrAdmin()); // Now commit the merged index up.clear(); // just do commit From 66dd8290c0c7d50b8c8e4cbcecd3ccf9ff5d8997 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 20 Jun 2011 12:00:12 +0000 Subject: [PATCH 03/10] revert speedup, the wrapping causes fc insanity. the only reason this works today is that a new index is created in every setup/teardown, which also makes these tests slow... git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137601 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/lucene/search/QueryUtils.java | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java b/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java index 4b13c62112f..699af49f51c 100644 --- a/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java @@ -148,35 +148,23 @@ public class QueryUtils { // we can't put deleted docs before the nested reader, because // it will throw off the docIds IndexReader[] readers = new IndexReader[] { - edge < 0 ? r : emptyReaders[0], - emptyReaders[0], - new MultiReader(edge < 0 ? emptyReaders[4] : emptyReaders[0], - emptyReaders[0], - 0 == edge ? r : emptyReaders[0]), - 0 < edge ? emptyReaders[0] : emptyReaders[7], - emptyReaders[0], - new MultiReader(0 < edge ? emptyReaders[0] : emptyReaders[5], - emptyReaders[0], - 0 < edge ? r : emptyReaders[0]) + edge < 0 ? r : IndexReader.open(makeEmptyIndex(random, 0), true), + IndexReader.open(makeEmptyIndex(random, 0), true), + new MultiReader(IndexReader.open(makeEmptyIndex(random, edge < 0 ? 4 : 0), true), + IndexReader.open(makeEmptyIndex(random, 0), true), + 0 == edge ? r : IndexReader.open(makeEmptyIndex(random, 0), true)), + IndexReader.open(makeEmptyIndex(random, 0 < edge ? 0 : 7), true), + IndexReader.open(makeEmptyIndex(random, 0), true), + new MultiReader(IndexReader.open(makeEmptyIndex(random, 0 < edge ? 0 : 5), true), + IndexReader.open(makeEmptyIndex(random, 0), true), + 0 < edge ? r : IndexReader.open(makeEmptyIndex(random, 0), true)) }; IndexSearcher out = LuceneTestCase.newSearcher(new MultiReader(readers)); out.setSimilarityProvider(s.getSimilarityProvider()); return out; } - - static final IndexReader[] emptyReaders = new IndexReader[8]; - static { - try { - emptyReaders[0] = makeEmptyIndex(new Random(0), 0); - emptyReaders[4] = makeEmptyIndex(new Random(0), 4); - emptyReaders[5] = makeEmptyIndex(new Random(0), 5); - emptyReaders[7] = makeEmptyIndex(new Random(0), 7); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - private static IndexReader makeEmptyIndex(Random random, final int numDeletedDocs) + private static Directory makeEmptyIndex(Random random, final int numDeletedDocs) throws IOException { Directory d = new MockDirectoryWrapper(random, new RAMDirectory()); IndexWriter w = new IndexWriter(d, new IndexWriterConfig( @@ -200,7 +188,8 @@ public class QueryUtils { IndexReader r = IndexReader.open(d, true); Assert.assertEquals("reader has wrong number of deleted docs", numDeletedDocs, r.numDeletedDocs()); - return r; + r.close(); + return d; } /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc From acc3392ae40ab4044abf5c339179104ca7389035 Mon Sep 17 00:00:00 2001 From: Christopher John Male Date: Mon, 20 Jun 2011 12:49:15 +0000 Subject: [PATCH 04/10] SOLR-2533: Added weighting to Sort and SortField git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137612 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 +++ .../java/org/apache/lucene/search/Sort.java | 25 +++++++++++++++++++ .../org/apache/lucene/search/SortField.java | 25 +++++++++++++++++-- solr/CHANGES.txt | 3 +++ .../apache/solr/search/SolrIndexSearcher.java | 21 +--------------- .../solr/search/function/ValueSource.java | 15 +++-------- .../apache/solr/search/QueryParsingTest.java | 10 ++++---- 7 files changed, 64 insertions(+), 39 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index d5f8328cf0b..e0bee217b8d 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -434,6 +434,10 @@ New features need to lookup by that field or perform deletions against it, for example in a near-real-time setting. (Mike McCandless) +* SOLR-2533: Added support for rewriting Sort and SortFields using an + IndexSearcher. SortFields can have SortField.REWRITEABLE type which + requires they are rewritten before they are used. (Chris Male) + Optimizations * LUCENE-2588: Don't store unnecessary suffixes when writing the terms diff --git a/lucene/src/java/org/apache/lucene/search/Sort.java b/lucene/src/java/org/apache/lucene/search/Sort.java index c06d79b36b2..ac324dba37e 100644 --- a/lucene/src/java/org/apache/lucene/search/Sort.java +++ b/lucene/src/java/org/apache/lucene/search/Sort.java @@ -17,6 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ +import java.io.IOException; import java.util.Arrays; @@ -149,6 +150,30 @@ public class Sort { return fields; } + /** + * Rewrites the SortFields in this Sort, returning a new Sort if any of the fields + * changes during their rewriting. + * + * @param searcher IndexSearcher to use in the rewriting + * @return {@code this} if the Sort/Fields have not changed, or a new Sort if there + * is a change + * @throws IOException Can be thrown by the rewriting + * @lucene.experimental + */ + public Sort rewrite(IndexSearcher searcher) throws IOException { + boolean changed = false; + + SortField[] rewrittenSortFields = new SortField[fields.length]; + for (int i = 0; i < fields.length; i++) { + rewrittenSortFields[i] = fields[i].rewrite(searcher); + if (fields[i] != rewrittenSortFields[i]) { + changed = true; + } + } + + return (changed) ? new Sort(rewrittenSortFields) : this; + } + @Override public String toString() { StringBuilder buffer = new StringBuilder(); diff --git a/lucene/src/java/org/apache/lucene/search/SortField.java b/lucene/src/java/org/apache/lucene/search/SortField.java index 60e0a1a9660..9560fd75f4c 100644 --- a/lucene/src/java/org/apache/lucene/search/SortField.java +++ b/lucene/src/java/org/apache/lucene/search/SortField.java @@ -86,10 +86,14 @@ public class SortField { * This is typically slower than {@link #STRING}, which * uses ordinals to do the sorting. */ public static final int STRING_VAL = 11; - + /** Sort use byte[] index values. */ public static final int BYTES = 12; - + + /** Force rewriting of SortField using {@link SortField#rewrite(IndexSearcher)} + * before it can be used for sorting */ + public static final int REWRITEABLE = 13; + /** Represents sorting by document score (relevance). */ public static final SortField FIELD_SCORE = new SortField(null, SCORE); @@ -475,9 +479,26 @@ public class SortField { case SortField.STRING_VAL: return new FieldComparator.TermValComparator(numHits, field); + + case SortField.REWRITEABLE: + throw new IllegalStateException("SortField needs to be rewritten through Sort.rewrite(..) and SortField.rewrite(..)"); default: throw new IllegalStateException("Illegal sort type: " + type); } } + + /** + * Rewrites this SortField, returning a new SortField if a change is made. + * Subclasses should override this define their rewriting behavior when this + * SortField is of type {@link SortField#REWRITEABLE} + * + * @param searcher IndexSearcher to use during rewriting + * @return New rewritten SortField, or {@code this} if nothing has changed. + * @throws IOException Can be thrown by the rewriting + * @lucene.experimental + */ + public SortField rewrite(IndexSearcher searcher) throws IOException { + return this; + } } diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index be009d6b7b9..b0d0b0f03ca 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -145,6 +145,9 @@ New Features * SOLR-2417: Add explain info directly to return documents using ?fl=id,[explain] (ryan) +* SOLR-2533: Converted ValueSource.ValueSourceSortField over to new rewriteable Lucene + SortFields. ValueSourceSortField instances must be rewritten before they can be used. + This is done by SolrIndexSearcher when necessary. (Chris Male). Optimizations diff --git a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java index f9f355b83e4..17e251efe29 100644 --- a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -475,26 +475,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { /** Returns a weighted sort according to this searcher */ public Sort weightSort(Sort sort) throws IOException { - if (sort == null) return null; - SortField[] sorts = sort.getSort(); - - boolean needsWeighting = false; - for (SortField sf : sorts) { - if (sf instanceof SolrSortField) { - needsWeighting = true; - break; - } - } - if (!needsWeighting) return sort; - - SortField[] newSorts = Arrays.copyOf(sorts, sorts.length); - for (int i=0; i Date: Mon, 20 Jun 2011 15:31:06 +0000 Subject: [PATCH 05/10] SOLR-2611: Fix typos in the example configuration git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137665 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 ++ solr/example/solr/conf/solrconfig.xml | 32 +++++++++++++-------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index b0d0b0f03ca..a086346359a 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -313,6 +313,8 @@ Other Changes any copies of the maven-ant-tasks jar in the Ant classpath, e.g. under ~/.ant/lib/ or under the Ant installation's lib/ directory. (Steve Rowe) +* SOLR-2611: Fix typos in the example configuration (Eric Pugh via rmuir) + ================== 3.2.0 ================== Versions of Major Components --------------------- diff --git a/solr/example/solr/conf/solrconfig.xml b/solr/example/solr/conf/solrconfig.xml index f1960306e24..4bdc8fde524 100755 --- a/solr/example/solr/conf/solrconfig.xml +++ b/solr/example/solr/conf/solrconfig.xml @@ -275,7 +275,7 @@ http://wiki.apache.org/solr/UpdateXmlMessages maxDocs - Maximum number of documents to add since the last - commit before automaticly triggering a new commit. + commit before automatically triggering a new commit. maxTime - Maximum amount of time that is allowed to pass since a document was added before automaticly @@ -290,7 +290,7 @@ - @@ -936,12 +936,12 @@ Note: Each document must contain a field which serves as the - unique key. This key is used in the returned response to assoicate - ananalysis breakdown to the analyzed document. + unique key. This key is used in the returned response to associate + an analysis breakdown to the analyzed document. Like the FieldAnalysisRequestHandler, this handler also supports query analysis by sending either an "analysis.query" or "q" - request paraemter that holds the query text to be analyized. It + request parameter that holds the query text to be analyzed. It also supports the "analysis.showmatch" parameter which when set to true, all field tokens that match the query tokens will be marked as a "match". @@ -957,7 +957,7 @@ --> - + - From 0c30aeffb3d21307190d4c60e3619ee9ee6a639a Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Mon, 20 Jun 2011 18:26:07 +0000 Subject: [PATCH 06/10] fix javadocs git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137733 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/lucene/index/TieredMergePolicy.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/TieredMergePolicy.java b/lucene/src/java/org/apache/lucene/index/TieredMergePolicy.java index 9f24120f3d8..653afad45f8 100644 --- a/lucene/src/java/org/apache/lucene/index/TieredMergePolicy.java +++ b/lucene/src/java/org/apache/lucene/index/TieredMergePolicy.java @@ -187,8 +187,12 @@ public class TieredMergePolicy extends MergePolicy { /** Sets the allowed number of segments per tier. Smaller * values mean more merging but fewer segments. - * setMaxMergeAtOnce} otherwise you'll hit - * Default is 10.0. */ + * + *

NOTE: this value should be >= the {@link + * #setMaxMergeAtOnce} otherwise you'll force too much + * merging to occur.

+ * + *

Default is 10.0.

*/ public TieredMergePolicy setSegmentsPerTier(double v) { if (v < 2.0) { throw new IllegalArgumentException("segmentsPerTier must be >= 2.0 (got " + v + ")"); From 5cd96bde67fee809d1d01a44d9088f38cdd9cc16 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Mon, 20 Jun 2011 20:19:29 +0000 Subject: [PATCH 07/10] LUCENE-3209: lazy decode the per-term metadata git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137763 13f79535-47bb-0310-9956-ffa450edef68 --- .../index/codecs/memory/MemoryCodec.java | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/codecs/memory/MemoryCodec.java b/lucene/src/java/org/apache/lucene/index/codecs/memory/MemoryCodec.java index 8b103cf21b3..f753066d33d 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/memory/MemoryCodec.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/memory/MemoryCodec.java @@ -534,6 +534,7 @@ public class MemoryCodec extends Codec { private final FieldInfo field; private final BytesRefFSTEnum fstEnum; private final ByteArrayDataInput buffer = new ByteArrayDataInput(null); + private boolean didDecode; private int docFreq; private long totalTermFreq; @@ -544,16 +545,19 @@ public class MemoryCodec extends Codec { fstEnum = new BytesRefFSTEnum(fst); } - private void readTermStats() throws IOException { - buffer.reset(current.output.bytes, 0, current.output.length); - docFreq = buffer.readVInt(); - if (!field.omitTermFreqAndPositions) { - totalTermFreq = docFreq + buffer.readVLong(); - } else { - totalTermFreq = 0; + private void decodeMetaData() throws IOException { + if (!didDecode) { + buffer.reset(current.output.bytes, 0, current.output.length); + docFreq = buffer.readVInt(); + if (!field.omitTermFreqAndPositions) { + totalTermFreq = docFreq + buffer.readVLong(); + } else { + totalTermFreq = 0; + } + current.output.offset = buffer.getPosition(); + if (VERBOSE) System.out.println(" df=" + docFreq + " totTF=" + totalTermFreq + " offset=" + buffer.getPosition() + " len=" + current.output.length); + didDecode = true; } - current.output.offset = buffer.getPosition(); - if (VERBOSE) System.out.println(" df=" + docFreq + " totTF=" + totalTermFreq + " offset=" + buffer.getPosition() + " len=" + current.output.length); } @Override @@ -570,7 +574,8 @@ public class MemoryCodec extends Codec { } } - readTermStats(); + didDecode = false; + if (text.equals(current.input)) { if (VERBOSE) System.out.println(" found!"); return SeekStatus.FOUND; @@ -582,7 +587,8 @@ public class MemoryCodec extends Codec { } @Override - public DocsEnum docs(Bits skipDocs, DocsEnum reuse) { + public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { + decodeMetaData(); FSTDocsEnum docsEnum; if (reuse == null || !(reuse instanceof FSTDocsEnum)) { docsEnum = new FSTDocsEnum(field.omitTermFreqAndPositions, field.storePayloads); @@ -596,10 +602,11 @@ public class MemoryCodec extends Codec { } @Override - public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) { + public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { if (field.omitTermFreqAndPositions) { return null; } + decodeMetaData(); FSTDocsAndPositionsEnum docsAndPositionsEnum; if (reuse == null || !(reuse instanceof FSTDocsAndPositionsEnum)) { docsAndPositionsEnum = new FSTDocsAndPositionsEnum(field.omitTermFreqAndPositions, field.storePayloads); @@ -626,18 +633,20 @@ public class MemoryCodec extends Codec { if (VERBOSE) System.out.println(" END"); return null; } - readTermStats(); + didDecode = false; if (VERBOSE) System.out.println(" term=" + field.name + ":" + current.input.utf8ToString()); return current.input; } @Override - public int docFreq() { + public int docFreq() throws IOException { + decodeMetaData(); return docFreq; } @Override - public long totalTermFreq() { + public long totalTermFreq() throws IOException { + decodeMetaData(); return totalTermFreq; } @@ -657,7 +666,6 @@ public class MemoryCodec extends Codec { // NOTE: we could add this... throw new UnsupportedOperationException(); } - } private final static class TermsReader extends Terms { From 8db3c5af74160fb034b909c2b946a37b2c6f018a Mon Sep 17 00:00:00 2001 From: Christopher John Male Date: Tue, 21 Jun 2011 06:56:02 +0000 Subject: [PATCH 08/10] LUCENE-3223: Fixed if else bug preventing sorting by doc git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1137882 13f79535-47bb-0310-9956-ffa450edef68 --- .../byTask/tasks/SearchWithSortTask.java | 2 +- .../byTask/tasks/SearchWithSortTaskTest.java | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTaskTest.java diff --git a/modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTask.java b/modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTask.java index e00583f6e28..04236c2e498 100644 --- a/modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTask.java +++ b/modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTask.java @@ -57,7 +57,7 @@ public class SearchWithSortTask extends ReadTask { SortField sortField0; if (field.equals("doc")) { sortField0 = SortField.FIELD_DOC; - } if (field.equals("score")) { + } else if (field.equals("score")) { sortField0 = SortField.FIELD_SCORE; } else if (field.equals("noscore")) { doScore = false; diff --git a/modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTaskTest.java b/modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTaskTest.java new file mode 100644 index 00000000000..705ab9e06bd --- /dev/null +++ b/modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/SearchWithSortTaskTest.java @@ -0,0 +1,34 @@ +package org.apache.lucene.benchmark.byTask.tasks; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.benchmark.BenchmarkTestCase; +import org.apache.lucene.benchmark.byTask.PerfRunData; +import org.apache.lucene.benchmark.byTask.utils.Config; +import org.apache.lucene.search.SortField; + +import java.util.Properties; + +public class SearchWithSortTaskTest extends BenchmarkTestCase { + + public void testSetParams_docField() throws Exception { + SearchWithSortTask task = new SearchWithSortTask(new PerfRunData(new Config(new Properties()))); + task.setParams("doc"); + assertEquals(SortField.DOC, task.getSort().getSort()[0].getType()); + } +} From af9323950d88b7402f69fecd750195f89154f085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 21 Jun 2011 14:27:40 +0000 Subject: [PATCH 09/10] SOLR-2598: exampledocs/books.json should use name instead of title git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1138017 13f79535-47bb-0310-9956-ffa450edef68 --- solr/example/exampledocs/books.json | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/solr/example/exampledocs/books.json b/solr/example/exampledocs/books.json index 188e0734fbe..f82d5103dd2 100644 --- a/solr/example/exampledocs/books.json +++ b/solr/example/exampledocs/books.json @@ -2,7 +2,7 @@ { "id" : "978-0641723445", "cat" : ["book","hardcover"], - "title" : "The Lightning Thief", + "name" : "The Lightning Thief", "author" : "Rick Riordan", "series_t" : "Percy Jackson and the Olympians", "sequence_i" : 1, @@ -15,7 +15,7 @@ { "id" : "978-1423103349", "cat" : ["book","paperback"], - "title" : "The Sea of Monsters", + "name" : "The Sea of Monsters", "author" : "Rick Riordan", "series_t" : "Percy Jackson and the Olympians", "sequence_i" : 2, @@ -24,4 +24,28 @@ "price" : 6.49, "pages_i" : 304 } +, + { + "id" : "978-1857995879", + "cat" : ["book","paperback"], + "name" : "Sophie's World : The Greek Philosophers", + "author" : "Jostein Gaarder", + "sequence_i" : 1, + "genre_s" : "fantasy", + "inStock" : true, + "price" : 3.07, + "pages_i" : 64 + } +, + { + "id" : "978-1933988177", + "cat" : ["book","paperback"], + "name" : "Lucene in Action, Second Edition", + "author" : "Michael McCandless", + "sequence_i" : 1, + "genre_s" : "IT", + "inStock" : true, + "price" : 30.50, + "pages_i" : 475 + } ] From 1d7317f8486ad2da259b08a70d95a497b2b8e2e3 Mon Sep 17 00:00:00 2001 From: Koji Sekiguchi Date: Tue, 21 Jun 2011 14:44:53 +0000 Subject: [PATCH 10/10] add svn:ignore git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1138030 13f79535-47bb-0310-9956-ffa450edef68