Skip to content

Instantly share code, notes, and snippets.

@aesgithub
Created June 20, 2018 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aesgithub/cc5b54fc3cf5a3a13f1f5ad3139dfd00 to your computer and use it in GitHub Desktop.
Save aesgithub/cc5b54fc3cf5a3a13f1f5ad3139dfd00 to your computer and use it in GitHub Desktop.
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