8000 vpack: performance · anderick/arangodb-java-driver@46ed9a2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 46ed9a2

Browse files
author
Mark
committed
vpack: performance
1 parent 8474c20 commit 46ed9a2

File tree

2 files changed

+69
-50
lines changed

2 files changed

+69
-50
lines changed

src/main/java/com/arangodb/velocypack/VPack.java

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import java.lang.reflect.Array;
44
import java.lang.reflect.Field;
55
import java.lang.reflect.InvocationTargetException;
6-
import java.lang.reflect.ParameterizedType;
7-
import java.lang.reflect.Type;
86
import java.math.BigDecimal;
97
import java.math.BigInteger;
108
import java.util.ArrayList;
@@ -215,26 +213,12 @@ private void deserializeField(final VPackSlice vpack, final Object entity, final
215213
final VPackSlice attr = new VPackSlice(vpack.getVpack(), vpack.getStart() + vpack.getByteSize());
216214
if (!attr.isNone()) {
217215
final Field field = fieldInfo.getField();
218-
final Object value = getValue(attr, field, field.getType());
216+
final Object value = getValue(attr, field.getType(), fieldInfo);
219217
field.set(entity, value);
220218
}
221219
}
222220

223-
private Class<?> getComponentType(final Field field, final Class<?> type, final int i) {
224-
Class<?> result;
225-
final Class<?> componentType = type.getComponentType();
226-
if (componentType != null) {
227-
result = componentType;
228-
} else {
229-
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
230-
final Type argType = genericType.getActualTypeArguments()[i];
231-
result = (Class<?>) (ParameterizedType.class.isAssignableFrom(argType.getClass())
232-
? ParameterizedType.class.cast(argType).getRawType() : argType);
233-
}
234-
return result;
235-
}
236-
237-
private <T> Object getValue(final VPackSlice vpack, final Field field, final Class<T> type)
221+
private <T> Object getValue(final VPackSlice vpack, final Class<T> type, final FieldInfo fieldInfo)
238222
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
239223
VPackException {
240224
final Object value;
@@ -245,64 +229,68 @@ private <T> Object getValue(final VPackSlice vpack, final Field field, final Cla
245229
if (deserializer != null) {
246230
value = ((VPackDeserializer<Object>) deserializer).deserialize(vpack, deserializationContext);
247231
} else if (type.isArray()) {
248-
value = deserializeArray(vpack, field, type);
232+
value = deserializeArray(vpack, type, fieldInfo);
249233
} else if (type.isEnum()) {
250234
value = Enum.valueOf((Class<? extends Enum>) type, vpack.getAsString());
251235
} else if (Collection.class.isAssignableFrom(type)) {
252-
value = deserializeCollection(vpack, field, type);
236+
value = deserializeCollection(vpack, type, fieldInfo);
253237
} else if (Map.class.isAssignableFrom(type)) {
254-
value = deserializeMap(vpack, field, type);
238+
value = deserializeMap(vpack, type, fieldInfo);
255239
} else {
256240
value = deserializeObject(vpack, type);
257241
}
258242
}
259243
return value;
260244
}
261245

