Skip to content

Commit f2a89c7

Browse files
guojialiang92jpountz
authored andcommitted
Support modifying segmentInfos.counter in IndexWriter (apache#14417)
1 parent f61f3f6 commit f2a89c7

File tree

4 files changed

+125
-1
lines changed

4 files changed

+125
-1
lines changed

lucene/CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ API Changes
5959
* GITHUB#14401: Added LeafCollector#collectRange to enable collector to take
6060
advantage of pre-aggregated data to speed up faceting. (Adrien Grand)
6161

62+
* GITHUB#14417: Support modifying segmentInfos.counter in IndexWriter (Jialiang Guo)
63+
6264
New Features
6365
---------------------
6466
(No changes)

lucene/core/src/java/org/apache/lucene/index/IndexWriter.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,25 @@ public synchronized void advanceSegmentInfosVersion(long newVersion) {
14271427
changed();
14281428
}
14291429

1430+
/**
1431+
* If {@link SegmentInfos#counter} is below {@code newCounter} then update it to this value.
1432+
*
1433+
* @lucene.internal
1434+
*/
1435+
public synchronized void advanceSegmentInfosCounter(long newCounter) {
1436+
this.ensureOpen();
1437+
if (segmentInfos.counter < newCounter) {
1438+
segmentInfos.counter = newCounter;
1439+
}
1440+
changed();
1441+
}
1442+
1443+
/** Returns the {@link SegmentInfos#counter}. */
1444+
public long getSegmentInfosCounter() {
1445+
this.ensureOpen();
1446+
return segmentInfos.counter;
1447+
}
1448+
14301449
/**
14311450
* Returns true if this index has deletions (including buffered deletions). Note that this will
14321451
* return true if there are buffered Term/Query deletions, even if it turns out those buffered

lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,4 +5037,88 @@ public void testDocValuesSkippingIndexWithoutDocValues() throws Exception {
50375037
}
50385038
}
50395039
}
5040+
5041+
public void testAdvanceSegmentInfosCounter() throws IOException {
5042+
Directory dir = newDirectory();
5043+
IndexWriter writer;
5044+
IndexReader reader;
5045+
writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())));
5046+
5047+
// add 10 documents
5048+
for (int i = 0; i < 10; i++) {
5049+
addDocWithIndex(writer, i);
5050+
writer.commit();
5051+
}
5052+
writer.advanceSegmentInfosCounter(1);
5053+
assertTrue(writer.getSegmentInfosCounter() >= 1);
5054+
5055+
writer.advanceSegmentInfosCounter(1000);
5056+
// add 40 documents
5057+
for (int i = 10; i < 50; i++) {
5058+
addDocWithIndex(writer, i);
5059+
writer.commit();
5060+
}
5061+
5062+
// There may be merge operations in the background, here only verifies that the current segment
5063+
// counter is greater than 1000.
5064+
assertTrue(writer.getSegmentInfosCounter() >= 1000);
5065+
5066+
IndexWriter.DocStats docStats = writer.getDocStats();
5067+
assertEquals(50, docStats.maxDoc);
5068+
assertEquals(50, docStats.numDocs);
5069+
writer.close();
5070+
5071+
// check that the index reader gives the same numbers.
5072+
reader = DirectoryReader.open(dir);
5073+
assertEquals(50, reader.maxDoc());
5074+
assertEquals(50, reader.numDocs());
5075+
reader.close();
5076+
dir.close();
5077+
}
5078+
5079+
public void testAdvanceSegmentCounterInCrashAndRecoveryScenario() throws IOException {
5080+
Directory dir = newDirectory();
5081+
IndexWriter writer;
5082+
IndexReader reader;
5083+
writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())));
5084+
5085+
// add 100 documents
5086+
for (int i = 0; i < 100; i++) {
5087+
addDocWithIndex(writer, i);
5088+
if (random().nextBoolean()) {
5089+
writer.commit();
5090+
}
5091+
}
5092+
IndexWriter.DocStats docStats = writer.getDocStats();
5093+
assertEquals(100, docStats.maxDoc);
5094+
assertEquals(100, docStats.numDocs);
5095+
writer.commit();
5096+
writer.close();
5097+
5098+
// recovery and advance segment counter
5099+
writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random())));
5100+
assertEquals(100, writer.getDocStats().numDocs);
5101+
long newSegmentCounter = writer.getSegmentInfosCounter() + 1000;
5102+
writer.advanceSegmentInfosCounter(newSegmentCounter);
5103+
5104+
// add 10 documents
5105+
for (int i = 0; i < 10; i++) {
5106+
addDocWithIndex(writer, i);
5107+
if (random().nextBoolean()) {
5108+
writer.commit();
5109+
}
5110+
}
5111+
5112+
assertTrue(writer.getSegmentInfosCounter() >= newSegmentCounter);
5113+
5114+
assertEquals(110, writer.getDocStats().numDocs);
5115+
// check that the index reader gives the same numbers.
5116+
writer.commit();
5117+
reader = DirectoryReader.open(dir);
5118+
assertEquals(110, reader.maxDoc());
5119+
assertEquals(110, reader.numDocs());
5120+
reader.close();
5121+
writer.close();
5122+
dir.close();
5123+
}
50405124
}

lucene/test-framework/src/java/org/apache/lucene/tests/index/ThreadedIndexingAndSearchingTestCase.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public abstract class ThreadedIndexingAndSearchingTestCase extends LuceneTestCas
8282
protected final AtomicInteger addCount = new AtomicInteger();
8383
protected final AtomicInteger delCount = new AtomicInteger();
8484
protected final AtomicInteger packCount = new AtomicInteger();
85+
protected AtomicLong maxAdvancedSegmentCounter = new AtomicLong(0);
8586

8687
protected Directory dir;
8788
protected IndexWriter writer;
@@ -189,6 +190,20 @@ public void run() {
189190
addedField = null;
190191
}
191192

193+
// Maybe advance segment counter. Run with a relatively low probability to avoid
194+
// testing slowdowns caused by synchronous operations.
195+
if (random().nextInt(7) == 5) {
196+
long newSegmentCounter = writer.getSegmentInfosCounter() + 100;
197+
writer.advanceSegmentInfosCounter(newSegmentCounter);
198+
if (VERBOSE) {
199+
System.out.println(
200+
Thread.currentThread().getName()
201+
+ " advance segment counter to "
202+
+ newSegmentCounter);
203+
}
204+
maxAdvancedSegmentCounter.accumulateAndGet(newSegmentCounter, Math::max);
205+
}
206+
192207
if (random().nextBoolean()) {
193208

194209
if (random().nextBoolean()) {
@@ -606,14 +621,18 @@ public void message(String component, String message) {
606621
thread.join();
607622
}
608623

624+
assertTrue(writer.getSegmentInfosCounter() >= maxAdvancedSegmentCounter.get());
625+
609626
if (VERBOSE) {
610627
System.out.println(
611628
"TEST: done join indexing threads ["
612629
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t0)
613630
+ " ms]; addCount="
614631
+ addCount
615632
+ " delCount="
616-
+ delCount);
633+
+ delCount
634+
+ " segmentCounter="
635+
+ writer.getSegmentInfosCounter());
617636
}
618637

619638
final IndexSearcher s = getFinalSearcher();

0 commit comments

Comments
 (0)