Created
June 20, 2018 19:41
-
-
Save aesgithub/cc5b54fc3cf5a3a13f1f5ad3139dfd00 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java | |
index 07ee5b5dc62..a162b668980 100644 | |
--- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java | |
+++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java | |
@@ -418,7 +418,7 @@ public class ScaledFloatFieldMapper extends FieldMapper { | |
boolean indexed = fieldType().indexOptions() != IndexOptions.NONE; | |
boolean docValued = fieldType().hasDocValues(); | |
boolean stored = fieldType().stored(); | |
- fields.addAll(NumberFieldMapper.NumberType.LONG.createFields(fieldType().name(), scaledValue, indexed, docValued, stored)); | |
+ NumberFieldMapper.NumberType.LONG.createFields(fieldType().name(), scaledValue, indexed, docValued, stored, fields, context); | |
if (docValued == false && (indexed || stored)) { | |
createFieldNamesField(context, fields); | |
} | |
diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java | |
index 7a777963baa..91bd3c2eeb7 100644 | |
--- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java | |
+++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java | |
@@ -148,7 +148,7 @@ public class TokenCountFieldMapper extends FieldMapper { | |
boolean indexed = fieldType().indexOptions() != IndexOptions.NONE; | |
boolean docValued = fieldType().hasDocValues(); | |
boolean stored = fieldType().stored(); | |
- fields.addAll(NumberFieldMapper.NumberType.INTEGER.createFields(fieldType().name(), tokenCount, indexed, docValued, stored)); | |
+ NumberFieldMapper.NumberType.INTEGER.createFields(fieldType().name(), tokenCount, indexed, docValued, stored, fields, context); | |
} | |
/** | |
diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java | |
index c1063795193..c176a2d36c2 100644 | |
--- a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java | |
+++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java | |
@@ -69,10 +69,13 @@ import org.elasticsearch.index.analysis.FieldNameAnalyzer; | |
import org.elasticsearch.index.fielddata.IndexFieldData; | |
import org.elasticsearch.index.fielddata.IndexFieldDataCache; | |
import org.elasticsearch.index.mapper.DocumentMapper; | |
+import org.elasticsearch.index.mapper.DocumentMapperForType; | |
import org.elasticsearch.index.mapper.MappedFieldType; | |
import org.elasticsearch.index.mapper.MapperService; | |
import org.elasticsearch.index.mapper.ParseContext; | |
import org.elasticsearch.index.mapper.ParsedDocument; | |
+import org.elasticsearch.index.mapper.FieldObjectCache; | |
+import org.elasticsearch.index.mapper.SourceToParse; | |
import org.elasticsearch.index.query.AbstractQueryBuilder; | |
import org.elasticsearch.index.query.QueryBuilder; | |
import org.elasticsearch.index.query.QueryRewriteContext; | |
@@ -581,6 +584,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu | |
final List<ParsedDocument> docs = new ArrayList<>(); | |
final DocumentMapper docMapper; | |
final MapperService mapperService = context.getMapperService(); | |
+ final FieldObjectCache foc = FieldObjectCache.GetObjectCache(java.lang.Thread.currentThread().getId()); | |
String type = mapperService.documentMapper().type(); | |
if (documentType != null) { | |
DEPRECATION_LOGGER.deprecated("[document_type] parameter has been deprecated because types have been deprecated"); | |
@@ -590,8 +594,12 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu | |
} | |
} | |
docMapper = mapperService.documentMapper(type); | |
+ DocumentMapperForType docMapperForType = mapperService.documentMapperWithAutoCreate(documentType); | |
for (BytesReference document : documents) { | |
- docs.add(docMapper.parse(source(context.index().getName(), type, "_temp_id", document, documentXContentType))); | |
+ SourceToParse src = | |
+ source(context.index().getName(), type, "_temp_id", document, documentXContentType); | |
+ ParseContext.InternalParseContext parseContext = foc.GetParseContext(docMapperForType, src); | |
+ docs.add(docMapper.parse(src, parseContext)); | |
} | |
FieldNameAnalyzer fieldNameAnalyzer = (FieldNameAnalyzer) docMapper.mappers().indexAnalyzer(); | |
diff --git a/plugins/mapper-size/src/main/java/org/elasticsearch/index/mapper/size/SizeFieldMapper.java b/plugins/mapper-size/src/main/java/org/elasticsearch/index/mapper/size/SizeFieldMapper.java | |
index 5b3895578e0..74e6d1ad7fc 100644 | |
--- a/plugins/mapper-size/src/main/java/org/elasticsearch/index/mapper/size/SizeFieldMapper.java | |
+++ b/plugins/mapper-size/src/main/java/org/elasticsearch/index/mapper/size/SizeFieldMapper.java | |
@@ -164,7 +164,7 @@ public class SizeFieldMapper extends MetadataFieldMapper { | |
boolean indexed = fieldType().indexOptions() != IndexOptions.NONE; | |
boolean docValued = fieldType().hasDocValues(); | |
boolean stored = fieldType().stored(); | |
- fields.addAll(NumberFieldMapper.NumberType.INTEGER.createFields(name(), value, indexed, docValued, stored)); | |
+ NumberFieldMapper.NumberType.INTEGER.createFields(name(), value, indexed, docValued, stored, fields, context); | |
} | |
@Override | |
diff --git a/server/src/main/java/org/elasticsearch/common/bytes/BytesReference.java b/server/src/main/java/org/elasticsearch/common/bytes/BytesReference.java | |
index 7147045c414..dced17abd23 100644 | |
--- a/server/src/main/java/org/elasticsearch/common/bytes/BytesReference.java | |
+++ b/server/src/main/java/org/elasticsearch/common/bytes/BytesReference.java | |
@@ -266,12 +266,16 @@ public abstract class BytesReference implements Accountable, Comparable<BytesRef | |
* this wrapper builds it on top of the BytesReferenceStreamInput which is much simpler | |
* that way. | |
*/ | |
- private static final class MarkSupportingStreamInputWrapper extends StreamInput { | |
+ public static final class MarkSupportingStreamInputWrapper extends StreamInput { | |
// can't use FilterStreamInput it needs to reset the delegate | |
private final BytesReference reference; | |
private BytesReferenceStreamInput input; | |
private int mark = 0; | |
+ public String getString() { | |
+ return reference.utf8ToString(); | |
+ } | |
+ | |
private MarkSupportingStreamInputWrapper(BytesReference reference) throws IOException { | |
this.reference = reference; | |
this.input = new BytesReferenceStreamInput(reference.iterator(), reference.length()); | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/ContentPath.java b/server/src/main/java/org/elasticsearch/index/mapper/ContentPath.java | |
index 3c67d3ee7f3..54a8ef17e3d 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/ContentPath.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/ContentPath.java | |
@@ -25,7 +25,7 @@ public final class ContentPath { | |
private final StringBuilder sb; | |
- private final int offset; | |
+ private int offset; | |
private int index = 0; | |
@@ -66,4 +66,10 @@ public final class ContentPath { | |
sb.append(name); | |
return sb.toString(); | |
} | |
+ | |
+ public void reset(int offset) { | |
+ this.sb.setLength(0); | |
+ this.offset = offset; | |
+ this.index = 0; | |
+ } | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java | |
index c8360e468d7..d1d91c0dae5 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java | |
@@ -453,16 +453,24 @@ public class DateFieldMapper extends FieldMapper { | |
} | |
} | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (fieldType().indexOptions() != IndexOptions.NONE) { | |
- fields.add(new LongPoint(fieldType().name(), timestamp)); | |
+ LongPoint lpobj = foc.pLongPointObjectCache.get(fieldType().name(), timestamp); | |
+ lpobj.setLongValue(timestamp); | |
+ fields.add(lpobj); | |
} | |
if (fieldType().hasDocValues()) { | |
- fields.add(new SortedNumericDocValuesField(fieldType().name(), timestamp)); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache | |
+ .get(fieldType().name(), timestamp); | |
+ snobj.setLongValue(timestamp); | |
+ fields.add(snobj); | |
} else if (fieldType().stored() || fieldType().indexOptions() != IndexOptions.NONE) { | |
createFieldNamesField(context, fields); | |
} | |
if (fieldType().stored()) { | |
- fields.add(new StoredField(fieldType().name(), timestamp)); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(fieldType().name(), timestamp); | |
+ sfobj.setLongValue(timestamp); | |
+ fields.add(sfobj); | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java | |
index b0d9b1e5e34..31d32cef49b 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java | |
@@ -240,8 +240,12 @@ public class DocumentMapper implements ToXContentFragment { | |
return this.objectMappers; | |
} | |
- public ParsedDocument parse(SourceToParse source) throws MapperParsingException { | |
- return documentParser.parseDocument(source); | |
+ public DocumentParser getDocumentParser() { | |
+ return documentParser; | |
+ } | |
+ | |
+ public ParsedDocument parse(SourceToParse source, ParseContext.InternalParseContext parseContext) throws MapperParsingException { | |
+ return documentParser.parseDocument(source, parseContext); | |
} | |
/** | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java | |
index 61ff4a4ff3d..52ca0c6115c 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java | |
@@ -43,7 +43,7 @@ import java.util.List; | |
import java.util.Objects; | |
/** A parser for documents, given mappings from a DocumentMapper */ | |
-final class DocumentParser { | |
+final public class DocumentParser { | |
private final IndexSettings indexSettings; | |
private final DocumentMapperParser docMapperParser; | |
@@ -55,23 +55,31 @@ final class DocumentParser { | |
this.docMapper = docMapper; | |
} | |
- ParsedDocument parseDocument(SourceToParse source) throws MapperParsingException { | |
+ public ParseContext.InternalParseContext getParseContext(SourceToParse source, FieldObjectCache foc) { | |
+ return new ParseContext.InternalParseContext(indexSettings.getSettings(), docMapperParser, docMapper, source, null, foc); | |
+ } | |
+ private void resetParseContext(ParseContext.InternalParseContext parseContext, SourceToParse source) { | |
+ parseContext.reset(indexSettings.getSettings(), docMapperParser, docMapper, source, null); | |
+ } | |
+ | |
+ ParsedDocument parseDocument(SourceToParse source, ParseContext.InternalParseContext context) throws MapperParsingException { | |
validateType(source); | |
final Mapping mapping = docMapper.mapping(); | |
- final ParseContext.InternalParseContext context; | |
final XContentType xContentType = source.getXContentType(); | |
try (XContentParser parser = XContentHelper.createParser(docMapperParser.getXContentRegistry(), | |
LoggingDeprecationHandler.INSTANCE, source.source(), xContentType)) { | |
- context = new ParseContext.InternalParseContext(indexSettings.getSettings(), docMapperParser, docMapper, source, parser); | |
+ resetParseContext(context, source); | |
+ context.setParser(parser); | |
+ | |
validateStart(parser); | |
internalParseDocument(mapping, context, parser); | |
validateEnd(parser); | |
} catch (Exception e) { | |
throw wrapInMapperParsingException(source, e); | |
} | |
- String remainingPath = context.path().pathAsText(""); | |
+ final String remainingPath = context.path().pathAsText(""); | |
if (remainingPath.isEmpty() == false) { | |
throw new IllegalStateException("found leftover path elements: " + remainingPath); | |
} | |
@@ -123,7 +131,7 @@ final class DocumentParser { | |
// try to parse the next token, this should be null if the object is ended properly | |
// but will throw a JSON exception if the extra tokens is not valid JSON (this will be handled by the catch) | |
token = parser.nextToken(); | |
- if (token != null) { | |
+ if (token != null && token != XContentParser.Token.END_OBJECT) { | |
throw new IllegalArgumentException("Malformed content, found extra data after parsing: " + token); | |
} | |
} | |
@@ -386,7 +394,8 @@ final class DocumentParser { | |
parseArray(context, mapper, currentFieldName); | |
} else if (token == XContentParser.Token.FIELD_NAME) { | |
currentFieldName = parser.currentName(); | |
- if (MapperService.isMetadataField(context.path().pathAsText(currentFieldName))) { | |
+ final String str = context.path().pathAsText(currentFieldName); | |
+ if (MapperService.isMetadataField(str)) { | |
throw new MapperParsingException("Field [" + currentFieldName + "] is a metadata field and cannot be added inside a document. Use the index API request parameters."); | |
} | |
} else if (token == XContentParser.Token.VALUE_NULL) { | |
@@ -851,7 +860,7 @@ final class DocumentParser { | |
int pathsAdded = 0; | |
ObjectMapper parent = mapper; | |
for (int i = 0; i < paths.length-1; i++) { | |
- String currentPath = context.path().pathAsText(paths[i]); | |
+ final String currentPath = context.path().pathAsText(paths[i]); | |
FieldMapper existingFieldMapper = context.docMapper().mappers().getMapper(currentPath); | |
if (existingFieldMapper != null) { | |
throw new MapperParsingException( | |
@@ -932,4 +941,8 @@ final class DocumentParser { | |
} | |
return objectMapper.getMapper(subfields[subfields.length - 1]); | |
} | |
+ | |
+ public final IndexSettings getIndexSettings() { | |
+ return indexSettings; | |
+ } | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java | |
index f23a8d0ce96..9455a7f4e51 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java | |
@@ -291,8 +291,11 @@ public abstract class FieldMapper extends Mapper implements Cloneable { | |
FieldNamesFieldType fieldNamesFieldType = (FieldNamesFieldMapper.FieldNamesFieldType) context.docMapper() | |
.metadataMapper(FieldNamesFieldMapper.class).fieldType(); | |
if (fieldNamesFieldType != null && fieldNamesFieldType.isEnabled()) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
for (String fieldName : FieldNamesFieldMapper.extractFieldNames(fieldType().name())) { | |
- fields.add(new Field(FieldNamesFieldMapper.NAME, fieldName, fieldNamesFieldType)); | |
+ Field fobj = foc.pGenericFieldObjectCache.get(FieldNamesFieldMapper.NAME, fieldName, fieldNamesFieldType); | |
+ fobj.setStringValue(fieldName); | |
+ fields.add(fobj); | |
} | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java | |
index 606777392de..5d67989c468 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java | |
@@ -278,10 +278,13 @@ public class FieldNamesFieldMapper extends MetadataFieldMapper { | |
paths.add(path); | |
previousPath = path; | |
} | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
for (String path : paths) { | |
for (String fieldName : extractFieldNames(path)) { | |
if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { | |
- document.add(new Field(fieldType().name(), fieldName, fieldType())); | |
+ Field f = foc.pGenericFieldObjectCache.get(fieldType().name(), fieldName, fieldType()); | |
+ f.setStringValue(fieldName); | |
+ document.add(f); | |
} | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldObjectCache.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldObjectCache.java | |
new file mode 100644 | |
index 00000000000..53d2eeab858 | |
--- /dev/null | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldObjectCache.java | |
@@ -0,0 +1,362 @@ | |
+package org.elasticsearch.index.mapper; | |
+ | |
+import org.apache.lucene.document.*; | |
+import org.apache.lucene.util.BytesRef; | |
+ | |
+import java.util.Arrays; | |
+import java.util.concurrent.ConcurrentHashMap; | |
+import java.util.HashMap; | |
+import java.util.Map; | |
+ | |
+public final class FieldObjectCache { | |
+ | |
+ static private Map<Long, FieldObjectCache> tidMap = new ConcurrentHashMap<Long, FieldObjectCache>(); | |
+ | |
+ public static FieldObjectCache GetObjectCache(long tid) { | |
+ if (tidMap.containsKey(tid)) { | |
+ return tidMap.get(tid); | |
+ } else { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ FieldObjectCache f = new FieldObjectCache(); | |
+ tidMap.put(tid, f); | |
+ return f; | |
+ } | |
+ } | |
+ | |
+ public LatLonPointObjectCache pLatLonPointObjectCache; | |
+ public LatLonDocValuesFieldObjectCache pLatLonDocValuesFieldObjectCache; | |
+ public StoredFieldObjectCache pStoredFieldObjectCache; | |
+ public LongPointObjectCache pLongPointObjectCache; | |
+ public SortedNumericDocValuesFieldObjectCache pSortedNumericDocValuesFieldObjectCache; | |
+ public SortedSetDocValuesFieldObjectCache pSortedSetDocValuesFieldObjectCache; | |
+ public SortedDocValuesFieldObjectCache pSortedDocValuesFieldObjectCache; | |
+ public GenericFieldObjectCache pGenericFieldObjectCache; | |
+ public HalfFloatPointObjectCache pHalfFloatPointObjectCache; | |
+ public FloatPointObjectCache pFloatPointObjectCache; | |
+ public DoublePointObjectCache pDoublePointObjectCache; | |
+ public IntPointObjectCache pIntPointObjectCache; | |
+ | |
+ FieldObjectCache() { | |
+ pLatLonPointObjectCache = new LatLonPointObjectCache(); | |
+ pLatLonDocValuesFieldObjectCache = new LatLonDocValuesFieldObjectCache(); | |
+ pStoredFieldObjectCache = new StoredFieldObjectCache(); | |
+ pLongPointObjectCache = new LongPointObjectCache(); | |
+ pSortedNumericDocValuesFieldObjectCache = new SortedNumericDocValuesFieldObjectCache(); | |
+ pSortedSetDocValuesFieldObjectCache = new SortedSetDocValuesFieldObjectCache(); | |
+ pSortedDocValuesFieldObjectCache = new SortedDocValuesFieldObjectCache(); | |
+ pGenericFieldObjectCache = new GenericFieldObjectCache(); | |
+ pHalfFloatPointObjectCache = new HalfFloatPointObjectCache(); | |
+ pFloatPointObjectCache = new FloatPointObjectCache(); | |
+ pDoublePointObjectCache = new DoublePointObjectCache(); | |
+ pIntPointObjectCache = new IntPointObjectCache(); | |
+ } | |
+ | |
+ //TODO: evict caches when full | |
+ final class LatLonPointObjectCache { | |
+ final private Map<String, LatLonPoint> fieldCache = new HashMap<String, LatLonPoint>(); | |
+ LatLonPointObjectCache() { | |
+ } | |
+ LatLonPoint createAndAdd(String fieldName, double lat, double lon) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ LatLonPoint obj = new LatLonPoint(fieldName, lat, lon); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ LatLonPoint get(String fieldName, double lat, double lon) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ LatLonPoint obj = createAndAdd(fieldName, lat, lon); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class LatLonDocValuesFieldObjectCache { | |
+ final private Map<String, LatLonDocValuesField> fieldCache = new HashMap<String, LatLonDocValuesField>(); | |
+ LatLonDocValuesFieldObjectCache() { | |
+ } | |
+ LatLonDocValuesField createAndAdd(String fieldName, double lat, double lon) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ LatLonDocValuesField obj = new LatLonDocValuesField(fieldName, lat, lon); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ LatLonDocValuesField get(String fieldName, double lat, double lon) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ LatLonDocValuesField obj = createAndAdd(fieldName, lat, lon); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class StoredFieldObjectCache { | |
+ final private Map<String, StoredField> fieldCache = new HashMap<String, StoredField>(); | |
+ StoredFieldObjectCache() { | |
+ } | |
+ StoredField createAndAdd(String fieldName, String value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, String value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ StoredField createAndAdd(String fieldName, long value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, long value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ StoredField createAndAdd(String fieldName, double value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, double value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ StoredField createAndAdd(String fieldName, float value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, float value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ StoredField createAndAdd(String fieldName, int value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, int value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ StoredField createAndAdd(String fieldName, byte[] value, int offset, int length) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ StoredField obj = new StoredField(fieldName, value, offset, length); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ StoredField get(String fieldName, byte[] value, int offset, int length) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ StoredField obj = createAndAdd(fieldName, value, offset, length); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class LongPointObjectCache { | |
+ final private Map<String, LongPoint> fieldCache = new HashMap<String, LongPoint>(); | |
+ LongPointObjectCache() { | |
+ } | |
+ LongPoint createAndAdd(String fieldName, long value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ LongPoint obj = new LongPoint(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ LongPoint get(String fieldName, long value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ LongPoint obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class SortedNumericDocValuesFieldObjectCache { | |
+ final private Map<String, SortedNumericDocValuesField> fieldCache = new HashMap<String, SortedNumericDocValuesField>(); | |
+ SortedNumericDocValuesFieldObjectCache() { | |
+ } | |
+ SortedNumericDocValuesField createAndAdd(String fieldName, long value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ SortedNumericDocValuesField obj = new SortedNumericDocValuesField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ SortedNumericDocValuesField get(String fieldName, long value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ SortedNumericDocValuesField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class SortedSetDocValuesFieldObjectCache { | |
+ final private Map<String, SortedSetDocValuesField> fieldCache = new HashMap<String, SortedSetDocValuesField>(); | |
+ SortedSetDocValuesFieldObjectCache() { | |
+ } | |
+ SortedSetDocValuesField createAndAdd(String fieldName, BytesRef value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ SortedSetDocValuesField obj = new SortedSetDocValuesField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ SortedSetDocValuesField get(String fieldName, BytesRef value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ SortedSetDocValuesField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class SortedDocValuesFieldObjectCache { | |
+ final private Map<String, SortedDocValuesField> fieldCache = new HashMap<String, SortedDocValuesField>(); | |
+ SortedDocValuesFieldObjectCache() { | |
+ } | |
+ SortedDocValuesField createAndAdd(String fieldName, BytesRef value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ SortedDocValuesField obj = new SortedDocValuesField(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ SortedDocValuesField get(String fieldName, BytesRef value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ SortedDocValuesField obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class GenericFieldObjectCache { | |
+ final private Map<String, Field> fieldCache = new HashMap<String, Field>(); | |
+ GenericFieldObjectCache() { | |
+ } | |
+ Field createAndAdd(String fieldName, String value, FieldType type) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ Field obj = new Field(fieldName, value, type); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ Field get(String fieldName, String value, FieldType type) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ Field obj = createAndAdd(fieldName, value, type); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class HalfFloatPointObjectCache { | |
+ final private Map<String, HalfFloatPoint> fieldCache = new HashMap<String, HalfFloatPoint>(); | |
+ HalfFloatPointObjectCache() { | |
+ } | |
+ HalfFloatPoint createAndAdd(String fieldName, float value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ HalfFloatPoint obj = new HalfFloatPoint(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ HalfFloatPoint get(String fieldName, float value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ HalfFloatPoint obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class FloatPointObjectCache { | |
+ final private Map<String, FloatPoint> fieldCache = new HashMap<String, FloatPoint>(); | |
+ FloatPointObjectCache() { | |
+ } | |
+ FloatPoint createAndAdd(String fieldName, float value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ FloatPoint obj = new FloatPoint(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ FloatPoint get(String fieldName, float value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ FloatPoint obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class DoublePointObjectCache { | |
+ final private Map<String, DoublePoint> fieldCache = new HashMap<String, DoublePoint>(); | |
+ DoublePointObjectCache() { | |
+ } | |
+ DoublePoint createAndAdd(String fieldName, double value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ DoublePoint obj = new DoublePoint(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ DoublePoint get(String fieldName, double value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ DoublePoint obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ final class IntPointObjectCache { | |
+ final private Map<String, IntPoint> fieldCache = new HashMap<String, IntPoint>(); | |
+ IntPointObjectCache() { | |
+ } | |
+ IntPoint createAndAdd(String fieldName, int value) { | |
+ System.out.println("cache-miss: "+Thread.currentThread().getStackTrace()[2].getClassName()); | |
+ IntPoint obj = new IntPoint(fieldName, value); | |
+ fieldCache.put(fieldName, obj); | |
+ return obj; | |
+ } | |
+ IntPoint get(String fieldName, int value) { | |
+ if (fieldCache.containsKey(fieldName)) { | |
+ return fieldCache.get(fieldName); | |
+ } else { | |
+ IntPoint obj = createAndAdd(fieldName, value); | |
+ return obj; | |
+ } | |
+ } | |
+ } | |
+ | |
+ private ParseContext.InternalParseContext parseContext = null; | |
+ public ParseContext.InternalParseContext GetParseContext(DocumentMapperForType docMapper, SourceToParse source) { | |
+ if (parseContext == null) { | |
+ parseContext = docMapper.getDocumentMapper().getDocumentParser().getParseContext(source, this); | |
+ } | |
+ return parseContext; | |
+ } | |
+} | |
+ | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java | |
index 551f7c18c1c..d63dc326b28 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java | |
@@ -262,14 +262,21 @@ public class GeoPointFieldMapper extends FieldMapper implements ArrayValueMapper | |
} else { | |
GeoUtils.normalizePoint(point); | |
} | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (fieldType().indexOptions() != IndexOptions.NONE) { | |
- context.doc().add(new LatLonPoint(fieldType().name(), point.lat(), point.lon())); | |
+ LatLonPoint llpt = foc.pLatLonPointObjectCache.get(fieldType().name(), point.lat(), point.lon()); | |
+ llpt.setLocationValue(point.lat(), point.lon()); | |
+ context.doc().add(llpt); | |
} | |
if (fieldType().stored()) { | |
- context.doc().add(new StoredField(fieldType().name(), point.toString())); | |
+ StoredField sfpt = foc.pStoredFieldObjectCache.get(fieldType().name(), point.toString()); | |
+ sfpt.setStringValue(point.toString()); | |
+ context.doc().add(sfpt); | |
} | |
if (fieldType.hasDocValues()) { | |
- context.doc().add(new LatLonDocValuesField(fieldType().name(), point.lat(), point.lon())); | |
+ LatLonDocValuesField lldvpt = foc.pLatLonDocValuesFieldObjectCache.get(fieldType().name(), point.lat(), point.lon()); | |
+ lldvpt.setLocationValue(point.lat(), point.lon()); | |
+ context.doc().add(lldvpt); | |
} else if (fieldType().stored() || fieldType().indexOptions() != IndexOptions.NONE) { | |
List<IndexableField> fields = new ArrayList<>(1); | |
createFieldNamesField(context, fields); | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java | |
index 32cb99e3f91..2efc26b448a 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java | |
@@ -271,7 +271,10 @@ public class IdFieldMapper extends MetadataFieldMapper { | |
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException { | |
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) { | |
BytesRef id = Uid.encodeId(context.sourceToParse().id()); | |
- fields.add(new Field(NAME, id, fieldType)); | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
+ Field idField = foc.pGenericFieldObjectCache.get(NAME, context.sourceToParse().id(), fieldType); | |
+ idField.setStringValue(context.sourceToParse().id()); | |
+ fields.add(idField); | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java | |
index de2aee326c7..50043551ea4 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java | |
@@ -364,11 +364,13 @@ public final class KeywordFieldMapper extends FieldMapper { | |
} | |
} | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
// convert to utf8 only once before feeding postings/dv/stored fields | |
final BytesRef binaryValue = new BytesRef(value); | |
if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { | |
- Field field = new Field(fieldType().name(), binaryValue, fieldType()); | |
- fields.add(field); | |
+ Field fobj = foc.pGenericFieldObjectCache.get(fieldType().name(), value, fieldType()); | |
+ fobj.setStringValue(value); | |
+ fields.add(fobj); | |
} | |
if (fieldType().hasDocValues()) { | |
fields.add(new SortedSetDocValuesField(fieldType().name(), binaryValue)); | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java | |
index 9c327c5294e..ffdb5eab6a9 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java | |
@@ -240,19 +240,26 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- List<Field> fields = new ArrayList<>(); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (indexed) { | |
- fields.add(new HalfFloatPoint(name, value.floatValue())); | |
+ HalfFloatPoint hfobj = foc.pHalfFloatPointObjectCache.get(name, value.floatValue()); | |
+ hfobj.setFloatValue(value.floatValue()); | |
+ fields.add(hfobj); | |
} | |
if (docValued) { | |
- fields.add(new SortedNumericDocValuesField(name, | |
- HalfFloatPoint.halfFloatToSortableShort(value.floatValue()))); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache.get(name, 0); | |
+ snobj.setLongValue(HalfFloatPoint.halfFloatToSortableShort(value.floatValue())); | |
+ fields.add(snobj); | |
} | |
if (stored) { | |
- fields.add(new StoredField(name, value.floatValue())); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(name, (float)0); | |
+ sfobj.setFloatValue(value.floatValue()); | |
+ fields.add(sfobj); | |
} | |
- return fields; | |
+ return null; | |
+ //return fields; | |
} | |
private void validateParsed(float value) { | |
@@ -330,19 +337,26 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- List<Field> fields = new ArrayList<>(); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (indexed) { | |
- fields.add(new FloatPoint(name, value.floatValue())); | |
+ FloatPoint fpobj = foc.pFloatPointObjectCache.get(name, 0); | |
+ fpobj.setFloatValue(value.floatValue()); | |
+ fields.add(fpobj); | |
} | |
if (docValued) { | |
- fields.add(new SortedNumericDocValuesField(name, | |
- NumericUtils.floatToSortableInt(value.floatValue()))); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache.get(name, (int)0); | |
+ snobj.setLongValue(NumericUtils.floatToSortableInt(value.floatValue())); | |
+ fields.add(snobj); | |
} | |
if (stored) { | |
- fields.add(new StoredField(name, value.floatValue())); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(name, (float)0); | |
+ sfobj.setFloatValue(value.floatValue()); | |
+ fields.add(sfobj); | |
} | |
- return fields; | |
+ return null; | |
+ //return fields; | |
} | |
private void validateParsed(float value) { | |
@@ -411,19 +425,26 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- List<Field> fields = new ArrayList<>(); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (indexed) { | |
- fields.add(new DoublePoint(name, value.doubleValue())); | |
+ DoublePoint fpobj = foc.pDoublePointObjectCache.get(name, 0); | |
+ fpobj.setDoubleValue(value.doubleValue()); | |
+ fields.add(fpobj); | |
} | |
if (docValued) { | |
- fields.add(new SortedNumericDocValuesField(name, | |
- NumericUtils.doubleToSortableLong(value.doubleValue()))); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache.get(name, (long)0); | |
+ snobj.setLongValue(NumericUtils.doubleToSortableLong(value.doubleValue())); | |
+ fields.add(snobj); | |
} | |
if (stored) { | |
- fields.add(new StoredField(name, value.doubleValue())); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(name, (double)0); | |
+ sfobj.setDoubleValue(value.doubleValue()); | |
+ fields.add(sfobj); | |
} | |
- return fields; | |
+ return null; | |
+ //return fields; | |
} | |
private void validateParsed(double value) { | |
@@ -479,8 +500,9 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- return INTEGER.createFields(name, value, indexed, docValued, stored); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ return INTEGER.createFields(name, value, indexed, docValued, stored, fields, context); | |
} | |
@Override | |
@@ -531,8 +553,9 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- return INTEGER.createFields(name, value, indexed, docValued, stored); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ return INTEGER.createFields(name, value, indexed, docValued, stored, fields, context); | |
} | |
@Override | |
@@ -637,18 +660,26 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- List<Field> fields = new ArrayList<>(); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (indexed) { | |
- fields.add(new IntPoint(name, value.intValue())); | |
+ IntPoint ipobj = foc.pIntPointObjectCache.get(name, 0); | |
+ ipobj.setIntValue(value.intValue()); | |
+ fields.add(ipobj); | |
} | |
if (docValued) { | |
- fields.add(new SortedNumericDocValuesField(name, value.intValue())); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache.get(name, 0); | |
+ snobj.setLongValue(value.longValue()); | |
+ fields.add(snobj); | |
} | |
if (stored) { | |
- fields.add(new StoredField(name, value.intValue())); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(name, (int)0); | |
+ sfobj.setIntValue(value.intValue()); | |
+ fields.add(sfobj); | |
} | |
- return fields; | |
+ return null; | |
+ //return fields; | |
} | |
}, | |
LONG("long", NumericType.LONG) { | |
@@ -751,18 +782,26 @@ public class NumberFieldMapper extends FieldMapper { | |
@Override | |
public List<Field> createFields(String name, Number value, | |
- boolean indexed, boolean docValued, boolean stored) { | |
- List<Field> fields = new ArrayList<>(); | |
+ boolean indexed, boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context) { | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
if (indexed) { | |
- fields.add(new LongPoint(name, value.longValue())); | |
+ LongPoint ipobj = foc.pLongPointObjectCache.get(name, 0); | |
+ ipobj.setLongValue(value.longValue()); | |
+ fields.add(ipobj); | |
} | |
if (docValued) { | |
- fields.add(new SortedNumericDocValuesField(name, value.longValue())); | |
+ SortedNumericDocValuesField snobj = foc.pSortedNumericDocValuesFieldObjectCache.get(name, (long)0); | |
+ snobj.setLongValue(value.longValue()); | |
+ fields.add(snobj); | |
} | |
if (stored) { | |
- fields.add(new StoredField(name, value.longValue())); | |
+ StoredField sfobj = foc.pStoredFieldObjectCache.get(name, (long)0); | |
+ sfobj.setLongValue(value.longValue()); | |
+ fields.add(sfobj); | |
} | |
- return fields; | |
+ //return fields; | |
+ return null; | |
} | |
}; | |
@@ -790,7 +829,8 @@ public class NumberFieldMapper extends FieldMapper { | |
public abstract Number parse(XContentParser parser, boolean coerce) throws IOException; | |
public abstract Number parse(Object value, boolean coerce); | |
public abstract List<Field> createFields(String name, Number value, boolean indexed, | |
- boolean docValued, boolean stored); | |
+ boolean docValued, boolean stored, List<IndexableField> fields, | |
+ ParseContext context); | |
Number valueForSearch(Number value) { | |
return value; | |
} | |
@@ -1014,7 +1054,7 @@ public class NumberFieldMapper extends FieldMapper { | |
boolean indexed = fieldType().indexOptions() != IndexOptions.NONE; | |
boolean docValued = fieldType().hasDocValues(); | |
boolean stored = fieldType().stored(); | |
- fields.addAll(fieldType().type.createFields(fieldType().name(), numericValue, indexed, docValued, stored)); | |
+ fieldType().type.createFields(fieldType().name(), numericValue, indexed, docValued, stored, fields, context); | |
if (docValued == false && (stored || indexed)) { | |
createFieldNamesField(context, fields); | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/ParseContext.java b/server/src/main/java/org/elasticsearch/index/mapper/ParseContext.java | |
index b77ffee05ca..cd3215bce32 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/ParseContext.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/ParseContext.java | |
@@ -41,9 +41,9 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
/** Fork of {@link org.apache.lucene.document.Document} with additional functionality. */ | |
public static class Document implements Iterable<IndexableField> { | |
- private final Document parent; | |
- private final String path; | |
- private final String prefix; | |
+ private Document parent; | |
+ private String path; | |
+ private String prefix; | |
private final List<IndexableField> fields; | |
private ObjectObjectMap<Object, IndexableField> keyedFields; | |
@@ -58,6 +58,14 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
this("", null); | |
} | |
+ //same as calling Document() | |
+ public void reset() { | |
+ this.path = ""; | |
+ this.parent = null; | |
+ fields.clear(); | |
+ this.prefix = ""; | |
+ } | |
+ | |
/** | |
* Return the path associated with this document. | |
*/ | |
@@ -303,28 +311,28 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
public static class InternalParseContext extends ParseContext { | |
- private final DocumentMapper docMapper; | |
+ private DocumentMapper docMapper; | |
- private final DocumentMapperParser docMapperParser; | |
+ private DocumentMapperParser docMapperParser; | |
private final ContentPath path; | |
- private final XContentParser parser; | |
+ private XContentParser parser; | |
private Document document; | |
private final List<Document> documents; | |
@Nullable | |
- private final Settings indexSettings; | |
+ private Settings indexSettings; | |
- private final SourceToParse sourceToParse; | |
+ private SourceToParse sourceToParse; | |
private Field version; | |
private SeqNoFieldMapper.SequenceIDFields seqID; | |
- private final long maxAllowedNumNestedDocs; | |
+ private long maxAllowedNumNestedDocs; | |
private long numNestedDocs; | |
@@ -334,8 +342,10 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
private final Set<String> ignoredFields = new HashSet<>(); | |
+ private final FieldObjectCache localObjectCache; | |
+ | |
public InternalParseContext(@Nullable Settings indexSettings, DocumentMapperParser docMapperParser, DocumentMapper docMapper, | |
- SourceToParse source, XContentParser parser) { | |
+ SourceToParse source, XContentParser parser, FieldObjectCache foc) { | |
this.indexSettings = indexSettings; | |
this.docMapper = docMapper; | |
this.docMapperParser = docMapperParser; | |
@@ -349,6 +359,28 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
this.dynamicMappers = new ArrayList<>(); | |
this.maxAllowedNumNestedDocs = MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.get(indexSettings); | |
this.numNestedDocs = 0L; | |
+ this.localObjectCache = foc; | |
+ } | |
+ | |
+ public void reset(@Nullable Settings indexSettings, DocumentMapperParser docMapperParser, DocumentMapper docMapper, | |
+ SourceToParse source, XContentParser parser) { | |
+ this.indexSettings = indexSettings; | |
+ this.docMapper = docMapper; | |
+ this.docMapperParser = docMapperParser; | |
+ this.path.reset(0); | |
+ this.parser = parser; | |
+ this.document.reset(); | |
+ this.documents.clear(); | |
+ this.documents.add(document); | |
+ this.version = null; | |
+ this.sourceToParse = source; | |
+ this.dynamicMappers.clear(); | |
+ this.maxAllowedNumNestedDocs = MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.get(indexSettings); | |
+ this.numNestedDocs = 0L; | |
+ } | |
+ | |
+ public void setParser(XContentParser parser) { | |
+ this.parser = parser; | |
} | |
@Override | |
@@ -479,6 +511,10 @@ public abstract class ParseContext implements Iterable<ParseContext.Document>{ | |
public Collection<String> getIgnoredFields() { | |
return Collections.unmodifiableCollection(ignoredFields); | |
} | |
+ | |
+ public FieldObjectCache getObjectCache() { | |
+ return localObjectCache; | |
+ } | |
} | |
/** | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java | |
index 76753496f46..6e07a2e1ad0 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java | |
@@ -170,7 +170,10 @@ public class RoutingFieldMapper extends MetadataFieldMapper { | |
String routing = context.sourceToParse().routing(); | |
if (routing != null) { | |
if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { | |
- fields.add(new Field(fieldType().name(), routing, fieldType())); | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
+ Field f = foc.pGenericFieldObjectCache.get(fieldType().name(), routing, fieldType()); | |
+ f.setStringValue(routing); | |
+ fields.add(f); | |
createFieldNamesField(context, fields); | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java | |
index ac3ffe46272..7f4251a1159 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java | |
@@ -227,15 +227,16 @@ public class SeqNoFieldMapper extends MetadataFieldMapper { | |
super.parse(context); | |
} | |
+ private SequenceIDFields seqIDGlobal = SequenceIDFields.emptySeqID(); | |
+ | |
@Override | |
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException { | |
// see InternalEngine.innerIndex to see where the real version value is set | |
// also see ParsedDocument.updateSeqID (called by innerIndex) | |
- SequenceIDFields seqID = SequenceIDFields.emptySeqID(); | |
- context.seqID(seqID); | |
- fields.add(seqID.seqNo); | |
- fields.add(seqID.seqNoDocValue); | |
- fields.add(seqID.primaryTerm); | |
+ context.seqID(seqIDGlobal); | |
+ fields.add(seqIDGlobal.seqNo); | |
+ fields.add(seqIDGlobal.seqNoDocValue); | |
+ fields.add(seqIDGlobal.primaryTerm); | |
} | |
@Override | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java | |
index f2090613c09..a36269b31fe 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java | |
@@ -239,7 +239,10 @@ public class SourceFieldMapper extends MetadataFieldMapper { | |
source = bStream.bytes(); | |
} | |
BytesRef ref = source.toBytesRef(); | |
- fields.add(new StoredField(fieldType().name(), ref.bytes, ref.offset, ref.length)); | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
+ StoredField f = foc.pStoredFieldObjectCache.get(fieldType().name(), ref.bytes, 0, 0); | |
+ f.setBytesValue(ref); | |
+ fields.add(f); | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java | |
index 9e2063adb14..9b44064d847 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java | |
@@ -527,8 +527,10 @@ public class TextFieldMapper extends FieldMapper { | |
} | |
if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { | |
- Field field = new Field(fieldType().name(), value, fieldType()); | |
- fields.add(field); | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
+ Field fobj = foc.pGenericFieldObjectCache.get(fieldType().name(), value, fieldType()); | |
+ fobj.setStringValue(value); | |
+ fields.add(fobj); | |
if (fieldType().omitNorms()) { | |
createFieldNamesField(context, fields); | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java | |
index 5172cb652e2..715b3412a29 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java | |
@@ -271,9 +271,14 @@ public class TypeFieldMapper extends MetadataFieldMapper { | |
if (fieldType().indexOptions() == IndexOptions.NONE && !fieldType().stored()) { | |
return; | |
} | |
- fields.add(new Field(fieldType().name(), context.sourceToParse().type(), fieldType())); | |
+ FieldObjectCache foc = ((ParseContext.InternalParseContext)context).getObjectCache(); | |
+ Field f = foc.pGenericFieldObjectCache.get(fieldType().name(), context.sourceToParse().type(), fieldType()); | |
+ fields.add(f); | |
if (fieldType().hasDocValues()) { | |
- fields.add(new SortedSetDocValuesField(fieldType().name(), new BytesRef(context.sourceToParse().type()))); | |
+ SortedSetDocValuesField sf = foc.pSortedSetDocValuesFieldObjectCache.get(fieldType().name(), | |
+ new BytesRef(context.sourceToParse().type())); | |
+ sf.setBytesValue(new BytesRef(context.sourceToParse().type())); | |
+ fields.add(sf); | |
} | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/Uid.java b/server/src/main/java/org/elasticsearch/index/mapper/Uid.java | |
index dca7a54987b..de38f5671f2 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/Uid.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/Uid.java | |
@@ -137,7 +137,7 @@ public final class Uid { | |
/** With numeric ids, we just fold two consecutive chars in a single byte | |
* and use 0x0f as an end marker. */ | |
- private static BytesRef encodeNumericId(String id) { | |
+ private static byte[] encodeNumericId(String id) { | |
byte[] b = new byte[1 + (id.length() + 1) / 2]; | |
b[0] = (byte) NUMERIC; | |
for (int i = 0; i < id.length(); i += 2) { | |
@@ -150,13 +150,13 @@ public final class Uid { | |
} | |
b[1 + i/2] = (byte) ((b1 << 4) | b2); | |
} | |
- return new BytesRef(b); | |
+ return b; | |
} | |
/** With base64 ids, we decode and prepend an escape char in the cases that | |
* it could be mixed up with numeric or utf8 encoding. In the majority of | |
* cases (253/256) the encoded id is exactly the binary form. */ | |
- private static BytesRef encodeBase64Id(String id) { | |
+ private static byte[] encodeBase64Id(String id) { | |
byte[] b = Base64.getUrlDecoder().decode(id); | |
if (Byte.toUnsignedInt(b[0]) >= BASE64_ESCAPE) { | |
byte[] newB = new byte[b.length + 1]; | |
@@ -164,22 +164,22 @@ public final class Uid { | |
System.arraycopy(b, 0, newB, 1, b.length); | |
b = newB; | |
} | |
- return new BytesRef(b, 0, b.length); | |
+ return b; | |
} | |
- private static BytesRef encodeUtf8Id(String id) { | |
+ private static byte[] encodeUtf8Id(String id) { | |
byte[] b = new byte[1 + UnicodeUtil.maxUTF8Length(id.length())]; | |
// Prepend a byte that indicates that the content is an utf8 string | |
b[0] = (byte) UTF8; | |
int length = UnicodeUtil.UTF16toUTF8(id, 0, id.length(), b, 1); | |
- return new BytesRef(b, 0, length); | |
+ return b; | |
} | |
/** Encode an id for storage in the index. This encoding is optimized for | |
* numeric and base64 ids, which are encoded in a much denser way than | |
* what UTF8 would do. | |
* @see #decodeId */ | |
- public static BytesRef encodeId(String id) { | |
+ public static byte[] encodeIdToBytes(String id) { | |
if (id.isEmpty()) { | |
throw new IllegalArgumentException("Ids can't be empty"); | |
} | |
@@ -194,6 +194,11 @@ public final class Uid { | |
} | |
} | |
+ public static BytesRef encodeId(String id) { | |
+ byte[] b = encodeIdToBytes(id); | |
+ return new BytesRef(b, 0, b.length); | |
+ } | |
+ | |
private static String decodeNumericId(byte[] idBytes, int offset, int len) { | |
assert Byte.toUnsignedInt(idBytes[offset]) == NUMERIC; | |
int length = (len - 1) * 2; | |
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java | |
index ef3c63f4889..4edf27f4bb8 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java | |
+++ b/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java | |
@@ -41,6 +41,7 @@ public class VersionFieldMapper extends MetadataFieldMapper { | |
public static final String NAME = "_version"; | |
public static final String CONTENT_TYPE = "_version"; | |
+ private final Field field; | |
public static class Defaults { | |
@@ -101,6 +102,7 @@ public class VersionFieldMapper extends MetadataFieldMapper { | |
private VersionFieldMapper(Settings indexSettings) { | |
super(NAME, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE, indexSettings); | |
+ field = new NumericDocValuesField(NAME, -1L); | |
} | |
@Override | |
@@ -111,9 +113,8 @@ public class VersionFieldMapper extends MetadataFieldMapper { | |
@Override | |
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException { | |
// see InternalEngine.updateVersion to see where the real version value is set | |
- final Field version = new NumericDocValuesField(NAME, -1L); | |
- context.version(version); | |
- fields.add(version); | |
+ context.version(field); | |
+ fields.add(field); | |
} | |
@Override | |
diff --git a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java | |
index 60392ab7990..eb7d47152e0 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java | |
+++ b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java | |
@@ -100,6 +100,8 @@ import org.elasticsearch.index.mapper.ParsedDocument; | |
import org.elasticsearch.index.mapper.SourceToParse; | |
import org.elasticsearch.index.mapper.Uid; | |
import org.elasticsearch.index.merge.MergeStats; | |
+import org.elasticsearch.index.mapper.ParseContext; | |
+import org.elasticsearch.index.mapper.FieldObjectCache; | |
import org.elasticsearch.index.recovery.RecoveryStats; | |
import org.elasticsearch.index.refresh.RefreshStats; | |
import org.elasticsearch.index.search.stats.SearchStats; | |
@@ -675,11 +677,16 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl | |
return index(getEngine(), operation); | |
} | |
+ private static ParseContext.InternalParseContext getParseContext(DocumentMapperForType docMapper, SourceToParse source) { | |
+ FieldObjectCache foc = FieldObjectCache.GetObjectCache(java.lang.Thread.currentThread().getId()); | |
+ return foc.GetParseContext(docMapper, source); | |
+ } | |
+ | |
public static Engine.Index prepareIndex(DocumentMapperForType docMapper, Version indexCreatedVersion, SourceToParse source, long seqNo, | |
long primaryTerm, long version, VersionType versionType, Engine.Operation.Origin origin, long autoGeneratedIdTimestamp, | |
boolean isRetry) { | |
long startTime = System.nanoTime(); | |
- ParsedDocument doc = docMapper.getDocumentMapper().parse(source); | |
+ ParsedDocument doc = docMapper.getDocumentMapper().parse(source, getParseContext(docMapper, source)); | |
if (docMapper.getMapping() != null) { | |
doc.addDynamicMappingsUpdate(docMapper.getMapping()); | |
} | |
diff --git a/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java b/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java | |
index 0148ab44d1b..f236f547407 100644 | |
--- a/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java | |
+++ b/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java | |
@@ -49,6 +49,8 @@ import org.elasticsearch.index.mapper.ParseContext; | |
import org.elasticsearch.index.mapper.ParsedDocument; | |
import org.elasticsearch.index.mapper.SourceFieldMapper; | |
import org.elasticsearch.index.mapper.TextFieldMapper; | |
+import org.elasticsearch.index.mapper.FieldObjectCache; | |
+import org.elasticsearch.index.mapper.SourceToParse; | |
import org.elasticsearch.index.shard.IndexShard; | |
import org.elasticsearch.search.dfs.AggregatedDfs; | |
@@ -308,7 +310,10 @@ public class TermVectorsService { | |
XContentType xContentType) { | |
MapperService mapperService = indexShard.mapperService(); | |
DocumentMapperForType docMapper = mapperService.documentMapperWithAutoCreate(type); | |
- ParsedDocument parsedDocument = docMapper.getDocumentMapper().parse(source(index, type, "_id_for_tv_api", doc, xContentType)); | |
+ SourceToParse src = source(index, type, "_id_for_tv_api", doc, xContentType); | |
+ FieldObjectCache foc = FieldObjectCache.GetObjectCache(java.lang.Thread.currentThread().getId()); | |
+ ParseContext.InternalParseContext parseContext = foc.GetParseContext(docMapper, src); | |
+ ParsedDocument parsedDocument = docMapper.getDocumentMapper().parse(src, parseContext); | |
if (docMapper.getMapping() != null) { | |
parsedDocument.addDynamicMappingsUpdate(docMapper.getMapping()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment