SOLR-8394: /admin/luke didn't computeindexHeapUsageBytes (#1497)

Needed to call FilterLeafReader.unwrap.

Co-authored-by: igiguere <igiguere@opentext.com>
This commit is contained in:
David Smiley 2020-05-15 14:02:49 -04:00 committed by GitHub
parent 34e5e6c127
commit 803aad9175
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 17 deletions

View File

@ -177,6 +177,9 @@ Bug Fixes
* SOLR-14471: Fix bug in shards.preference behavior, base replica selection strategy not applied to the last group of * SOLR-14471: Fix bug in shards.preference behavior, base replica selection strategy not applied to the last group of
equivalent replicas. (Michael Gibney via Tomás Fernández Löbbe) equivalent replicas. (Michael Gibney via Tomás Fernández Löbbe)
* SOLR-8394: /admin/luke was always showing 0 for indexHeapUsageBytes. It should work now.
(Steve Molloy, Isabelle Giguere, David Smiley)
Other Changes Other Changes
--------------------- ---------------------
* SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid * SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid

View File

@ -17,8 +17,8 @@
package org.apache.solr.handler.admin; package org.apache.solr.handler.admin;
import java.io.IOException; import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.nio.file.NoSuchFileException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -39,6 +39,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.FilterLeafReader;
import org.apache.lucene.index.IndexCommit; import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
@ -47,7 +48,6 @@ import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiTerms; import org.apache.lucene.index.MultiTerms;
import org.apache.lucene.index.PostingsEnum; import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.SegmentReader;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.TermsEnum;
@ -55,6 +55,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Bits; import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.CharsRefBuilder; import org.apache.lucene.util.CharsRefBuilder;
@ -634,17 +635,19 @@ public class LukeRequestHandler extends RequestHandlerBase
/** Returns the sum of RAM bytes used by each segment */ /** Returns the sum of RAM bytes used by each segment */
private static long getIndexHeapUsed(DirectoryReader reader) { private static long getIndexHeapUsed(DirectoryReader reader) {
long indexHeapRamBytesUsed = 0; return reader.leaves().stream()
for(LeafReaderContext leafReaderContext : reader.leaves()) { .map(LeafReaderContext::reader)
LeafReader leafReader = leafReaderContext.reader(); .map(FilterLeafReader::unwrap)
if (leafReader instanceof SegmentReader) { .map(leafReader -> {
indexHeapRamBytesUsed += ((SegmentReader) leafReader).ramBytesUsed(); if (leafReader instanceof Accountable) {
return ((Accountable) leafReader).ramBytesUsed();
} else { } else {
// Not supported for any reader that is not a SegmentReader return -1L; // unsupported
return -1;
} }
} })
return indexHeapRamBytesUsed; .mapToLong(Long::longValue)
.reduce(0, (left, right) -> left == -1 || right == -1 ? -1 : left + right);
// if any leaves are unsupported (-1), we ultimately return -1.
} }
// Get terribly detailed information about a particular field. This is a very expensive call, use it with caution // Get terribly detailed information about a particular field. This is a very expensive call, use it with caution

View File

@ -238,10 +238,7 @@ public class SegmentsInfoRequestHandler extends RequestHandlerBase {
SegmentReader seg = null; SegmentReader seg = null;
for (LeafReaderContext lrc : leafContexts) { for (LeafReaderContext lrc : leafContexts) {
LeafReader leafReader = lrc.reader(); LeafReader leafReader = lrc.reader();
// unwrap leafReader = FilterLeafReader.unwrap(leafReader);
while (leafReader instanceof FilterLeafReader) {
leafReader = ((FilterLeafReader)leafReader).getDelegate();
}
if (leafReader instanceof SegmentReader) { if (leafReader instanceof SegmentReader) {
SegmentReader sr = (SegmentReader)leafReader; SegmentReader sr = (SegmentReader)leafReader;
if (sr.getSegmentInfo().info.equals(segmentCommitInfo.info)) { if (sr.getSegmentInfo().info.equals(segmentCommitInfo.info)) {

View File

@ -19,12 +19,15 @@ package org.apache.solr.handler.admin;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import javax.xml.xpath.XPathConstants;
import org.apache.solr.common.luke.FieldFlag; import org.apache.solr.common.luke.FieldFlag;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.CustomAnalyzerStrField; // jdoc import org.apache.solr.schema.CustomAnalyzerStrField; // jdoc
import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchema;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.util.TestHarness; import org.apache.solr.util.TestHarness;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -142,6 +145,18 @@ public class LukeRequestHandlerTest extends SolrTestCaseJ4 {
private static String dynfield(String field) { private static String dynfield(String field) {
return "//lst[@name='dynamicFields']/lst[@name='"+field+"']/"; return "//lst[@name='dynamicFields']/lst[@name='"+field+"']/";
} }
@Test
public void testIndexHeapUsageBytes() throws Exception {
try (SolrQueryRequest req = req("qt", "/admin/luke")) {
String response = h.query(req);
String xpath = "//long[@name='indexHeapUsageBytes']";
Double num = (Double) TestHarness.evaluateXPath(response, xpath, XPathConstants.NUMBER);
//with docs in the index, indexHeapUsageBytes should be greater than 0
Assert.assertTrue("indexHeapUsageBytes should be > 0, but was " + num.intValue(), num.intValue() > 0);
}
}
@Test @Test
public void testFlParam() { public void testFlParam() {
SolrQueryRequest req = req("qt", "/admin/luke", "fl", "solr_t solr_s", "show", "all"); SolrQueryRequest req = req("qt", "/admin/luke", "fl", "solr_t solr_s", "show", "all");