PERFORMANCE: Remove SymbolBiValue

Fixes #8189
This commit is contained in:
Armin 2017-09-08 23:14:12 +02:00 committed by Armin Braun
parent a252ec6178
commit baf1c8f03d
9 changed files with 32 additions and 61 deletions

View file

@ -6,6 +6,7 @@ import org.jruby.RubyBoolean;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.logstash.bivalues.BiValue;
import org.logstash.bivalues.BiValues;
import org.logstash.ext.JrubyTimestampExtLibrary;
@ -57,9 +58,10 @@ public final class Javafier {
converters.put(Integer.class, Valuefier.IDENTITY);
converters.put(Boolean.class, Valuefier.IDENTITY);
converters.put(Timestamp.class, Valuefier.IDENTITY);
// Explicitly casting to RubyString when we know it's a RubyString for sure is faster
// Explicitly casting to RubyString or RubySymbol when we know its type for sure is faster
// than having the JVM look up the type.
converters.put(RubyString.class, value -> ((RubyString) value).toString());
converters.put(RubySymbol.class, value -> ((RubySymbol) value).toString());
converters.put(RubyBoolean.class, value -> ((RubyBoolean) value).isTrue());
converters.put(BiValue.class, value -> ((BiValue<?, ?>) value).javaValue());
converters.put(RubyFixnum.class, value -> ((RubyFixnum) value).getLongValue());

View file

@ -14,12 +14,14 @@ import org.jruby.RubyBoolean;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
public final class ObjectMappers {
private static final SimpleModule RUBY_SERIALIZERS =
new SimpleModule("RubySerializers")
.addSerializer(RubyString.class, new RubyStringSerializer())
.addSerializer(RubySymbol.class, new RubySymbolSerializer())
.addSerializer(RubyFloat.class, new RubyFloatSerializer())
.addSerializer(RubyBoolean.class, new RubyBooleanSerializer())
.addSerializer(RubyFixnum.class, new RubyFixnumSerializer());
@ -59,6 +61,25 @@ public final class ObjectMappers {
}
}
/**
* Serializer for {@link RubySymbol} since Jackson can't handle that type natively, so we
* simply serialize it as if it were a {@link String}.
*/
private static final class RubySymbolSerializer
extends NonTypedScalarSerializerBase<RubySymbol> {
RubySymbolSerializer() {
super(RubySymbol.class, true);
}
@Override
public void serialize(final RubySymbol value, final JsonGenerator generator,
final SerializerProvider provider)
throws IOException {
generator.writeString(value.asJavaString());
}
}
/**
* Serializer for {@link RubyFloat} since Jackson can't handle that type natively, so we
* simply serialize it as if it were a {@code double}.

View file

@ -10,6 +10,7 @@ import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.runtime.builtin.IRubyObject;
import org.logstash.bivalues.BiValue;
import org.logstash.bivalues.BiValues;
@ -74,6 +75,7 @@ public final class Rubyfier {
final Map<Class<?>, Rubyfier.Converter> converters =
new ConcurrentHashMap<>(50, 0.2F, 1);
converters.put(RubyString.class, IDENTITY);
converters.put(RubySymbol.class, IDENTITY);
converters.put(RubyFloat.class, IDENTITY);
converters.put(RubyFixnum.class, IDENTITY);
converters.put(RubyBoolean.class, IDENTITY);

View file

@ -11,6 +11,7 @@ import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.RubyTime;
import org.jruby.java.proxies.ArrayJavaProxy;
import org.jruby.java.proxies.ConcreteJavaProxy;
@ -99,6 +100,7 @@ public final class Valuefier {
final Map<Class<?>, Valuefier.Converter> converters =
new ConcurrentHashMap<>(50, 0.2F, 1);
converters.put(RubyString.class, IDENTITY);
converters.put(RubySymbol.class, IDENTITY);
converters.put(RubyFixnum.class, IDENTITY);
converters.put(JrubyTimestampExtLibrary.RubyTimestamp.class, IDENTITY);
converters.put(RubyFloat.class, IDENTITY);

View file

@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.Map;
import org.jruby.RubyBignum;
import org.jruby.RubyNil;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.jruby.java.proxies.ConcreteJavaProxy;
import org.jruby.java.proxies.JavaProxy;
@ -46,7 +45,6 @@ public final class BiValues {
hm.put(BigInteger.class, value -> new BigIntegerBiValue((BigInteger) value));
hm.put(RubyBignum.class, value -> new BigIntegerBiValue((RubyBignum) value));
hm.put(RubyNil.class, value -> NULL_BI_VALUE);
hm.put(RubySymbol.class, value -> new SymbolBiValue((RubySymbol) value));
hm.put(RubyBigDecimal.class, value -> new BigDecimalBiValue((RubyBigDecimal) value));
hm.put(ConcreteJavaProxy.class, value -> {
if (value instanceof JavaProxy) {

View file

@ -1,35 +0,0 @@
package org.logstash.bivalues;
import org.jruby.Ruby;
import org.jruby.RubySymbol;
import java.io.ObjectStreamException;
public class SymbolBiValue extends BiValue<RubySymbol, String> {
public SymbolBiValue(RubySymbol rubyValue) {
this.rubyValue = rubyValue;
javaValue = null;
}
public SymbolBiValue(String javaValue) {
this.javaValue = javaValue;
rubyValue = null;
}
private SymbolBiValue() {
}
protected void addRuby(Ruby runtime) {
rubyValue = RubySymbol.newSymbol(runtime, javaValue);
}
protected void addJava() {
javaValue = rubyValue.asJavaString();
}
// Called when object is to be serialized on a stream to allow the object to substitute a proxy for itself.
private Object writeReplace() throws ObjectStreamException {
return newProxy(this);
}
}

View file

@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jruby.RubySymbol;
import org.jruby.RubyTime;
import org.junit.Test;
@ -22,11 +23,14 @@ public final class EventTest {
e.setField("bar", 42);
Map<String, Object> inner = new HashMap<>(2);
inner.put("innerFoo", 42L);
final RubySymbol symbol = RubyUtil.RUBY.newSymbol("val");
e.setField("symbol", symbol);
inner.put("innerQuux", 42.42);
e.setField("baz", inner);
e.setField("[@metadata][foo]", 42L);
byte[] binary = e.serialize();
Event er = Event.deserialize(binary);
assertEquals(symbol.toString(), er.getField("symbol"));
assertEquals(42L, er.getField("foo"));
assertEquals(42L, er.getField("bar"));
assertEquals(42L, er.getField("[baz][innerFoo]"));

View file

@ -7,7 +7,6 @@ import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.jruby.RubyBignum;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.junit.Test;
import org.logstash.TestBase;
@ -18,15 +17,6 @@ import static org.junit.Assert.assertTrue;
public class BiValueTest extends TestBase {
@Test
public void testSymbolBiValueFromRuby() {
String s = "foo";
SymbolBiValue subject = new SymbolBiValue(RubySymbol.newSymbol(ruby, s));
assertTrue(subject.hasRubyValue());
assertFalse(subject.hasJavaValue());
assertEquals(s, subject.javaValue());
}
@Test
public void testBigDecimalBiValueFromRuby() {
BigDecimal s = BigDecimal.valueOf(12345.678D);

View file

@ -4,7 +4,6 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import org.jruby.RubyBignum;
import org.jruby.RubyNil;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.junit.Test;
import org.logstash.TestBase;
@ -14,18 +13,6 @@ import static org.junit.Assert.assertNull;
public class BiValuesTest extends TestBase {
@Test
public void testBiValuesSymbolRuby() {
String js = "double";
RubySymbol rs = RubySymbol.newSymbol(ruby, js);
BiValue subject = BiValues.newBiValue(rs);
assertEquals(rs, subject.rubyValueUnconverted());
assertEquals(rs.getClass(), subject.rubyValue(ruby).getClass());
assertEquals(js, subject.javaValue());
assertEquals(String.class, subject.javaValue().getClass());
}
@Test
public void testBiValuesBigDecimalRuby() {
BigDecimal jo = BigDecimal.valueOf(12345.678D);