SOLR-3621: fix rare concurrency issue when opening a new IndexWriter for replication or rollback.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1362232 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Robert Miller 2012-07-16 20:08:46 +00:00
parent 905510ace8
commit 922ad2bff2
12 changed files with 296 additions and 155 deletions

View File

@ -87,6 +87,9 @@ Bug Fixes
* SOLR-3377: edismax fails to correctly parse a fielded query wrapped by parens.
This regression was introduced in 3.6. (Bernd Fehling, Jan Høydahl, yonik)
* SOLR-3621: fix rare concurrency issue when opening a new IndexWriter for replication or rollback.
(Mark Miller)
Other Changes

View File

@ -1180,8 +1180,12 @@ public final class SolrCore implements SolrInfoMBean {
if (updateHandlerReopens) {
// SolrCore.verbose("start reopen from",previousSearcher,"writer=",writer);
IndexWriter writer = getUpdateHandler().getSolrCoreState().getIndexWriter(this);
newReader = DirectoryReader.openIfChanged(currentReader, writer, true);
RefCounted<IndexWriter> writer = getUpdateHandler().getSolrCoreState().getIndexWriter(this);
try {
newReader = DirectoryReader.openIfChanged(currentReader, writer.get(), true);
} finally {
writer.decref();
}
} else {
// verbose("start reopen without writer, reader=", currentReader);

View File

@ -19,6 +19,7 @@ package org.apache.solr.handler;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.HttpClient;
import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexWriter;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpClientUtil;
@ -276,7 +277,12 @@ public class SnapPuller {
if (force && commit.getGeneration() != 0) {
// since we won't get the files for an empty index,
// we just clear ours and commit
core.getUpdateHandler().getSolrCoreState().getIndexWriter(core).deleteAll();
RefCounted<IndexWriter> iw = core.getUpdateHandler().getSolrCoreState().getIndexWriter(core);
try {
iw.get().deleteAll();
} finally {
iw.decref();
}
SolrQueryRequest req = new LocalSolrQueryRequest(core,
new ModifiableSolrParams());
core.getUpdateHandler().commit(new CommitUpdateCommand(req, false));

View File

@ -24,6 +24,7 @@ import org.apache.solr.cloud.RecoveryStrategy;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.RefCounted;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -40,26 +41,67 @@ public final class DefaultSolrCoreState extends SolrCoreState {
private boolean recoveryRunning;
private RecoveryStrategy recoveryStrat;
private boolean closed = false;
private RefCounted<IndexWriter> refCntWriter;
private boolean pauseWriter;
private boolean writerFree = true;
public DefaultSolrCoreState(DirectoryFactory directoryFactory) {
this.directoryFactory = directoryFactory;
}
@Override
public synchronized IndexWriter getIndexWriter(SolrCore core) throws IOException {
if (indexWriter == null) {
indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2", false, false);
public synchronized RefCounted<IndexWriter> getIndexWriter(SolrCore core)
throws IOException {
while (pauseWriter) {
try {
wait();
} catch (InterruptedException e) {}
}
return indexWriter;
if (indexWriter == null) {
indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2", false,
false);
}
if (refCntWriter == null) {
refCntWriter = new RefCounted<IndexWriter>(indexWriter) {
@Override
public void close() {
synchronized (DefaultSolrCoreState.this) {
writerFree = true;
DefaultSolrCoreState.this.notifyAll();
}
}
};
}
writerFree = false;
notifyAll();
refCntWriter.incref();
return refCntWriter;
}
@Override
public synchronized void newIndexWriter(SolrCore core) throws IOException {
// we need to wait for the Writer to fall out of use
// first lets stop it from being lent out
pauseWriter = true;
// then lets wait until its out of use
while(!writerFree) {
try {
wait();
} catch (InterruptedException e) {}
}
if (indexWriter != null) {
indexWriter.close();
}
indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2",
false, true);
// we need to null this so it picks up the new writer next get call
refCntWriter = null;
pauseWriter = false;
notifyAll();
}
@Override

View File

@ -137,7 +137,12 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
private void deleteAll() throws IOException {
SolrCore.log.info(core.getLogId()+"REMOVING ALL DOCUMENTS FROM INDEX");
solrCoreState.getIndexWriter(core).deleteAll();
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
iw.get().deleteAll();
} finally {
iw.decref();
}
}
protected void rollbackWriter() throws IOException {
@ -148,115 +153,124 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
@Override
public int addDoc(AddUpdateCommand cmd) throws IOException {
IndexWriter writer = solrCoreState.getIndexWriter(core);
addCommands.incrementAndGet();
addCommandsCumulative.incrementAndGet();
int rc=-1;
// if there is no ID field, don't overwrite
if( idField == null ) {
cmd.overwrite = false;
}
int rc = -1;
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
if (cmd.overwrite) {
// Check for delete by query commands newer (i.e. reordered). This should always be null on a leader
List<UpdateLog.DBQ> deletesAfter = null;
if (ulog != null && cmd.version > 0) {
deletesAfter = ulog.getDBQNewer(cmd.version);
}
if (deletesAfter != null) {
log.info("Reordered DBQs detected. Update="+cmd+" DBQs="+deletesAfter);
List<Query> dbqList = new ArrayList<Query>(deletesAfter.size());
for (UpdateLog.DBQ dbq : deletesAfter) {
try {
DeleteUpdateCommand tmpDel = new DeleteUpdateCommand(cmd.req);
tmpDel.query = dbq.q;
tmpDel.version = -dbq.version;
dbqList.add( getQuery(tmpDel) );
} catch (Exception e) {
log.error("Exception parsing reordered query : " + dbq, e);
IndexWriter writer = iw.get();
addCommands.incrementAndGet();
addCommandsCumulative.incrementAndGet();
// if there is no ID field, don't overwrite
if (idField == null) {
cmd.overwrite = false;
}
try {
if (cmd.overwrite) {
// Check for delete by query commands newer (i.e. reordered). This
// should always be null on a leader
List<UpdateLog.DBQ> deletesAfter = null;
if (ulog != null && cmd.version > 0) {
deletesAfter = ulog.getDBQNewer(cmd.version);
}
if (deletesAfter != null) {
log.info("Reordered DBQs detected. Update=" + cmd + " DBQs="
+ deletesAfter);
List<Query> dbqList = new ArrayList<Query>(deletesAfter.size());
for (UpdateLog.DBQ dbq : deletesAfter) {
try {
DeleteUpdateCommand tmpDel = new DeleteUpdateCommand(cmd.req);
tmpDel.query = dbq.q;
tmpDel.version = -dbq.version;
dbqList.add(getQuery(tmpDel));
} catch (Exception e) {
log.error("Exception parsing reordered query : " + dbq, e);
}
}
}
addAndDelete(cmd, dbqList);
} else {
// normal update
Term updateTerm;
Term idTerm = new Term(idField.getName(), cmd.getIndexedId());
boolean del = false;
if (cmd.updateTerm == null) {
updateTerm = idTerm;
addAndDelete(cmd, dbqList);
} else {
del = true;
updateTerm = cmd.updateTerm;
// normal update
Term updateTerm;
Term idTerm = new Term(idField.getName(), cmd.getIndexedId());
boolean del = false;
if (cmd.updateTerm == null) {
updateTerm = idTerm;
} else {
del = true;
updateTerm = cmd.updateTerm;
}
Document luceneDocument = cmd.getLuceneDocument();
// SolrCore.verbose("updateDocument",updateTerm,luceneDocument,writer);
writer.updateDocument(updateTerm, luceneDocument,
schema.getAnalyzer());
// SolrCore.verbose("updateDocument",updateTerm,"DONE");
if (del) { // ensure id remains unique
BooleanQuery bq = new BooleanQuery();
bq.add(new BooleanClause(new TermQuery(updateTerm),
Occur.MUST_NOT));
bq.add(new BooleanClause(new TermQuery(idTerm), Occur.MUST));
writer.deleteDocuments(bq);
}
// Add to the transaction log *after* successfully adding to the
// index, if there was no error.
// This ordering ensures that if we log it, it's definitely been
// added to the the index.
// This also ensures that if a commit sneaks in-between, that we
// know everything in a particular
// log version was definitely committed.
if (ulog != null) ulog.add(cmd);
}
Document luceneDocument = cmd.getLuceneDocument();
// SolrCore.verbose("updateDocument",updateTerm,luceneDocument,writer);
writer.updateDocument(updateTerm, luceneDocument, schema.getAnalyzer());
// SolrCore.verbose("updateDocument",updateTerm,"DONE");
if(del) { // ensure id remains unique
BooleanQuery bq = new BooleanQuery();
bq.add(new BooleanClause(new TermQuery(updateTerm), Occur.MUST_NOT));
bq.add(new BooleanClause(new TermQuery(idTerm), Occur.MUST));
writer.deleteDocuments(bq);
}
// Add to the transaction log *after* successfully adding to the index, if there was no error.
// This ordering ensures that if we log it, it's definitely been added to the the index.
// This also ensures that if a commit sneaks in-between, that we know everything in a particular
// log version was definitely committed.
} else {
// allow duplicates
writer.addDocument(cmd.getLuceneDocument(), schema.getAnalyzer());
if (ulog != null) ulog.add(cmd);
}
} else {
// allow duplicates
writer.addDocument(cmd.getLuceneDocument(), schema.getAnalyzer());
if (ulog != null) ulog.add(cmd);
if ((cmd.getFlags() & UpdateCommand.IGNORE_AUTOCOMMIT) == 0) {
commitTracker.addedDocument(-1);
softCommitTracker.addedDocument(cmd.commitWithin);
}
rc = 1;
} finally {
if (rc != 1) {
numErrors.incrementAndGet();
numErrorsCumulative.incrementAndGet();
} else {
numDocsPending.incrementAndGet();
}
}
if ((cmd.getFlags() & UpdateCommand.IGNORE_AUTOCOMMIT) == 0) {
commitTracker.addedDocument( -1 );
softCommitTracker.addedDocument( cmd.commitWithin );
}
rc = 1;
} finally {
if (rc!=1) {
numErrors.incrementAndGet();
numErrorsCumulative.incrementAndGet();
} else {
numDocsPending.incrementAndGet();
}
iw.decref();
}
return rc;
}
private void updateDeleteTrackers(DeleteUpdateCommand cmd) {
if ((cmd.getFlags() & UpdateCommand.IGNORE_AUTOCOMMIT) == 0) {
softCommitTracker.deletedDocument( cmd.commitWithin );
softCommitTracker.deletedDocument(cmd.commitWithin);
if (commitTracker.getTimeUpperBound() > 0) {
commitTracker.scheduleCommitWithin(commitTracker.getTimeUpperBound());
}
if (softCommitTracker.getTimeUpperBound() > 0) {
softCommitTracker.scheduleCommitWithin(softCommitTracker.getTimeUpperBound());
softCommitTracker.scheduleCommitWithin(softCommitTracker
.getTimeUpperBound());
}
}
}
// we don't return the number of docs deleted because it's not always possible to quickly know that info.
@Override
@ -264,11 +278,14 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
deleteByIdCommands.incrementAndGet();
deleteByIdCommandsCumulative.incrementAndGet();
IndexWriter writer = solrCoreState.getIndexWriter(core);
Term deleteTerm = new Term(idField.getName(), cmd.getIndexedId());
// SolrCore.verbose("deleteDocuments",deleteTerm,writer);
writer.deleteDocuments(deleteTerm);
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
iw.get().deleteDocuments(deleteTerm);
} finally {
iw.decref();
}
// SolrCore.verbose("deleteDocuments",deleteTerm,"DONE");
if (ulog != null) ulog.delete(cmd);
@ -343,7 +360,12 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
if (delAll) {
deleteAll();
} else {
solrCoreState.getIndexWriter(core).deleteDocuments(q);
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
iw.get().deleteDocuments(q);
} finally {
iw.decref();
}
}
if (ulog != null) ulog.deleteByQuery(cmd);
@ -364,23 +386,29 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
/** Add a document execute the deletes as atomically as possible */
private void addAndDelete(AddUpdateCommand cmd, List<Query> dbqList) throws IOException {
private void addAndDelete(AddUpdateCommand cmd, List<Query> dbqList)
throws IOException {
Document luceneDocument = cmd.getLuceneDocument();
Term idTerm = new Term(idField.getName(), cmd.getIndexedId());
// see comment in deleteByQuery
synchronized (this) {
IndexWriter writer = solrCoreState.getIndexWriter(core);
writer.updateDocument(idTerm, luceneDocument, core.getSchema().getAnalyzer());
for (Query q : dbqList) {
writer.deleteDocuments(q);
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
IndexWriter writer = iw.get();
writer.updateDocument(idTerm, luceneDocument, core.getSchema()
.getAnalyzer());
for (Query q : dbqList) {
writer.deleteDocuments(q);
}
} finally {
iw.decref();
}
if (ulog != null) ulog.add(cmd, true);
}
}
@ -395,7 +423,12 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
IndexReader[] readers = cmd.readers;
if (readers != null && readers.length > 0) {
solrCoreState.getIndexWriter(core).addIndexes(readers);
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
iw.get().addIndexes(readers);
} finally {
iw.decref();
}
rc = 1;
} else {
rc = 0;
@ -418,9 +451,12 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
try {
log.info("start "+cmd);
IndexWriter writer = solrCoreState.getIndexWriter(core);
writer.prepareCommit();
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
iw.get().prepareCommit();
} finally {
iw.decref();
}
log.info("end_prepareCommit");
@ -438,7 +474,6 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
return;
}
IndexWriter writer = solrCoreState.getIndexWriter(core);
if (cmd.optimize) {
optimizeCommands.incrementAndGet();
} else {
@ -473,27 +508,35 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
commitTracker.cancelPendingCommit();
}
if (cmd.optimize) {
writer.forceMerge(cmd.maxOptimizeSegments);
} else if (cmd.expungeDeletes) {
writer.forceMergeDeletes();
}
if (!cmd.softCommit) {
synchronized (this) { // sync is currently needed to prevent preCommit from being called between preSoft and postSoft... see postSoft comments.
if (ulog != null) ulog.preCommit(cmd);
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
try {
IndexWriter writer = iw.get();
if (cmd.optimize) {
writer.forceMerge(cmd.maxOptimizeSegments);
} else if (cmd.expungeDeletes) {
writer.forceMergeDeletes();
}
// SolrCore.verbose("writer.commit() start writer=",writer);
final Map<String,String> commitData = new HashMap<String,String>();
commitData.put(SolrIndexWriter.COMMIT_TIME_MSEC_KEY, String.valueOf(System.currentTimeMillis()));
writer.commit(commitData);
// SolrCore.verbose("writer.commit() end");
numDocsPending.set(0);
callPostCommitCallbacks();
} else {
callPostSoftCommitCallbacks();
if (!cmd.softCommit) {
synchronized (this) { // sync is currently needed to prevent preCommit
// from being called between preSoft and
// postSoft... see postSoft comments.
if (ulog != null) ulog.preCommit(cmd);
}
// SolrCore.verbose("writer.commit() start writer=",writer);
final Map<String,String> commitData = new HashMap<String,String>();
commitData.put(SolrIndexWriter.COMMIT_TIME_MSEC_KEY,
String.valueOf(System.currentTimeMillis()));
writer.commit(commitData);
// SolrCore.verbose("writer.commit() end");
numDocsPending.set(0);
callPostCommitCallbacks();
} else {
callPostSoftCommitCallbacks();
}
} finally {
iw.decref();
}

View File

@ -23,6 +23,7 @@ import org.apache.lucene.index.IndexWriter;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.RefCounted;
/**
* The state in this class can be easily shared between SolrCores across
@ -46,7 +47,7 @@ public abstract class SolrCoreState {
*
* @throws IOException
*/
public abstract IndexWriter getIndexWriter(SolrCore core) throws IOException;
public abstract RefCounted<IndexWriter> getIndexWriter(SolrCore core) throws IOException;
/**
* Decrement the number of references to this state. When then number of

View File

@ -52,6 +52,7 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.util.RefCounted;
import org.junit.BeforeClass;
@ -125,9 +126,14 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
// test merge factor picked up
SolrCore core = h.getCore();
IndexWriter writer = ((DirectUpdateHandler2)core.getUpdateHandler()).getSolrCoreState().getIndexWriter(core);
assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor());
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2) core
.getUpdateHandler()).getSolrCoreState().getIndexWriter(core);
try {
assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy) iw
.get().getConfig().getMergePolicy()).getMergeFactor());
} finally {
iw.decref();
}
// test stats call
NamedList stats = core.getStatistics();
assertEquals("collection1", stats.get("coreName"));

View File

@ -139,7 +139,7 @@ public abstract class AbstractDistributedZkTestCase extends BaseDistributedSearc
}
}
}
if (!sawLiveRecovering || cnt == 120) {
if (!sawLiveRecovering || cnt == 520) {
if (!sawLiveRecovering) {
if (verbose) System.out.println("no one is recoverying");
} else {

View File

@ -28,6 +28,7 @@ import org.apache.solr.core.SolrCore;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.util.RefCounted;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -61,10 +62,12 @@ public class BasicZkTest extends AbstractZkTestCase {
// test merge factor picked up
SolrCore core = h.getCore();
IndexWriter writer = ((DirectUpdateHandler2)core.getUpdateHandler()).getSolrCoreState().getIndexWriter(core);
assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor());
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2)core.getUpdateHandler()).getSolrCoreState().getIndexWriter(core);
try {
assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy)iw.get().getConfig().getMergePolicy()).getMergeFactor());
} finally {
iw.decref();
}
lrf.args.put(CommonParams.VERSION, "2.2");
assertQ("test query on empty index", request("qlkciyopsbgzyvkylsjhchghjrdf"),
"//result[@numFound='0']");

View File

@ -23,6 +23,7 @@ import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.handler.admin.ShowFileRequestHandler;
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.update.SolrIndexConfig;
import org.apache.solr.util.RefCounted;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Node;
@ -115,8 +116,15 @@ public class TestConfig extends SolrTestCaseJ4 {
@Test
public void testTermIndexInterval() throws Exception {
IndexWriter writer = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
int interval = writer.getConfig().getTermIndexInterval();
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2) h.getCore()
.getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
int interval = 0;
try {
IndexWriter writer = iw.get();
interval = writer.getConfig().getTermIndexInterval();
} finally {
iw.decref();
}
assertEquals(256, interval);
}

View File

@ -24,6 +24,7 @@ import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.util.RefCounted;
public class TestPropInject extends AbstractSolrTestCase {
@Override
@ -37,14 +38,25 @@ public class TestPropInject extends AbstractSolrTestCase {
}
public void testMergePolicy() throws Exception {
IndexWriter writer = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
LogByteSizeMergePolicy mp = (LogByteSizeMergePolicy)writer.getConfig().getMergePolicy();
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
LogByteSizeMergePolicy mp;
try {
mp = (LogByteSizeMergePolicy)iw.get().getConfig().getMergePolicy();
} finally {
iw.decref();
}
assertEquals(64.0, mp.getMaxMergeMB(), 0);
}
public void testProps() throws Exception {
IndexWriter writer = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
ConcurrentMergeScheduler cms = (ConcurrentMergeScheduler)writer.getConfig().getMergeScheduler();
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
ConcurrentMergeScheduler cms;
try {
cms = (ConcurrentMergeScheduler)iw.get().getConfig().getMergeScheduler();
} finally {
iw.decref();
}
assertEquals(2, cms.getMaxThreadCount());
}
}

View File

@ -22,6 +22,7 @@ import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.util.RefCounted;
import org.junit.BeforeClass;
import org.junit.Test;
@ -33,15 +34,27 @@ public class TestPropInjectDefaults extends SolrTestCaseJ4 {
@Test
public void testMergePolicyDefaults() throws Exception {
IndexWriter writer = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
LogByteSizeMergePolicy mp = (LogByteSizeMergePolicy)writer.getConfig().getMergePolicy();
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2) h.getCore()
.getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
LogByteSizeMergePolicy mp;
try {
mp = (LogByteSizeMergePolicy) iw.get().getConfig().getMergePolicy();
} finally {
iw.decref();
}
assertEquals(32.0, mp.getMaxMergeMB(), 0);
}
@Test
public void testPropsDefaults() throws Exception {
IndexWriter writer = ((DirectUpdateHandler2)h.getCore().getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
ConcurrentMergeScheduler cms = (ConcurrentMergeScheduler)writer.getConfig().getMergeScheduler();
RefCounted<IndexWriter> iw = ((DirectUpdateHandler2) h.getCore()
.getUpdateHandler()).getSolrCoreState().getIndexWriter(h.getCore());
ConcurrentMergeScheduler cms;
try {
cms = (ConcurrentMergeScheduler) iw.get().getConfig().getMergeScheduler();
} finally {
iw.decref();
}
assertEquals(4, cms.getMaxThreadCount());
}