Improve new field mapping introduction performance
Improve the introduction of new fields into the concrete parsed mappings by not relying on immutable maps and copying over entries, but instead using open maps (which will also use less memory), and using clone to perform the copy on write logic
This commit is contained in:
parent
f01d3a18ad
commit
5cd56e5cea
|
@ -19,27 +19,25 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.analysis;
|
package org.elasticsearch.index.analysis;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.AnalyzerWrapper;
|
import org.apache.lucene.analysis.AnalyzerWrapper;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class FieldNameAnalyzer extends AnalyzerWrapper {
|
public final class FieldNameAnalyzer extends AnalyzerWrapper {
|
||||||
|
|
||||||
private final ImmutableMap<String, Analyzer> analyzers;
|
private final ObjectObjectOpenHashMap<String, Analyzer> analyzers;
|
||||||
|
|
||||||
private final Analyzer defaultAnalyzer;
|
private final Analyzer defaultAnalyzer;
|
||||||
|
|
||||||
public FieldNameAnalyzer(Map<String, Analyzer> analyzers, Analyzer defaultAnalyzer) {
|
public FieldNameAnalyzer(ObjectObjectOpenHashMap<String, Analyzer> analyzers, Analyzer defaultAnalyzer) {
|
||||||
this.analyzers = ImmutableMap.copyOf(analyzers);
|
this.analyzers = analyzers;
|
||||||
this.defaultAnalyzer = defaultAnalyzer;
|
this.defaultAnalyzer = defaultAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableMap<String, Analyzer> analyzers() {
|
public ObjectObjectOpenHashMap<String, Analyzer> analyzers() {
|
||||||
return analyzers;
|
return analyzers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,65 +19,43 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper;
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
import com.google.common.collect.*;
|
import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.UnmodifiableIterator;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.elasticsearch.common.regex.Regex;
|
import org.elasticsearch.common.hppc.HppcMaps;
|
||||||
import org.elasticsearch.index.analysis.FieldNameAnalyzer;
|
import org.elasticsearch.index.analysis.FieldNameAnalyzer;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
|
|
||||||
private final ImmutableList<FieldMapper> fieldMappers;
|
private final DocumentMapper docMapper;
|
||||||
private final Map<String, FieldMappers> fullNameFieldMappers;
|
private final FieldMappersLookup fieldMappers;
|
||||||
private final Map<String, FieldMappers> nameFieldMappers;
|
|
||||||
private final Map<String, FieldMappers> indexNameFieldMappers;
|
|
||||||
|
|
||||||
private final FieldNameAnalyzer indexAnalyzer;
|
private volatile FieldNameAnalyzer indexAnalyzer;
|
||||||
private final FieldNameAnalyzer searchAnalyzer;
|
private volatile FieldNameAnalyzer searchAnalyzer;
|
||||||
private final FieldNameAnalyzer searchQuoteAnalyzer;
|
private volatile FieldNameAnalyzer searchQuoteAnalyzer;
|
||||||
|
|
||||||
public DocumentFieldMappers(DocumentMapper docMapper, Iterable<FieldMapper> fieldMappers) {
|
public DocumentFieldMappers(DocumentMapper docMapper) {
|
||||||
final Map<String, FieldMappers> tempNameFieldMappers = newHashMap();
|
this.docMapper = docMapper;
|
||||||
final Map<String, FieldMappers> tempIndexNameFieldMappers = newHashMap();
|
this.fieldMappers = new FieldMappersLookup();
|
||||||
final Map<String, FieldMappers> tempFullNameFieldMappers = newHashMap();
|
this.indexAnalyzer = new FieldNameAnalyzer(HppcMaps.<String, Analyzer>newMap(), docMapper.indexAnalyzer());
|
||||||
|
this.searchAnalyzer = new FieldNameAnalyzer(HppcMaps.<String, Analyzer>newMap(), docMapper.searchAnalyzer());
|
||||||
|
this.searchQuoteAnalyzer = new FieldNameAnalyzer(HppcMaps.<String, Analyzer>newMap(), docMapper.searchQuotedAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, Analyzer> indexAnalyzers = newHashMap();
|
public void addNewMappers(Iterable<FieldMapper> newMappers) {
|
||||||
final Map<String, Analyzer> searchAnalyzers = newHashMap();
|
fieldMappers.addNewMappers(newMappers);
|
||||||
final Map<String, Analyzer> searchQuoteAnalyzers = newHashMap();
|
|
||||||
|
|
||||||
for (FieldMapper fieldMapper : fieldMappers) {
|
final ObjectObjectOpenHashMap<String, Analyzer> indexAnalyzers = this.indexAnalyzer.analyzers().clone();
|
||||||
FieldMappers mappers = tempNameFieldMappers.get(fieldMapper.names().name());
|
final ObjectObjectOpenHashMap<String, Analyzer> searchAnalyzers = this.searchAnalyzer.analyzers().clone();
|
||||||
if (mappers == null) {
|
final ObjectObjectOpenHashMap<String, Analyzer> searchQuoteAnalyzers = this.searchQuoteAnalyzer.analyzers().clone();
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
tempNameFieldMappers.put(fieldMapper.names().name(), mappers);
|
|
||||||
|
|
||||||
mappers = tempIndexNameFieldMappers.get(fieldMapper.names().indexName());
|
|
||||||
if (mappers == null) {
|
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
tempIndexNameFieldMappers.put(fieldMapper.names().indexName(), mappers);
|
|
||||||
|
|
||||||
mappers = tempFullNameFieldMappers.get(fieldMapper.names().fullName());
|
|
||||||
if (mappers == null) {
|
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
tempFullNameFieldMappers.put(fieldMapper.names().fullName(), mappers);
|
|
||||||
|
|
||||||
|
for (FieldMapper fieldMapper : newMappers) {
|
||||||
if (fieldMapper.indexAnalyzer() != null) {
|
if (fieldMapper.indexAnalyzer() != null) {
|
||||||
indexAnalyzers.put(fieldMapper.names().indexName(), fieldMapper.indexAnalyzer());
|
indexAnalyzers.put(fieldMapper.names().indexName(), fieldMapper.indexAnalyzer());
|
||||||
}
|
}
|
||||||
|
@ -88,10 +66,6 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
searchQuoteAnalyzers.put(fieldMapper.names().indexName(), fieldMapper.searchQuoteAnalyzer());
|
searchQuoteAnalyzers.put(fieldMapper.names().indexName(), fieldMapper.searchQuoteAnalyzer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.fieldMappers = ImmutableList.copyOf(fieldMappers);
|
|
||||||
this.nameFieldMappers = ImmutableMap.copyOf(tempNameFieldMappers);
|
|
||||||
this.indexNameFieldMappers = ImmutableMap.copyOf(tempIndexNameFieldMappers);
|
|
||||||
this.fullNameFieldMappers = ImmutableMap.copyOf(tempFullNameFieldMappers);
|
|
||||||
|
|
||||||
this.indexAnalyzer = new FieldNameAnalyzer(indexAnalyzers, docMapper.indexAnalyzer());
|
this.indexAnalyzer = new FieldNameAnalyzer(indexAnalyzers, docMapper.indexAnalyzer());
|
||||||
this.searchAnalyzer = new FieldNameAnalyzer(searchAnalyzers, docMapper.searchAnalyzer());
|
this.searchAnalyzer = new FieldNameAnalyzer(searchAnalyzers, docMapper.searchAnalyzer());
|
||||||
|
@ -104,51 +78,31 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableList<FieldMapper> mappers() {
|
public ImmutableList<FieldMapper> mappers() {
|
||||||
return this.fieldMappers;
|
return this.fieldMappers.mappers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasMapper(FieldMapper fieldMapper) {
|
public boolean hasMapper(FieldMapper fieldMapper) {
|
||||||
return fieldMappers.contains(fieldMapper);
|
return fieldMappers.mappers().contains(fieldMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldMappers name(String name) {
|
public FieldMappers name(String name) {
|
||||||
return nameFieldMappers.get(name);
|
return fieldMappers.name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldMappers indexName(String indexName) {
|
public FieldMappers indexName(String indexName) {
|
||||||
return indexNameFieldMappers.get(indexName);
|
return fieldMappers.indexName(indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldMappers fullName(String fullName) {
|
public FieldMappers fullName(String fullName) {
|
||||||
return fullNameFieldMappers.get(fullName);
|
return fieldMappers.fullName(fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> simpleMatchToIndexNames(String pattern) {
|
public Set<String> simpleMatchToIndexNames(String pattern) {
|
||||||
Set<String> fields = Sets.newHashSet();
|
return fieldMappers.simpleMatchToIndexNames(pattern);
|
||||||
for (FieldMapper fieldMapper : fieldMappers) {
|
|
||||||
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
|
||||||
fields.add(fieldMapper.names().indexName());
|
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
|
||||||
fields.add(fieldMapper.names().indexName());
|
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
|
||||||
fields.add(fieldMapper.names().indexName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> simpleMatchToFullName(String pattern) {
|
public Set<String> simpleMatchToFullName(String pattern) {
|
||||||
Set<String> fields = Sets.newHashSet();
|
return fieldMappers.simpleMatchToFullName(pattern);
|
||||||
for (FieldMapper fieldMapper : fieldMappers) {
|
|
||||||
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
|
||||||
fields.add(fieldMapper.names().fullName());
|
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
|
||||||
fields.add(fieldMapper.names().fullName());
|
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
|
||||||
fields.add(fieldMapper.names().fullName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,23 +110,11 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
* by {@link #name(String)}.
|
* by {@link #name(String)}.
|
||||||
*/
|
*/
|
||||||
public FieldMappers smartName(String name) {
|
public FieldMappers smartName(String name) {
|
||||||
FieldMappers fieldMappers = fullName(name);
|
return fieldMappers.smartName(name);
|
||||||
if (fieldMappers != null) {
|
|
||||||
return fieldMappers;
|
|
||||||
}
|
|
||||||
fieldMappers = indexName(name);
|
|
||||||
if (fieldMappers != null) {
|
|
||||||
return fieldMappers;
|
|
||||||
}
|
|
||||||
return name(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldMapper smartNameFieldMapper(String name) {
|
public FieldMapper smartNameFieldMapper(String name) {
|
||||||
FieldMappers fieldMappers = smartName(name);
|
return fieldMappers.smartNameFieldMapper(name);
|
||||||
if (fieldMappers == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return fieldMappers.mapper();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,12 +144,4 @@ public class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
public Analyzer searchQuoteAnalyzer() {
|
public Analyzer searchQuoteAnalyzer() {
|
||||||
return this.searchQuoteAnalyzer;
|
return this.searchQuoteAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocumentFieldMappers concat(DocumentMapper docMapper, FieldMapper... fieldMappers) {
|
|
||||||
return concat(docMapper, newArrayList(fieldMappers));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DocumentFieldMappers concat(DocumentMapper docMapper, Iterable<FieldMapper> fieldMappers) {
|
|
||||||
return new DocumentFieldMappers(docMapper, Iterables.concat(this.fieldMappers, fieldMappers));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
private final NamedAnalyzer searchAnalyzer;
|
private final NamedAnalyzer searchAnalyzer;
|
||||||
private final NamedAnalyzer searchQuoteAnalyzer;
|
private final NamedAnalyzer searchQuoteAnalyzer;
|
||||||
|
|
||||||
private volatile DocumentFieldMappers fieldMappers;
|
private final DocumentFieldMappers fieldMappers;
|
||||||
|
|
||||||
private volatile ImmutableMap<String, ObjectMapper> objectMappers = ImmutableMap.of();
|
private volatile ImmutableMap<String, ObjectMapper> objectMappers = ImmutableMap.of();
|
||||||
|
|
||||||
|
@ -325,7 +325,8 @@ public class DocumentMapper implements ToXContent {
|
||||||
// now traverse and get all the statically defined ones
|
// now traverse and get all the statically defined ones
|
||||||
rootObjectMapper.traverse(fieldMappersAgg);
|
rootObjectMapper.traverse(fieldMappersAgg);
|
||||||
|
|
||||||
this.fieldMappers = new DocumentFieldMappers(this, fieldMappersAgg.mappers);
|
this.fieldMappers = new DocumentFieldMappers(this);
|
||||||
|
this.fieldMappers.addNewMappers(fieldMappersAgg.mappers);
|
||||||
|
|
||||||
final Map<String, ObjectMapper> objectMappers = Maps.newHashMap();
|
final Map<String, ObjectMapper> objectMappers = Maps.newHashMap();
|
||||||
rootObjectMapper.traverse(new ObjectMapperListener() {
|
rootObjectMapper.traverse(new ObjectMapperListener() {
|
||||||
|
@ -575,7 +576,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
|
|
||||||
public void addFieldMappers(FieldMapper... fieldMappers) {
|
public void addFieldMappers(FieldMapper... fieldMappers) {
|
||||||
synchronized (mappersMutex) {
|
synchronized (mappersMutex) {
|
||||||
this.fieldMappers = this.fieldMappers.concat(this, fieldMappers);
|
this.fieldMappers.addNewMappers(Arrays.asList(fieldMappers));
|
||||||
}
|
}
|
||||||
for (FieldMapperListener listener : fieldMapperListeners) {
|
for (FieldMapperListener listener : fieldMapperListeners) {
|
||||||
listener.fieldMappers(fieldMappers);
|
listener.fieldMappers(fieldMappers);
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.collect.UnmodifiableIterator;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.hppc.HppcMaps;
|
||||||
|
import org.elasticsearch.common.regex.Regex;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that holds a map of field mappers from name, index name, and full name.
|
||||||
|
*/
|
||||||
|
public class FieldMappersLookup implements Iterable<FieldMapper> {
|
||||||
|
|
||||||
|
private volatile ImmutableList<FieldMapper> mappers;
|
||||||
|
private volatile ObjectObjectOpenHashMap<String, FieldMappers> name;
|
||||||
|
private volatile ObjectObjectOpenHashMap<String, FieldMappers> indexName;
|
||||||
|
private volatile ObjectObjectOpenHashMap<String, FieldMappers> fullName;
|
||||||
|
|
||||||
|
public FieldMappersLookup() {
|
||||||
|
this.mappers = ImmutableList.of();
|
||||||
|
this.fullName = HppcMaps.newMap();
|
||||||
|
this.name = HppcMaps.newMap();
|
||||||
|
this.indexName = HppcMaps.newMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new set of mappers.
|
||||||
|
*/
|
||||||
|
public void addNewMappers(Iterable<FieldMapper> newMappers) {
|
||||||
|
final ObjectObjectOpenHashMap<String, FieldMappers> tempName = this.name.clone();
|
||||||
|
final ObjectObjectOpenHashMap<String, FieldMappers> tempIndexName = this.indexName.clone();
|
||||||
|
final ObjectObjectOpenHashMap<String, FieldMappers> tempFullName = this.fullName.clone();
|
||||||
|
|
||||||
|
for (FieldMapper fieldMapper : newMappers) {
|
||||||
|
FieldMappers mappers = tempName.get(fieldMapper.names().name());
|
||||||
|
if (mappers == null) {
|
||||||
|
mappers = new FieldMappers(fieldMapper);
|
||||||
|
} else {
|
||||||
|
mappers = mappers.concat(fieldMapper);
|
||||||
|
}
|
||||||
|
tempName.put(fieldMapper.names().name(), mappers);
|
||||||
|
|
||||||
|
mappers = tempIndexName.get(fieldMapper.names().indexName());
|
||||||
|
if (mappers == null) {
|
||||||
|
mappers = new FieldMappers(fieldMapper);
|
||||||
|
} else {
|
||||||
|
mappers = mappers.concat(fieldMapper);
|
||||||
|
}
|
||||||
|
tempIndexName.put(fieldMapper.names().indexName(), mappers);
|
||||||
|
|
||||||
|
mappers = tempFullName.get(fieldMapper.names().fullName());
|
||||||
|
if (mappers == null) {
|
||||||
|
mappers = new FieldMappers(fieldMapper);
|
||||||
|
} else {
|
||||||
|
mappers = mappers.concat(fieldMapper);
|
||||||
|
}
|
||||||
|
tempFullName.put(fieldMapper.names().fullName(), mappers);
|
||||||
|
}
|
||||||
|
this.mappers = ImmutableList.<FieldMapper>builder().addAll(this.mappers).addAll(newMappers).build();
|
||||||
|
this.name = tempName;
|
||||||
|
this.indexName = tempIndexName;
|
||||||
|
this.fullName = tempFullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the set of mappers.
|
||||||
|
*/
|
||||||
|
public void removeMappers(Iterable<FieldMapper> mappersToRemove) {
|
||||||
|
List<FieldMapper> tempMappers = new ArrayList<FieldMapper>(this.mappers);
|
||||||
|
ObjectObjectOpenHashMap<String, FieldMappers> tempName = this.name.clone();
|
||||||
|
ObjectObjectOpenHashMap<String, FieldMappers> tempIndexName = this.indexName.clone();
|
||||||
|
ObjectObjectOpenHashMap<String, FieldMappers> tempFullName = this.fullName.clone();
|
||||||
|
|
||||||
|
for (FieldMapper mapper : mappersToRemove) {
|
||||||
|
FieldMappers mappers = tempName.get(mapper.names().name());
|
||||||
|
if (mappers != null) {
|
||||||
|
mappers = mappers.remove(mapper);
|
||||||
|
if (mappers.isEmpty()) {
|
||||||
|
tempName.remove(mapper.names().name());
|
||||||
|
} else {
|
||||||
|
tempName.put(mapper.names().name(), mappers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mappers = tempIndexName.get(mapper.names().indexName());
|
||||||
|
if (mappers != null) {
|
||||||
|
mappers = mappers.remove(mapper);
|
||||||
|
if (mappers.isEmpty()) {
|
||||||
|
tempIndexName.remove(mapper.names().indexName());
|
||||||
|
} else {
|
||||||
|
tempIndexName.put(mapper.names().indexName(), mappers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mappers = tempFullName.get(mapper.names().fullName());
|
||||||
|
if (mappers != null) {
|
||||||
|
mappers = mappers.remove(mapper);
|
||||||
|
if (mappers.isEmpty()) {
|
||||||
|
tempFullName.remove(mapper.names().fullName());
|
||||||
|
} else {
|
||||||
|
tempFullName.put(mapper.names().fullName(), mappers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tempMappers.remove(mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.mappers = ImmutableList.copyOf(tempMappers);
|
||||||
|
this.name = tempName;
|
||||||
|
this.indexName = tempIndexName;
|
||||||
|
this.fullName = tempFullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnmodifiableIterator<FieldMapper> iterator() {
|
||||||
|
return mappers.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of all mappers.
|
||||||
|
*/
|
||||||
|
public ImmutableList<FieldMapper> mappers() {
|
||||||
|
return this.mappers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there a mapper (based on unique {@link FieldMapper} identity)?
|
||||||
|
*/
|
||||||
|
public boolean hasMapper(FieldMapper fieldMapper) {
|
||||||
|
return mappers.contains(fieldMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the field mappers based on the mapper name.
|
||||||
|
*/
|
||||||
|
public FieldMappers name(String name) {
|
||||||
|
return this.name.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the field mappers based on the mapper index name.
|
||||||
|
*/
|
||||||
|
public FieldMappers indexName(String indexName) {
|
||||||
|
return this.indexName.get(indexName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the field mappers based on the mapper full name.
|
||||||
|
*/
|
||||||
|
public FieldMappers fullName(String fullName) {
|
||||||
|
return this.fullName.get(fullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of the index names of a simple match regex like pattern against full name, name and index name.
|
||||||
|
*/
|
||||||
|
public Set<String> simpleMatchToIndexNames(String pattern) {
|
||||||
|
Set<String> fields = Sets.newHashSet();
|
||||||
|
for (FieldMapper fieldMapper : mappers) {
|
||||||
|
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
||||||
|
fields.add(fieldMapper.names().indexName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
||||||
|
fields.add(fieldMapper.names().indexName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
||||||
|
fields.add(fieldMapper.names().indexName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of the full names of a simple match regex like pattern against full name, name and index name.
|
||||||
|
*/
|
||||||
|
public Set<String> simpleMatchToFullName(String pattern) {
|
||||||
|
Set<String> fields = Sets.newHashSet();
|
||||||
|
for (FieldMapper fieldMapper : mappers) {
|
||||||
|
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
|
||||||
|
fields.add(fieldMapper.names().fullName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last
|
||||||
|
* by {@link #name(String)}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public FieldMappers smartName(String name) {
|
||||||
|
FieldMappers fieldMappers = fullName(name);
|
||||||
|
if (fieldMappers != null) {
|
||||||
|
return fieldMappers;
|
||||||
|
}
|
||||||
|
fieldMappers = indexName(name);
|
||||||
|
if (fieldMappers != null) {
|
||||||
|
return fieldMappers;
|
||||||
|
}
|
||||||
|
return name(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last
|
||||||
|
* by {@link #name(String)} and return the first mapper for it (see {@link org.elasticsearch.index.mapper.FieldMappers#mapper()}).
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public FieldMapper smartNameFieldMapper(String name) {
|
||||||
|
FieldMappers fieldMappers = smartName(name);
|
||||||
|
if (fieldMappers == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return fieldMappers.mapper();
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper;
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
|
@ -31,7 +32,7 @@ import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.hppc.HppcMaps;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.io.Streams;
|
import org.elasticsearch.common.io.Streams;
|
||||||
import org.elasticsearch.common.lucene.search.AndFilter;
|
import org.elasticsearch.common.lucene.search.AndFilter;
|
||||||
|
@ -88,10 +89,8 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
private final Object typeMutex = new Object();
|
private final Object typeMutex = new Object();
|
||||||
private final Object mappersMutex = new Object();
|
private final Object mappersMutex = new Object();
|
||||||
|
|
||||||
private volatile Map<String, FieldMappers> nameFieldMappers = ImmutableMap.of();
|
private final FieldMappersLookup fieldMappers = new FieldMappersLookup();
|
||||||
private volatile Map<String, FieldMappers> indexNameFieldMappers = ImmutableMap.of();
|
private volatile ObjectObjectOpenHashMap<String, ObjectMappers> fullPathObjectMappers = HppcMaps.newMap();
|
||||||
private volatile Map<String, FieldMappers> fullNameFieldMappers = ImmutableMap.of();
|
|
||||||
private volatile Map<String, ObjectMappers> fullPathObjectMappers = ImmutableMap.of();
|
|
||||||
private boolean hasNested = false; // updated dynamically to true when a nested object is added
|
private boolean hasNested = false; // updated dynamically to true when a nested object is added
|
||||||
|
|
||||||
private final DocumentMapperParser documentParser;
|
private final DocumentMapperParser documentParser;
|
||||||
|
@ -296,7 +295,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
|
|
||||||
private void addObjectMappers(ObjectMapper[] objectMappers) {
|
private void addObjectMappers(ObjectMapper[] objectMappers) {
|
||||||
synchronized (mappersMutex) {
|
synchronized (mappersMutex) {
|
||||||
MapBuilder<String, ObjectMappers> fullPathObjectMappers = newMapBuilder(this.fullPathObjectMappers);
|
ObjectObjectOpenHashMap<String, ObjectMappers> fullPathObjectMappers = this.fullPathObjectMappers.clone();
|
||||||
for (ObjectMapper objectMapper : objectMappers) {
|
for (ObjectMapper objectMapper : objectMappers) {
|
||||||
ObjectMappers mappers = fullPathObjectMappers.get(objectMapper.fullPath());
|
ObjectMappers mappers = fullPathObjectMappers.get(objectMapper.fullPath());
|
||||||
if (mappers == null) {
|
if (mappers == null) {
|
||||||
|
@ -310,46 +309,13 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
hasNested = true;
|
hasNested = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.fullPathObjectMappers = fullPathObjectMappers.map();
|
this.fullPathObjectMappers = fullPathObjectMappers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFieldMappers(FieldMapper[] fieldMappers) {
|
private void addFieldMappers(FieldMapper[] fieldMappers) {
|
||||||
synchronized (mappersMutex) {
|
synchronized (mappersMutex) {
|
||||||
MapBuilder<String, FieldMappers> nameFieldMappers = newMapBuilder(this.nameFieldMappers);
|
this.fieldMappers.addNewMappers(Arrays.asList(fieldMappers));
|
||||||
MapBuilder<String, FieldMappers> indexNameFieldMappers = newMapBuilder(this.indexNameFieldMappers);
|
|
||||||
MapBuilder<String, FieldMappers> fullNameFieldMappers = newMapBuilder(this.fullNameFieldMappers);
|
|
||||||
for (FieldMapper fieldMapper : fieldMappers) {
|
|
||||||
FieldMappers mappers = nameFieldMappers.get(fieldMapper.names().name());
|
|
||||||
if (mappers == null) {
|
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
nameFieldMappers.put(fieldMapper.names().name(), mappers);
|
|
||||||
|
|
||||||
|
|
||||||
mappers = indexNameFieldMappers.get(fieldMapper.names().indexName());
|
|
||||||
if (mappers == null) {
|
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
indexNameFieldMappers.put(fieldMapper.names().indexName(), mappers);
|
|
||||||
|
|
||||||
|
|
||||||
mappers = fullNameFieldMappers.get(fieldMapper.names().fullName());
|
|
||||||
if (mappers == null) {
|
|
||||||
mappers = new FieldMappers(fieldMapper);
|
|
||||||
} else {
|
|
||||||
mappers = mappers.concat(fieldMapper);
|
|
||||||
}
|
|
||||||
fullNameFieldMappers.put(fieldMapper.names().fullName(), mappers);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.nameFieldMappers = nameFieldMappers.map();
|
|
||||||
this.indexNameFieldMappers = indexNameFieldMappers.map();
|
|
||||||
this.fullNameFieldMappers = fullNameFieldMappers.map();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,47 +336,9 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
|
|
||||||
private void removeObjectAndFieldMappers(DocumentMapper docMapper) {
|
private void removeObjectAndFieldMappers(DocumentMapper docMapper) {
|
||||||
synchronized (mappersMutex) {
|
synchronized (mappersMutex) {
|
||||||
// we need to remove those mappers
|
fieldMappers.removeMappers(docMapper.mappers());
|
||||||
MapBuilder<String, FieldMappers> nameFieldMappers = newMapBuilder(this.nameFieldMappers);
|
|
||||||
MapBuilder<String, FieldMappers> indexNameFieldMappers = newMapBuilder(this.indexNameFieldMappers);
|
|
||||||
MapBuilder<String, FieldMappers> fullNameFieldMappers = newMapBuilder(this.fullNameFieldMappers);
|
|
||||||
|
|
||||||
for (FieldMapper mapper : docMapper.mappers()) {
|
ObjectObjectOpenHashMap<String, ObjectMappers> fullPathObjectMappers = this.fullPathObjectMappers.clone();
|
||||||
FieldMappers mappers = nameFieldMappers.get(mapper.names().name());
|
|
||||||
if (mappers != null) {
|
|
||||||
mappers = mappers.remove(mapper);
|
|
||||||
if (mappers.isEmpty()) {
|
|
||||||
nameFieldMappers.remove(mapper.names().name());
|
|
||||||
} else {
|
|
||||||
nameFieldMappers.put(mapper.names().name(), mappers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mappers = indexNameFieldMappers.get(mapper.names().indexName());
|
|
||||||
if (mappers != null) {
|
|
||||||
mappers = mappers.remove(mapper);
|
|
||||||
if (mappers.isEmpty()) {
|
|
||||||
indexNameFieldMappers.remove(mapper.names().indexName());
|
|
||||||
} else {
|
|
||||||
indexNameFieldMappers.put(mapper.names().indexName(), mappers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mappers = fullNameFieldMappers.get(mapper.names().fullName());
|
|
||||||
if (mappers != null) {
|
|
||||||
mappers = mappers.remove(mapper);
|
|
||||||
if (mappers.isEmpty()) {
|
|
||||||
fullNameFieldMappers.remove(mapper.names().fullName());
|
|
||||||
} else {
|
|
||||||
fullNameFieldMappers.put(mapper.names().fullName(), mappers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.nameFieldMappers = nameFieldMappers.map();
|
|
||||||
this.indexNameFieldMappers = indexNameFieldMappers.map();
|
|
||||||
this.fullNameFieldMappers = fullNameFieldMappers.map();
|
|
||||||
|
|
||||||
MapBuilder<String, ObjectMappers> fullPathObjectMappers = newMapBuilder(this.fullPathObjectMappers);
|
|
||||||
for (ObjectMapper mapper : docMapper.objectMappers().values()) {
|
for (ObjectMapper mapper : docMapper.objectMappers().values()) {
|
||||||
ObjectMappers mappers = fullPathObjectMappers.get(mapper.fullPath());
|
ObjectMappers mappers = fullPathObjectMappers.get(mapper.fullPath());
|
||||||
if (mappers != null) {
|
if (mappers != null) {
|
||||||
|
@ -423,7 +351,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fullPathObjectMappers = fullPathObjectMappers.map();
|
this.fullPathObjectMappers = fullPathObjectMappers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +494,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
* @return All the {@link FieldMappers} for across all {@link DocumentMapper}s
|
* @return All the {@link FieldMappers} for across all {@link DocumentMapper}s
|
||||||
*/
|
*/
|
||||||
public FieldMappers name(String name) {
|
public FieldMappers name(String name) {
|
||||||
return nameFieldMappers.get(name);
|
return fieldMappers.name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -577,7 +505,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
* @return All the {@link FieldMappers} across all {@link DocumentMapper}s for the given indexName.
|
* @return All the {@link FieldMappers} across all {@link DocumentMapper}s for the given indexName.
|
||||||
*/
|
*/
|
||||||
public FieldMappers indexName(String indexName) {
|
public FieldMappers indexName(String indexName) {
|
||||||
return indexNameFieldMappers.get(indexName);
|
return fieldMappers.indexName(indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -588,7 +516,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
* @return All teh {@link FieldMappers} across all the {@link DocumentMapper}s for the given fullName.
|
* @return All teh {@link FieldMappers} across all the {@link DocumentMapper}s for the given fullName.
|
||||||
*/
|
*/
|
||||||
public FieldMappers fullName(String fullName) {
|
public FieldMappers fullName(String fullName) {
|
||||||
return fullNameFieldMappers.get(fullName);
|
return fieldMappers.fullName(fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -644,29 +572,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
return typedFields;
|
return typedFields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Set<String> fields = Sets.newHashSet();
|
return fieldMappers.simpleMatchToIndexNames(pattern);
|
||||||
for (Map.Entry<String, FieldMappers> entry : fullNameFieldMappers.entrySet()) {
|
|
||||||
if (Regex.simpleMatch(pattern, entry.getKey())) {
|
|
||||||
for (FieldMapper mapper : entry.getValue()) {
|
|
||||||
fields.add(mapper.names().indexName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Map.Entry<String, FieldMappers> entry : indexNameFieldMappers.entrySet()) {
|
|
||||||
if (Regex.simpleMatch(pattern, entry.getKey())) {
|
|
||||||
for (FieldMapper mapper : entry.getValue()) {
|
|
||||||
fields.add(mapper.names().indexName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Map.Entry<String, FieldMappers> entry : nameFieldMappers.entrySet()) {
|
|
||||||
if (Regex.simpleMatch(pattern, entry.getKey())) {
|
|
||||||
for (FieldMapper mapper : entry.getValue()) {
|
|
||||||
fields.add(mapper.names().indexName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SmartNameObjectMapper smartNameObjectMapper(String smartName, @Nullable String[] types) {
|
public SmartNameObjectMapper smartNameObjectMapper(String smartName, @Nullable String[] types) {
|
||||||
|
@ -1060,12 +966,12 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
return possibleDocMapper.mappers().searchAnalyzer();
|
return possibleDocMapper.mappers().searchAnalyzer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldMappers mappers = fullNameFieldMappers.get(fieldName);
|
FieldMappers mappers = fieldMappers.fullName(fieldName);
|
||||||
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchAnalyzer() != null) {
|
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchAnalyzer() != null) {
|
||||||
return mappers.mapper().searchAnalyzer();
|
return mappers.mapper().searchAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
||||||
mappers = indexNameFieldMappers.get(fieldName);
|
mappers = fieldMappers.indexName(fieldName);
|
||||||
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchAnalyzer() != null) {
|
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchAnalyzer() != null) {
|
||||||
return mappers.mapper().searchAnalyzer();
|
return mappers.mapper().searchAnalyzer();
|
||||||
}
|
}
|
||||||
|
@ -1096,12 +1002,12 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||||
return possibleDocMapper.mappers().searchQuoteAnalyzer();
|
return possibleDocMapper.mappers().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldMappers mappers = fullNameFieldMappers.get(fieldName);
|
FieldMappers mappers = fieldMappers.fullName(fieldName);
|
||||||
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) {
|
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) {
|
||||||
return mappers.mapper().searchQuoteAnalyzer();
|
return mappers.mapper().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
||||||
mappers = indexNameFieldMappers.get(fieldName);
|
mappers = fieldMappers.indexName(fieldName);
|
||||||
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) {
|
if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) {
|
||||||
return mappers.mapper().searchQuoteAnalyzer();
|
return mappers.mapper().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper.object;
|
package org.elasticsearch.index.mapper.object;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
|
||||||
|
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.index.IndexableField;
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
@ -29,6 +30,7 @@ import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.hppc.HppcMaps;
|
||||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -42,9 +44,7 @@ import org.elasticsearch.index.mapper.multifield.MultiFieldMapper;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static com.google.common.collect.ImmutableMap.copyOf;
|
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
|
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType;
|
||||||
|
@ -291,7 +291,7 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
|
|
||||||
private Boolean includeInAll;
|
private Boolean includeInAll;
|
||||||
|
|
||||||
private volatile ImmutableMap<String, Mapper> mappers = ImmutableMap.of();
|
private volatile ObjectObjectOpenHashMap<String, Mapper> mappers = HppcMaps.newMap();
|
||||||
|
|
||||||
private final Object mutex = new Object();
|
private final Object mutex = new Object();
|
||||||
|
|
||||||
|
@ -303,7 +303,9 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
this.dynamic = dynamic;
|
this.dynamic = dynamic;
|
||||||
this.pathType = pathType;
|
this.pathType = pathType;
|
||||||
if (mappers != null) {
|
if (mappers != null) {
|
||||||
this.mappers = copyOf(mappers);
|
for (Map.Entry<String, Mapper> entry : mappers.entrySet()) {
|
||||||
|
this.mappers.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.nestedTypePathAsString = "__" + fullPath;
|
this.nestedTypePathAsString = "__" + fullPath;
|
||||||
this.nestedTypePathAsBytes = new BytesRef(nestedTypePathAsString);
|
this.nestedTypePathAsBytes = new BytesRef(nestedTypePathAsString);
|
||||||
|
@ -322,9 +324,9 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
}
|
}
|
||||||
this.includeInAll = includeInAll;
|
this.includeInAll = includeInAll;
|
||||||
// when called from outside, apply this on all the inner mappers
|
// when called from outside, apply this on all the inner mappers
|
||||||
for (Mapper mapper : mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
if (mapper instanceof AllFieldMapper.IncludeInAll) {
|
if (cursor.value instanceof AllFieldMapper.IncludeInAll) {
|
||||||
((AllFieldMapper.IncludeInAll) mapper).includeInAll(includeInAll);
|
((AllFieldMapper.IncludeInAll) cursor.value).includeInAll(includeInAll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,9 +337,9 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
this.includeInAll = includeInAll;
|
this.includeInAll = includeInAll;
|
||||||
}
|
}
|
||||||
// when called from outside, apply this on all the inner mappers
|
// when called from outside, apply this on all the inner mappers
|
||||||
for (Mapper mapper : mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
if (mapper instanceof AllFieldMapper.IncludeInAll) {
|
if (cursor.value instanceof AllFieldMapper.IncludeInAll) {
|
||||||
((AllFieldMapper.IncludeInAll) mapper).includeInAllIfNotSet(includeInAll);
|
((AllFieldMapper.IncludeInAll) cursor.value).includeInAllIfNotSet(includeInAll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,23 +357,25 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
((AllFieldMapper.IncludeInAll) mapper).includeInAllIfNotSet(includeInAll);
|
((AllFieldMapper.IncludeInAll) mapper).includeInAllIfNotSet(includeInAll);
|
||||||
}
|
}
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
mappers = newMapBuilder(mappers).put(mapper.name(), mapper).immutableMap();
|
ObjectObjectOpenHashMap<String, Mapper> mappers = this.mappers.clone();
|
||||||
|
mappers.put(mapper.name(), mapper);
|
||||||
|
this.mappers = mappers;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void traverse(FieldMapperListener fieldMapperListener) {
|
public void traverse(FieldMapperListener fieldMapperListener) {
|
||||||
for (Mapper mapper : mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
mapper.traverse(fieldMapperListener);
|
cursor.value.traverse(fieldMapperListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void traverse(ObjectMapperListener objectMapperListener) {
|
public void traverse(ObjectMapperListener objectMapperListener) {
|
||||||
objectMapperListener.objectMapper(this);
|
objectMapperListener.objectMapper(this);
|
||||||
for (Mapper mapper : mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
mapper.traverse(objectMapperListener);
|
cursor.value.traverse(objectMapperListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +839,8 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
FieldMapperListener.Aggregator newFieldMappers = new FieldMapperListener.Aggregator();
|
FieldMapperListener.Aggregator newFieldMappers = new FieldMapperListener.Aggregator();
|
||||||
ObjectMapperListener.Aggregator newObjectMappers = new ObjectMapperListener.Aggregator();
|
ObjectMapperListener.Aggregator newObjectMappers = new ObjectMapperListener.Aggregator();
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
for (Mapper mergeWithMapper : mergeWithObject.mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mergeWithObject.mappers) {
|
||||||
|
Mapper mergeWithMapper = cursor.value;
|
||||||
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||||
if (mergeIntoMapper == null) {
|
if (mergeIntoMapper == null) {
|
||||||
// no mapping, simply add it if not simulating
|
// no mapping, simply add it if not simulating
|
||||||
|
@ -882,8 +887,8 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
for (Mapper mapper : mappers.values()) {
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
mapper.close();
|
cursor.value.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,7 +931,10 @@ public class ObjectMapper implements Mapper, AllFieldMapper.IncludeInAll {
|
||||||
doXContent(builder, params);
|
doXContent(builder, params);
|
||||||
|
|
||||||
// sort the mappers so we get consistent serialization format
|
// sort the mappers so we get consistent serialization format
|
||||||
TreeMap<String, Mapper> sortedMappers = new TreeMap<String, Mapper>(mappers);
|
TreeMap<String, Mapper> sortedMappers = new TreeMap<String, Mapper>();
|
||||||
|
for (ObjectObjectCursor<String, Mapper> cursor : mappers) {
|
||||||
|
sortedMappers.put(cursor.key, cursor.value);
|
||||||
|
}
|
||||||
|
|
||||||
// check internal mappers first (this is only relevant for root object)
|
// check internal mappers first (this is only relevant for root object)
|
||||||
for (Mapper mapper : sortedMappers.values()) {
|
for (Mapper mapper : sortedMappers.values()) {
|
||||||
|
|
Loading…
Reference in New Issue