提交 e7e6a8a9 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add DataUtils.getMapName() as faster alternative to parseMap().get("name")

上级 969f44a9
......@@ -613,6 +613,40 @@ public final class DataUtils {
}
}
/**
* @param buff output buffer, should be empty
* @param s parsed string
* @param i offset to parse from
* @param size stop offset (exclusive)
* @return new offset
*/
private static int parseMapValue(StringBuilder buff, String s, int i, int size) {
while (i < size) {
char c = s.charAt(i++);
if (c == ',') {
break;
} else if (c == '\"') {
while (i < size) {
c = s.charAt(i++);
if (c == '\\') {
if (i == size) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_FILE_CORRUPT,
"Not a map: {0}", s);
}
c = s.charAt(i++);
} else if (c == '\"') {
break;
}
buff.append(c);
}
} else {
buff.append(c);
}
}
return i;
}
/**
* Parse a key-value pair list.
*
......@@ -622,6 +656,7 @@ public final class DataUtils {
*/
public static HashMap<String, String> parseMap(String s) {
HashMap<String, String> map = New.hashMap();
StringBuilder buff = new StringBuilder();
for (int i = 0, size = s.length(); i < size;) {
int startKey = i;
i = s.indexOf(':', i);
......@@ -630,7 +665,33 @@ public final class DataUtils {
DataUtils.ERROR_FILE_CORRUPT, "Not a map: {0}", s);
}
String key = s.substring(startKey, i++);
i = parseMapValue(buff, s, i, size);
map.put(key, buff.toString());
buff.setLength(0);
}
return map;
}
/**
* Parse a name from key-value pair list.
*
* @param s the list
* @return value of name item, or {@code null}
* @throws IllegalStateException if parsing failed
*/
public static String getMapName(String s) {
for (int i = 0, size = s.length(); i < size;) {
int startKey = i;
i = s.indexOf(':', i);
if (i < 0) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_FILE_CORRUPT, "Not a map: {0}", s);
}
if (i++ - startKey == 4 && s.regionMatches(startKey, "name", 0, 4)) {
StringBuilder buff = new StringBuilder();
i = parseMapValue(buff, s, i, size);
return buff.toString();
} else {
while (i < size) {
char c = s.charAt(i++);
if (c == ',') {
......@@ -648,15 +709,12 @@ public final class DataUtils {
} else if (c == '\"') {
break;
}
buff.append(c);
}
} else {
buff.append(c);
}
}
map.put(key, buff.toString());
}
return map;
}
return null;
}
/**
......
......@@ -2462,7 +2462,7 @@ public final class MVStore {
public synchronized String getMapName(int id) {
checkOpen();
String m = meta.get(MVMap.getMapKey(id));
return m == null ? null : DataUtils.parseMap(m).get("name");
return m == null ? null : DataUtils.getMapName(m);
}
/**
......
......@@ -99,16 +99,34 @@ public class TestDataUtils extends TestBase {
DataUtils.appendMap(buff, "c", "1,2");
DataUtils.appendMap(buff, "d", "\"test\"");
DataUtils.appendMap(buff, "e", "}");
assertEquals(":,a:1,b:\",\",c:\"1,2\",d:\"\\\"test\\\"\",e:}", buff.toString());
DataUtils.appendMap(buff, "name", "1:1\",");
String encoded = buff.toString();
assertEquals(":,a:1,b:\",\",c:\"1,2\",d:\"\\\"test\\\"\",e:},name:\"1:1\\\",\"", encoded);
HashMap<String, String> m = DataUtils.parseMap(buff.toString());
assertEquals(6, m.size());
HashMap<String, String> m = DataUtils.parseMap(encoded);
assertEquals(7, m.size());
assertEquals("", m.get(""));
assertEquals("1", m.get("a"));
assertEquals(",", m.get("b"));
assertEquals("1,2", m.get("c"));
assertEquals("\"test\"", m.get("d"));
assertEquals("}", m.get("e"));
assertEquals("1:1\",", m.get("name"));
assertEquals("1:1\",", DataUtils.getMapName(encoded));
buff.setLength(0);
DataUtils.appendMap(buff, "1", "1");
DataUtils.appendMap(buff, "name", "2");
DataUtils.appendMap(buff, "3", "3");
encoded = buff.toString();
assertEquals("2", DataUtils.parseMap(encoded).get("name"));
assertEquals("2", DataUtils.getMapName(encoded));
buff.setLength(0);
DataUtils.appendMap(buff, "name", "xx");
encoded = buff.toString();
assertEquals("xx", DataUtils.parseMap(encoded).get("name"));
assertEquals("xx", DataUtils.getMapName(encoded));
}
private void testMapRandomized() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论