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

View File

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

View File

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

View File

@ -31,8 +31,32 @@ import java.util.*;
*/ */
public class XContentMapConverter { 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 { 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(); XContentParser.Token t = parser.currentToken();
if (t == null) { if (t == null) {
t = parser.nextToken(); t = parser.nextToken();
@ -45,21 +69,21 @@ public class XContentMapConverter {
String fieldName = parser.currentName(); String fieldName = parser.currentName();
// And then the value... // And then the value...
t = parser.nextToken(); t = parser.nextToken();
Object value = readValue(parser, t); Object value = readValue(parser, mapFactory, t);
map.put(fieldName, value); map.put(fieldName, value);
} }
return map; 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>(); ArrayList<Object> list = new ArrayList<Object>();
while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) { while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
list.add(readValue(parser, t)); list.add(readValue(parser, mapFactory, t));
} }
return list; 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) { if (t == XContentParser.Token.VALUE_NULL) {
return null; return null;
} else if (t == XContentParser.Token.VALUE_STRING) { } else if (t == XContentParser.Token.VALUE_STRING) {
@ -78,9 +102,9 @@ public class XContentMapConverter {
} else if (t == XContentParser.Token.VALUE_BOOLEAN) { } else if (t == XContentParser.Token.VALUE_BOOLEAN) {
return parser.booleanValue(); return parser.booleanValue();
} else if (t == XContentParser.Token.START_OBJECT) { } else if (t == XContentParser.Token.START_OBJECT) {
return readMap(parser); return readMap(parser, mapFactory);
} else if (t == XContentParser.Token.START_ARRAY) { } else if (t == XContentParser.Token.START_ARRAY) {
return readList(parser, t); return readList(parser, mapFactory, t);
} }
return null; return null;
} }