Skip to content

Commit

Permalink
Remove recursion in implementation of Leech.next() (#47)
Browse files Browse the repository at this point in the history
If you have an index with deleted records, a call to `.next()` might
find that the next term in the index doesn't appear in any live
document.  The original implementation just skipped such terms by
recursively calling `.next()`, but this can lead to a
StackOverflowError being thrown when there are lots of deleted terms.

Switch the implementation to use a loop instead.  The logic is
otherwise unchanged.
  • Loading branch information
marktriggs authored Nov 2, 2023
1 parent 6ef902f commit 63b4998
Showing 1 changed file with 30 additions and 22 deletions.
52 changes: 30 additions & 22 deletions browse-indexing/Leech.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.io.*;
import java.util.*;

import org.apache.lucene.util.BytesRef;

import org.vufind.util.BrowseEntry;
import org.vufind.util.Normalizer;
import org.vufind.util.NormalizerFactory;
Expand Down Expand Up @@ -73,36 +75,42 @@ private boolean termExists(String t)
//
public BrowseEntry next() throws Exception
{
if (tenum == null) {
if (leafReaders.isEmpty()) {
// Nothing left to do
return null;
}
for (;;) {
if (tenum == null) {
// Load the next reader in our list and position the term enum.

if (leafReaders.isEmpty()) {
// Nothing left to do
return null;
}

// Select our next LeafReader to work from
LeafReader ir = leafReaders.remove(0).reader();
Terms terms = ir.terms(this.field);

// Select our next LeafReader to work from
LeafReader ir = leafReaders.remove(0).reader();
Terms terms = ir.terms(this.field);
if (terms == null) {
// Try the next reader
continue;
}

if (terms == null) {
// Try the next reader
return next();
tenum = terms.iterator();
}

tenum = terms.iterator();
}
BytesRef nextTerm = tenum.next();

if (nextTerm == null) {
// Exhausted this reader. Try the next one.
tenum = null;
continue;
}

if (tenum.next() != null) {
String termText = tenum.term().utf8ToString();
String termText = nextTerm.utf8ToString();

if (termExists(termText)) {
return new BrowseEntry(buildSortKey(termText), termText, termText) ;
} else {
return this.next();
return new BrowseEntry(buildSortKey(termText), termText, termText);
}
} else {
// Exhausted this reader
tenum = null;
return next();

// Try the next term
}
}
}

0 comments on commit 63b4998

Please sign in to comment.