LUCENE-8018: FieldInfos retains garbage if non-sparse.

This commit is contained in:
Adrien Grand 2017-10-27 08:36:27 +02:00
parent 0d29f7a1a2
commit 401dda7e06
2 changed files with 10 additions and 2 deletions

View File

@ -31,6 +31,11 @@ Bug Fixes
refreshes or commits, and high indexing thread counts, do not
overflow an int (Mykhailo Demianenko via Mike McCandless)
Optimizations
* LUCENE-8018: Smaller FieldInfos memory footprint by not retaining unnecessary
references to TreeMap entries. (Julian Vassev via Adrien Grand)
======================= Lucene 7.1.0 =======================
Changes in Runtime Behavior

View File

@ -17,6 +17,7 @@
package org.apache.lucene.index;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@ -95,14 +96,15 @@ public class FieldInfos implements Iterable<FieldInfo> {
this.hasNorms = hasNorms;
this.hasDocValues = hasDocValues;
this.hasPointValues = hasPointValues;
this.values = Collections.unmodifiableCollection(byNumber.values());
Integer max = byNumber.isEmpty() ? null : Collections.max(byNumber.keySet());
Integer max = byNumber.isEmpty() ? null : byNumber.lastKey();
// Only usee TreeMap in the very sparse case (< 1/16th of the numbers are used),
// because TreeMap uses ~ 64 (32 bit JVM) or 120 (64 bit JVM w/o compressed oops)
// overall bytes per entry, but array uses 4 (32 bit JMV) or 8
// (64 bit JVM w/o compressed oops):
if (max != null && max < ArrayUtil.MAX_ARRAY_LENGTH && max < 16L*byNumber.size()) {
// Pull infos into an arraylist to avoid holding a reference to the TreeMap
values = Collections.unmodifiableCollection(new ArrayList<>(byNumber.values()));
byNumberMap = null;
byNumberTable = new FieldInfo[max+1];
for (Map.Entry<Integer,FieldInfo> entry : byNumber.entrySet()) {
@ -110,6 +112,7 @@ public class FieldInfos implements Iterable<FieldInfo> {
}
} else {
byNumberMap = byNumber;
values = Collections.unmodifiableCollection(byNumber.values());
byNumberTable = null;
}
}