262-
private <T> Object deserializeArray(final VPackSlice vpack, final Field field, final Class<T> type)
246+
private <T> Object deserializeArray(final VPackSlice vpack, final Class<T> type, final FieldInfo fieldInfo)
263247
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
264-
ArrayIndexOutOfBoundsException, IllegalArgumentException, VPackException {
248+
VPackException {
265249
final int length = (int) vpack.getLength();
266-
final Class<?> componentType = getComponentType(field, type, 0);
250+
final Class<?> componentType = fieldInfo != null ? fieldInfo.getParameterizedTypes()[0]
251+
: type.getComponentType();
267252
final Object value = Array.newInstance(componentType, length);
268253
for (int i = 0; i < length; i++) {
269-
Array.set(value, i, getValue(vpack.at(i), null, componentType));
254+
Array.set(value, i, getValue(vpack.at(i), componentType, null));
270255
}
271256
return value;
272257
}
273258

274-
private <T> Object deserializeCollection(final VPackSlice vpack, final Field field, final Class<T> type)
259+
private <T> Object deserializeCollection(final VPackSlice vpack, final Class<T> type, final FieldInfo fieldInfo)
275260
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
276261
VPackException {
277262
final Collection value = (Collection) createInstance(type);
278263
final long length = vpack.getLength();
279264
if (length > 0) {
280-
final Class<?> componentType = getComponentType(field, type, 0);
265+
final Class<?> componentType = fieldInfo.getParameterizedTypes()[0];
281266
for (int i = 0; i < length; i++) {
282-
value.add(getValue(vpack.at(i), null, componentType));
267+
value.add(getValue(vpack.at(i), componentType, null));
283268
}
284269
}
285270
return value;
286271
}
287272

288-
private <T> Object deserializeMap(final VPackSlice vpack, final Field field, final Class<T> type)
273+
private <T> Object deserializeMap(final VPackSlice vpack, final Class<T> type, final FieldInfo fieldInfo)
289274
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
290275
VPackException {
291276
final int length = (int) vpack.getLength();
292277
final Map value = (Map) createInstance(type);
293278
if (length > 0) {
294-
final Class<?> keyType = getComponentType(field, type, 0);
295-
final Class<?> valueType = getComponentType(field, type, 1);
279+
final Class<?>[] parameterizedTypes = fieldInfo.getParameterizedTypes();
280+
final Class<?> keyType = parameterizedTypes[0];
281+
final Class<?> valueType = parameterizedTypes[1];
296282
if (isStringableKeyType(keyType)) {
297-
for (int i = 0; i < vpack.getLength(); i++) {
298-
value.put(getKeyfromString(vpack.keyAt(i).makeKey().getAsString(), keyType),
299-
getValue(vpack.valueAt(i), null, valueType));
283+
for (final Iterator<VPackSlice> iterator = vpack.iterator(); iterator.hasNext();) {
284+
final VPackSlice key = iterator.next();
285+
final VPackSlice valueAt = new VPackSlice(key.getVpack(), key.getStart() + key.getByteSize());
286+
value.put(getKeyfromString(key.makeKey().getAsString(), keyType),
287+
getValue(valueAt, valueType, null));
300288
}
301289
} else {
302290
for (int i = 0; i < vpack.getLength(); i++) {
303291
final VPackSlice entry = vpack.at(i);
304-
final Object mapKey = getValue(entry.get(ATTR_KEY), null, keyType);
305-
final Object mapValue = getValue(entry.get(ATTR_VALUE), null, valueType);
292+
final Object mapKey = getValue(entry.get(ATTR_KEY), keyType, null);
293+
final Object mapValue = getValue(entry.get(ATTR_VALUE), valueType, null);
306294
value.put(mapKey, mapValue);
307295
}
308296
}
@@ -381,15 +369,16 @@ private void serializeField(final Object entity, final VPackBuilder builder, fin
381369
final Field field = fieldInfo.getField();
382370
final Class<?> type = field.getType();
383371
final Object value = field.get(entity);
384-
addValue(field, fieldName, type, value, builder);
372+
addValue(field, fieldName, type, value, builder, fieldInfo);
385373
}
386374

387375
private void addValue(
388376
final Field field,
389377
final String name,
390378
final Class<?> type,
391379
final Object value,
392-
final VPackBuilder builder)
380+
final VPackBuilder builder,
381+
final FieldInfo fieldInfo)
393382
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, VPackException {
394383

395384
if (value == null) {
@@ -405,7 +394,7 @@ private void addValue(
405394
} else if (Iterable.class.isAssignableFrom(type)) {
406395
serializeIterable(name, value, builder);
407396
} else if (Map.class.isAssignableFrom(type)) {
408-
serializeMap(field, name, type, value, builder);
397+
serializeMap(name, type, value, builder, fieldInfo);
409398
} else {
410399
serializeObject(name, value, builder);
411400
}
@@ -418,7 +407,7 @@ private void serializeArray(final String name, final Object value, final VPackBu
418407
builder.add(name, new Value(ValueType.ARRAY));
419408
for (int i = 0; i < Array.getLength(value); i++) {
420409
final Object element = Array.get(value, i);
421-
addValue(null, null, element.getClass(), element, builder);
410+
addValue(null, null, element.getClass(), element, builder, null);
422411
}
423412
builder.close();
424413
}
@@ -428,35 +417,36 @@ private void serializeIterable(final String name, final Object value, final VPac
428417
builder.add(name, new Value(ValueType.ARRAY));
429418
for (final Iterator iterator = Iterable.class.cast(value).iterator(); iterator.hasNext();) {
430419
final Object element = iterator.next();
431-
addValue(null, null, element.getClass(), element, builder);
420+
addValue(null, null, element.getClass(), element, builder, null);
432421
}
433422
builder.close();
434423
}
435424

436425
private void serializeMap(
437-
final Field field,
438426
final String name,
439427
final Class<?> type,
440428
final Object value,
441-
final VPackBuilder builder)
429+
final VPackBuilder builder,
430+
final FieldInfo fieldInfo)
442431
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, VPackException {
443432
final Map map = Map.class.cast(value);
444433
if (map.size() > 0) {
445-
final Class<?> keyType = getComponentType(field, type, 0);
434+
final Class<?> keyType = fieldInfo.getParameterizedTypes()[0];
446435
if (isStringableKeyType(keyType)) {
447436
builder.add(name, new Value(ValueType.OBJECT));
448437
final Set<Entry<?, ?>> entrySet = map.entrySet();
449438
for (final Entry<?, ?> entry : entrySet) {
450-
addValue(null, keyToString(entry.getKey()), entry.getValue().getClass(), entry.getValue(), builder);
439+
addValue(null, keyToString(entry.getKey()), entry.getValue().getClass(), entry.getValue(), builder,
440+
null);
451441
}
452442
builder.close();
453443
} else {
454444
builder.add(name, new Value(ValueType.ARRAY));
455445
final Set<Entry<?, ?>> entrySet = map.entrySet();
456446
for (final Entry<?, ?> entry : entrySet) {
457447
builder.add(null, new Value(ValueType.OBJECT));
458-
addValue(null, ATTR_KEY, entry.getKey().getClass(), entry.getKey(), builder);
459-
addValue(null, ATTR_VALUE, entry.getValue().getClass(), entry.getValue(), builder);
448+
addValue(null, ATTR_KEY, entry.getKey().getClass(), entry.getKey(), builder, null);
449+
addValue(null, ATTR_VALUE, entry.getValue().getClass(), entry.getValue(), builder, null);
460450
builder.close();
461451
}
462452
builder.close();

src/main/java/com/arangodb/velocypack/internal/VPackCache.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import java.lang.reflect.Field;
44
import java.lang.reflect.Modifier;
5+
import java.lang.reflect.ParameterizedType;
6+
import java.lang.reflect.Type;
57
import java.util.ArrayList;
8+
import java.util.Collection;
69
import java.util.Collections;
710
import java.util.Comparator;
811
import java.util.HashMap;
@@ -27,14 +30,16 @@ public static class FieldInfo {
2730
private final Field field;
2831
private final boolean serialize;
2932
private final boolean deserialize;
33+
private final Class<?>[] parameterizedTypes;
3034

31-
private FieldInfo(final String fieldName, final Field field, final boolean serialize,
32-
final boolean deserialize) {
35+
private FieldInfo(final String fieldName, final Field field, final boolean serialize, final boolean deserialize,
36+
final Class<?>[] parameterizedTypes) {
3337
super();
3438
this.fieldName = fieldName;
3539
this.field = field;
3640
this.serialize = serialize;
3741
this.deserialize = deserialize;
42+
this.parameterizedTypes = parameterizedTypes;
3843
}
3944

4045
public String getFieldName() {
@@ -52,6 +57,10 @@ public boolean isSerialize() {
5257
public boolean isDeserialize() {
5358
return deserialize;
5459
}
60+
61+
public Class<?>[] getParameterizedTypes() {
62+
return parameterizedTypes;
63+
}
5564
}
5665

5766
private final Map<Class<?>, Map<String, FieldInfo>> cache;
@@ -110,7 +119,27 @@ private FieldInfo createFieldInfo(final Field field) {
110119
final Expose expose = field.getAnnotation(Expose.class);
111120
final boolean serialize = expose != null ? expose.serialize() : true;
112121
final boolean deserialize = expose != null ? expose.deserialize() : true;
113-
return new FieldInfo(fieldName, field, serialize, deserialize);
122+
final Class<?> type = field.getType();
123+
Class<?>[] parameterizedTypes = null;
124+
if (type.isArray()) {
125+
parameterizedTypes = new Class<?>[] { type.getComponentType() };
126+
} else if (Collection.class.isAssignableFrom(type)) {
127+
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
128+
final Type argType = genericType.getActualTypeArguments()[0];
129+
parameterizedTypes = new Class<?>[] {
130+
(Class<?>) (ParameterizedType.class.isAssignableFrom(argType.getClass())
131+
? ParameterizedType.class.cast(argType).getRawType() : argType) };
132+
} else if (Map.class.isAssignableFrom(type)) {
133+
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
134+
final Type argKeyType = genericType.getActualTypeArguments()[0];
135+
final Class<?> key = (Class<?>) (ParameterizedType.class.isAssignableFrom(argKeyType.getClass())
136+
? ParameterizedType.class.cast(argKeyType).getRawType() : argKeyType);
137+
final Type argValueType = genericType.getActualTypeArguments()[1];
138+
final Class<?> value = (Class<?>) (ParameterizedType.class.isAssignableFrom(argValueType.getClass())
139+
? ParameterizedType.class.cast(argValueType).getRawType() : argValueType);
140+
parameterizedTypes = new Class<?>[] { key, value };
141+
}
142+
return new FieldInfo(fieldName, field, serialize, deserialize, parameterizedTypes);
114143
}
115144

116145
}

0 commit comments

Comments
 (0)
0