-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add custom serializers for KV reducible maps #68
Comments
This sketch implementation compiles, I haven't checked it yet: package jsonista.jackson;
import java.util.Map;
import java.util.Set;
import clojure.lang.PersistentArrayMap;
import clojure.lang.IKVReduce;
import clojure.lang.IFn;
import clojure.lang.AFn;
import clojure.lang.Util;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.MapSerializer;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import java.io.IOException;
public class PersistentArrayMapSerializer extends MapSerializer {
@SuppressWarnings("unchecked")
protected PersistentArrayMapSerializer
(Set<String> ignoredEntries, Set<String> includedEntries,
JavaType keyType, JavaType valueType, boolean valueTypeIsStatic,
TypeSerializer vts,
JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer)
{
super(ignoredEntries, includedEntries, keyType, valueType, valueTypeIsStatic, vts, keySerializer, valueSerializer);
}
public final JsonSerializer<Object> _findSerializer(SerializerProvider provider,
Object value)
throws JsonMappingException
{
final Class<?> cc = value.getClass();
JsonSerializer<Object> valueSer = _dynamicValueSerializers.serializerFor(cc);
if (valueSer != null) {
return valueSer;
}
if (_valueType.hasGenericTypes()) {
return _findAndAddDynamic(_dynamicValueSerializers,
provider.constructSpecializedType(_valueType, cc), provider);
}
return _findAndAddDynamic(_dynamicValueSerializers, cc, provider);
}
@Override
public void serializeFields(Map<?,?> m, JsonGenerator gen, SerializerProvider provider)
throws IOException
{
final IKVReduce value = (IKVReduce) m;
// If value type needs polymorphic type handling, some more work needed:
if (_valueTypeSerializer != null) {
serializeTypedFields(m, gen, provider, null);
return;
}
final JsonSerializer<Object> keySerializer = _keySerializer;
Object keyElem = null;
try {
value.kvreduce(new AFn ()
{
public Object invoke(Object init, Object keyElem, Object valueElem) {
try
{
// First, serialize key
if (keyElem == null) {
provider.findNullKeySerializer(_keyType, _property).serialize(null, gen, provider);
} else {
// One twist: is entry ignorable? If so, skip
if ((_inclusionChecker != null) && _inclusionChecker.shouldIgnore(keyElem)) {
return null;
}
keySerializer.serialize(keyElem, gen, provider);
}
// And then value
if (valueElem == null) {
provider.defaultSerializeNull(gen);
return null;
}
JsonSerializer<Object> serializer = _valueSerializer;
if (serializer == null) {
serializer = _findSerializer(provider, valueElem);
}
serializer.serialize(valueElem, gen, provider);
return null;
}
catch (Exception e) {throw Util.sneakyThrow(e);}
}
},
null);
}
catch (Exception e) { // Add reference information
wrapAndThrow(provider, e, m, String.valueOf(keyElem));
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently, jsonista uses the default Map serializer which iterates over map entries, causing an allocation of an entry each iteration.
Using the kv reduce API should be faster.
The text was updated successfully, but these errors were encountered: