Skip to content

Commit

Permalink
Check the real memory circuit breaker when building global ordinals
Browse files Browse the repository at this point in the history
  • Loading branch information
iverase committed Nov 22, 2023
1 parent b924343 commit adb8f5d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@

import org.apache.logging.log4j.Logger;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.FilterLeafReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.packed.PackedInts;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
import org.elasticsearch.index.fielddata.LeafOrdinalsFieldData;
import org.elasticsearch.index.fielddata.plain.AbstractLeafOrdinalsFieldData;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.script.field.ToScriptFieldFactory;

import java.io.IOException;
Expand All @@ -37,7 +39,7 @@ public enum GlobalOrdinalsBuilder {
public static IndexOrdinalsFieldData build(
final IndexReader indexReader,
IndexOrdinalsFieldData indexFieldData,
CircuitBreakerService breakerService,
CircuitBreaker breaker,
Logger logger,
ToScriptFieldFactory<SortedSetDocValues> toScriptFieldFactory
) throws IOException {
Expand All @@ -50,9 +52,25 @@ public static IndexOrdinalsFieldData build(
atomicFD[i] = indexFieldData.load(indexReader.leaves().get(i));
subs[i] = atomicFD[i].getOrdinalsValues();
}
final OrdinalMap ordinalMap = OrdinalMap.build(null, subs, PackedInts.DEFAULT);
final TermsEnum[] termsEnums = new TermsEnum[subs.length];
final long[] weights = new long[subs.length];
final long[] counter = new long[1];
for (int i = 0; i < subs.length; ++i) {
termsEnums[i] = new FilterLeafReader.FilterTermsEnum(subs[i].termsEnum()) {
@Override
public BytesRef next() throws IOException {
// check parent circuit breaker every 8192 calls
if ((++counter[0] & 0x1FFF) == 0x1FFF) {
breaker.addEstimateBytesAndMaybeBreak(0L, "Global Ordinals");
}
return in.next();
}
};
weights[i] = subs[i].getValueCount();
}
final OrdinalMap ordinalMap = OrdinalMap.build(null, termsEnums, weights, PackedInts.DEFAULT);
final long memorySizeInBytes = ordinalMap.ramBytesUsed();
breakerService.getBreaker(CircuitBreaker.FIELDDATA).addWithoutBreaking(memorySizeInBytes);
breaker.addWithoutBreaking(memorySizeInBytes);

TimeValue took = new TimeValue(System.nanoTime() - startTimeNS, TimeUnit.NANOSECONDS);
if (logger.isDebugEnabled()) {
Expand Down Expand Up @@ -108,5 +126,4 @@ public void close() {}
took
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
import org.elasticsearch.index.fielddata.LeafOrdinalsFieldData;
Expand Down Expand Up @@ -136,7 +137,13 @@ private IndexOrdinalsFieldData loadGlobalInternal(DirectoryReader indexReader) {

@Override
public IndexOrdinalsFieldData loadGlobalDirect(DirectoryReader indexReader) throws Exception {
return GlobalOrdinalsBuilder.build(indexReader, this, breakerService, logger, toScriptFieldFactory);
return GlobalOrdinalsBuilder.build(
indexReader,
this,
breakerService.getBreaker(CircuitBreaker.FIELDDATA),
logger,
toScriptFieldFactory
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.common.breaker.CircuitBreakingException;
import org.elasticsearch.common.breaker.NoopCircuitBreaker;
import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader;
import org.elasticsearch.index.fielddata.plain.PagedBytesIndexFieldData;
import org.elasticsearch.index.fielddata.plain.SortedSetOrdinalsIndexFieldData;
Expand Down Expand Up @@ -78,6 +81,52 @@ public void testLoadGlobal_neverCacheIfFieldIsMissing() throws Exception {
dir.close();
}

public void testGlobalOrdinalsCircuitBreaker() throws Exception {
Directory dir = newDirectory();
IndexWriterConfig iwc = new IndexWriterConfig(null);
iwc.setMergePolicy(NoMergePolicy.INSTANCE);
IndexWriter iw = new IndexWriter(dir, iwc);
long numDocs = randomIntBetween(8192, 2 * 8192);

for (int i = 1; i <= numDocs; i++) {
Document doc = new Document();
doc.add(new SortedSetDocValuesField("field1", new BytesRef(String.valueOf(i))));
iw.addDocument(doc);
if (i % 24 == 0) {
iw.commit();
}
}
iw.close();
DirectoryReader ir = ElasticsearchDirectoryReader.wrap(DirectoryReader.open(dir), new ShardId("_index", "_na_", 0));

boolean[] called = new boolean[1];
SortedSetOrdinalsIndexFieldData sortedSetOrdinalsIndexFieldData = new SortedSetOrdinalsIndexFieldData(
new DummyAccountingFieldDataCache(),
"field1",
CoreValuesSourceType.KEYWORD,
new NoneCircuitBreakerService() {
@Override
public CircuitBreaker getBreaker(String name) {
assertThat(name, equalTo(CircuitBreaker.FIELDDATA));
return new NoopCircuitBreaker("test") {
@Override
public void addEstimateBytesAndMaybeBreak(long bytes, String label) throws CircuitBreakingException {
assertThat(label, equalTo("Global Ordinals"));
assertThat(bytes, equalTo(0L));
called[0] = true;
}
};
}
},
MOCK_TO_SCRIPT_FIELD
);
sortedSetOrdinalsIndexFieldData.loadGlobal(ir);
assertThat(called[0], equalTo(true));

ir.close();
dir.close();
}

private SortedSetOrdinalsIndexFieldData createSortedDV(String fieldName, IndexFieldDataCache indexFieldDataCache) {
return new SortedSetOrdinalsIndexFieldData(
indexFieldDataCache,
Expand Down

0 comments on commit adb8f5d

Please sign in to comment.