Skip to content

Commit

Permalink
Mappings: Make lookup structures immutable.
Browse files Browse the repository at this point in the history
This commit makes the lookup structures that are used for mappings immutable.
When changes are required, a new instance is created while the current instance
is left unmodified. This is done efficiently thanks to a hash table
implementation based on a array hash trie, see
org.elasticsearch.common.collect.CopyOnWriteHashMap.

ManyMappingsBenchmark returns indexing times that are similar to the ones that
can be observed in current master.

Ultimately, I would like to see if we can make mappings completely immutable as
well and updated atomically. This is not trivial however, eg. because of dynamic
mappings. So here is a first baby step that should help move towards that
direction.

Close #7486
  • Loading branch information
jpountz committed Oct 2, 2014
1 parent 9f8a840 commit 19aa80f
Show file tree
Hide file tree
Showing 19 changed files with 1,138 additions and 551 deletions.
11 changes: 11 additions & 0 deletions pom.xml
Expand Up @@ -260,6 +260,12 @@
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>

<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
Expand Down Expand Up @@ -691,6 +697,7 @@
<include>com.ning:compress-lzf</include>
<include>com.github.spullara.mustache.java:compiler</include>
<include>com.tdunning:t-digest</include>
<include>org.apache.commons:commons-lang3</include>
<include>commons-cli:commons-cli</include>
</includes>
</artifactSet>
Expand Down Expand Up @@ -731,6 +738,10 @@
<pattern>com.tdunning.math.stats</pattern>
<shadedPattern>org.elasticsearch.common.stats</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.lang</pattern>
<shadedPattern>org.elasticsearch.common.lang</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.cli</pattern>
<shadedPattern>org.elasticsearch.common.cli.commons</shadedPattern>
Expand Down
Expand Up @@ -37,6 +37,7 @@
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.mapper.DocumentFieldMappers;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.service.IndexService;
Expand All @@ -48,7 +49,8 @@

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;

/**
* Transport action used to retrieve the mappings related to fields that belong to a specific index
Expand Down Expand Up @@ -175,47 +177,41 @@ public Boolean paramAsBooleanOptional(String key, Boolean defaultValue) {

private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(DocumentMapper documentMapper, GetFieldMappingsIndexRequest request) throws ElasticsearchException {
MapBuilder<String, FieldMappingMetaData> fieldMappings = new MapBuilder<>();
final List<FieldMapper> allFieldMappers = documentMapper.mappers().mappers();
final DocumentFieldMappers allFieldMappers = documentMapper.mappers();
for (String field : request.fields()) {
if (Regex.isMatchAllPattern(field)) {
for (FieldMapper fieldMapper : allFieldMappers) {
for (FieldMapper<?> fieldMapper : allFieldMappers) {
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
}
} else if (Regex.isSimpleMatchPattern(field)) {
// go through the field mappers 3 times, to make sure we give preference to the resolve order: full name, index name, name.
// also make sure we only store each mapper once.
boolean[] resolved = new boolean[allFieldMappers.size()];
for (int i = 0; i < allFieldMappers.size(); i++) {
FieldMapper fieldMapper = allFieldMappers.get(i);
Collection<FieldMapper<?>> remainingFieldMappers = new LinkedList<>(allFieldMappers);
for (Iterator<FieldMapper<?>> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
final FieldMapper<?> fieldMapper = it.next();
if (Regex.simpleMatch(field, fieldMapper.names().fullName())) {
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
resolved[i] = true;
it.remove();
}
}
for (int i = 0; i < allFieldMappers.size(); i++) {
if (resolved[i]) {
continue;
}
FieldMapper fieldMapper = allFieldMappers.get(i);
for (Iterator<FieldMapper<?>> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
final FieldMapper<?> fieldMapper = it.next();
if (Regex.simpleMatch(field, fieldMapper.names().indexName())) {
addFieldMapper(fieldMapper.names().indexName(), fieldMapper, fieldMappings, request.includeDefaults());
resolved[i] = true;
it.remove();
}
}
for (int i = 0; i < allFieldMappers.size(); i++) {
if (resolved[i]) {
continue;
}
FieldMapper fieldMapper = allFieldMappers.get(i);
for (Iterator<FieldMapper<?>> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
final FieldMapper<?> fieldMapper = it.next();
if (Regex.simpleMatch(field, fieldMapper.names().name())) {
addFieldMapper(fieldMapper.names().name(), fieldMapper, fieldMappings, request.includeDefaults());
resolved[i] = true;
it.remove();
}
}

} else {
// not a pattern
FieldMapper fieldMapper = documentMapper.mappers().smartNameFieldMapper(field);
FieldMapper<?> fieldMapper = allFieldMappers.smartNameFieldMapper(field);
if (fieldMapper != null) {
addFieldMapper(field, fieldMapper, fieldMappings, request.includeDefaults());
} else if (request.probablySingleFieldRequest()) {
Expand All @@ -226,7 +222,7 @@ private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(Docum
return fieldMappings.immutableMap();
}

private void addFieldMapper(String field, FieldMapper fieldMapper, MapBuilder<String, FieldMappingMetaData> fieldMappings, boolean includeDefaults) {
private void addFieldMapper(String field, FieldMapper<?> fieldMapper, MapBuilder<String, FieldMappingMetaData> fieldMappings, boolean includeDefaults) {
if (fieldMappings.containsKey(field)) {
return;
}
Expand Down

0 comments on commit 19aa80f

Please sign in to comment.