make sure we keep order in mappings when recovering so there won't be reparsing of the mappings on nodes (introduced with faster recovery work done on gateway)

This commit is contained in:
kimchy 2011-04-20 03:42:51 +03:00
parent af39f07213
commit 3c233347b8
4 changed files with 39 additions and 9 deletions

View File

@ -281,7 +281,7 @@ public class IndexMetaData {
for (Map.Entry<String, MappingMetaData> entry : indexMetaData.mappings().entrySet()) {
byte[] data = entry.getValue().source().uncompressed();
XContentParser parser = XContentFactory.xContent(data).createParser(data);
Map<String, Object> mapping = parser.map();
Map<String, Object> mapping = parser.mapOrdered();
parser.close();
builder.map(mapping);
}
@ -310,7 +310,7 @@ public class IndexMetaData {
builder.settings(settingsBuilder.build());
} else if ("mappings".equals(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
Map<String, Object> mapping = parser.map();
Map<String, Object> mapping = parser.mapOrdered();
if (mapping.size() == 1) {
String mappingType = mapping.keySet().iterator().next();
builder.putMapping(new MappingMetaData(mappingType, mapping));

View File

@ -108,6 +108,8 @@ public interface XContentParser {
Map<String, Object> map() throws IOException;
Map<String, Object> mapOrdered() throws IOException;
Map<String, Object> mapAndClose() throws IOException;
String text() throws IOException;

View File

@ -103,6 +103,10 @@ public abstract class AbstractXContentParser implements XContentParser {
return XContentMapConverter.readMap(this);
}
@Override public Map<String, Object> mapOrdered() throws IOException {
return XContentMapConverter.readOrderedMap(this);
}
@Override public Map<String, Object> mapAndClose() throws IOException {
try {
return map();

View File

@ -31,8 +31,32 @@ import java.util.*;
*/
public class XContentMapConverter {
public static interface MapFactory {
Map<String, Object> newMap();
}
public static final MapFactory SIMPLE_MAP_FACTORY = new MapFactory() {
@Override public Map<String, Object> newMap() {
return new HashMap<String, Object>();
}
};
public static final MapFactory ORDERED_MAP_FACTORY = new MapFactory() {
@Override public Map<String, Object> newMap() {
return new LinkedHashMap<String, Object>();
}
};
public static Map<String, Object> readMap(XContentParser parser) throws IOException {
Map<String, Object> map = new HashMap<String, Object>();
return readMap(parser, SIMPLE_MAP_FACTORY);
}
public static Map<String, Object> readOrderedMap(XContentParser parser) throws IOException {
return readMap(parser, ORDERED_MAP_FACTORY);
}
public static Map<String, Object> readMap(XContentParser parser, MapFactory mapFactory) throws IOException {
Map<String, Object> map = mapFactory.newMap();
XContentParser.Token t = parser.currentToken();
if (t == null) {
t = parser.nextToken();
@ -45,21 +69,21 @@ public class XContentMapConverter {
String fieldName = parser.currentName();
// And then the value...
t = parser.nextToken();
Object value = readValue(parser, t);
Object value = readValue(parser, mapFactory, t);
map.put(fieldName, value);
}
return map;
}
private static List<Object> readList(XContentParser parser, XContentParser.Token t) throws IOException {
private static List<Object> readList(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
ArrayList<Object> list = new ArrayList<Object>();
while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
list.add(readValue(parser, t));
list.add(readValue(parser, mapFactory, t));
}
return list;
}
private static Object readValue(XContentParser parser, XContentParser.Token t) throws IOException {
private static Object readValue(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
if (t == XContentParser.Token.VALUE_NULL) {
return null;
} else if (t == XContentParser.Token.VALUE_STRING) {
@ -78,9 +102,9 @@ public class XContentMapConverter {
} else if (t == XContentParser.Token.VALUE_BOOLEAN) {
return parser.booleanValue();
} else if (t == XContentParser.Token.START_OBJECT) {
return readMap(parser);
return readMap(parser, mapFactory);
} else if (t == XContentParser.Token.START_ARRAY) {
return readList(parser, t);
return readList(parser, mapFactory, t);
}
return null;
}