PERFORMANCE: Removed DoubleBiValue and FloatBiValue

Fixes #7917
This commit is contained in:
Armin 2017-08-05 00:04:35 +02:00 committed by Armin Braun
parent 8153411c15
commit e48dc93df9
9 changed files with 40 additions and 150 deletions

View file

@ -1,6 +1,7 @@
package org.logstash;
import org.jruby.RubyFloat;
import org.jruby.RubyString;
import org.logstash.bivalues.BiValue;
import org.logstash.bivalues.BiValues;
@ -19,9 +20,12 @@ public class Javafier {
if (o instanceof RubyString) {
return o.toString();
}
if (o instanceof String) {
if (o instanceof String || o instanceof Float || o instanceof Double) {
return o;
}
if (o instanceof RubyFloat) {
return ((RubyFloat) o).getDoubleValue();
}
if (o instanceof BiValue) {
return ((BiValue)o).javaValue();
} else if(o instanceof ConvertedMap) {

View file

@ -9,20 +9,22 @@ import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import java.io.IOException;
import org.jruby.RubyFloat;
import org.jruby.RubyString;
public final class ObjectMappers {
private static final SimpleModule RUBY_STRING_SERIALIZER =
private static final SimpleModule RUBY_SERIALIZERS =
new SimpleModule("RubyStringSerializer")
.addSerializer(RubyString.class, new RubyStringSerializer());
.addSerializer(RubyString.class, new RubyStringSerializer())
.addSerializer(RubyFloat.class, new RubyFloatSerializer());
public static final ObjectMapper JSON_MAPPER = new ObjectMapper()
.registerModule(new AfterburnerModule()).registerModule(RUBY_STRING_SERIALIZER);
.registerModule(new AfterburnerModule()).registerModule(RUBY_SERIALIZERS);
public static final ObjectMapper CBOR_MAPPER = new ObjectMapper(
new CBORFactory().configure(CBORGenerator.Feature.WRITE_MINIMAL_INTS, false)
).registerModule(new AfterburnerModule()).registerModule(RUBY_STRING_SERIALIZER);
).registerModule(new AfterburnerModule()).registerModule(RUBY_SERIALIZERS);
private ObjectMappers() {
}
@ -44,6 +46,23 @@ public final class ObjectMappers {
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}.
*/
private static final class RubyFloatSerializer
extends NonTypedScalarSerializerBase<RubyFloat> {
RubyFloatSerializer() {
super(RubyFloat.class, true);
}
@Override
public void serialize(final RubyFloat value, final JsonGenerator generator,
final SerializerProvider provider) throws IOException {
generator.writeNumber(value.getDoubleValue());
}
}
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.runtime.builtin.IRubyObject;
@ -28,6 +29,10 @@ public final class Rubyfier {
public static IRubyObject deep(Ruby runtime, final Object input) {
if (input instanceof RubyString) return (RubyString) input;
if (input instanceof String) return BiValues.RUBY.newString((String) input);
if (input instanceof RubyFloat) return (RubyFloat) input;
if (input instanceof Double || input instanceof Float) {
return BiValues.RUBY.newFloat(((Number) input).doubleValue());
}
if (input instanceof BiValue) return ((BiValue) input).rubyValue(runtime);
if (input instanceof Map) return deepMap(runtime, (Map) input);
if (input instanceof List) return deepList(runtime, (List) input);

View file

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import org.joda.time.DateTime;
import org.jruby.RubyArray;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.RubyTime;
@ -59,6 +60,12 @@ public class Valuefier {
if (o instanceof String) {
return BiValues.RUBY.newString((String) o);
}
if (o instanceof RubyFloat) {
return o;
}
if (o instanceof Float || o instanceof Double) {
return BiValues.RUBY.newFloat(((Number) o).doubleValue());
}
if (o instanceof ConvertedMap || o instanceof ConvertedList) {
return o;
}

View file

@ -6,7 +6,6 @@ import java.util.HashMap;
import org.jruby.Ruby;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
import org.jruby.RubyFloat;
import org.jruby.RubyInteger;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
@ -19,8 +18,6 @@ public enum BiValues {
ORG_LOGSTASH_EXT_JRUBYTIMESTAMPEXTLIBRARY$RUBYTIMESTAMP(BiValueType.TIMESTAMP),
ORG_LOGSTASH_TIMESTAMP(BiValueType.TIMESTAMP),
JAVA_LANG_BOOLEAN(BiValueType.BOOLEAN),
JAVA_LANG_DOUBLE(BiValueType.DOUBLE),
JAVA_LANG_FLOAT(BiValueType.FLOAT),
JAVA_LANG_INTEGER(BiValueType.INT),
JAVA_LANG_LONG(BiValueType.LONG),
JAVA_MATH_BIGDECIMAL(BiValueType.DECIMAL),
@ -32,7 +29,6 @@ public enum BiValues {
ORG_JRUBY_RUBYBOOLEAN$TRUE(BiValueType.BOOLEAN),
ORG_JRUBY_RUBYBOOLEAN(BiValueType.BOOLEAN),
ORG_JRUBY_RUBYFIXNUM(BiValueType.LONG),
ORG_JRUBY_RUBYFLOAT(BiValueType.DOUBLE),
ORG_JRUBY_RUBYINTEGER(BiValueType.LONG),
ORG_JRUBY_RUBYNIL(BiValueType.NULL),
ORG_JRUBY_RUBYSYMBOL(BiValueType.SYMBOL), // one way conversion, a Java string will use STRING
@ -43,11 +39,8 @@ public enum BiValues {
hm.put("org.logstash.Timestamp", "ORG_LOGSTASH_TIMESTAMP");
hm.put("org.logstash.ext.JrubyTimestampExtLibrary$RubyTimestamp", "ORG_LOGSTASH_EXT_JRUBYTIMESTAMPEXTLIBRARY$RUBYTIMESTAMP");
hm.put("java.lang.Boolean", "JAVA_LANG_BOOLEAN");
hm.put("java.lang.Double", "JAVA_LANG_DOUBLE");
hm.put("java.lang.Float", "JAVA_LANG_FLOAT");
hm.put("java.lang.Integer", "JAVA_LANG_INTEGER");
hm.put("java.lang.Long", "JAVA_LANG_LONG");
hm.put("java.lang.String", "JAVA_LANG_STRING");
hm.put("java.math.BigDecimal", "JAVA_MATH_BIGDECIMAL");
hm.put("java.math.BigInteger", "JAVA_MATH_BIGINTEGER");
hm.put("org.jruby.RubyBignum", "ORG_JRUBY_RUBYBIGNUM");
@ -55,10 +48,8 @@ public enum BiValues {
hm.put("org.jruby.RubyBoolean$False", "ORG_JRUBY_RUBYBOOLEAN$FALSE");
hm.put("org.jruby.RubyBoolean$True", "ORG_JRUBY_RUBYBOOLEAN$TRUE");
hm.put("org.jruby.RubyFixnum", "ORG_JRUBY_RUBYFIXNUM");
hm.put("org.jruby.RubyFloat", "ORG_JRUBY_RUBYFLOAT");
hm.put("org.jruby.RubyInteger", "ORG_JRUBY_RUBYINTEGER");
hm.put("org.jruby.RubyNil", "ORG_JRUBY_RUBYNIL");
hm.put("org.jruby.RubyString", "ORG_JRUBY_RUBYSTRING");
hm.put("org.jruby.RubySymbol", "ORG_JRUBY_RUBYSYMBOL");
hm.put("org.jruby.ext.bigdecimal.RubyBigDecimal", "ORG_JRUBY_EXT_BIGDECIMAL_RUBYBIGDECIMAL");
hm.put("org.jruby.java.proxies.ConcreteJavaProxy", "ORG_JRUBY_JAVA_PROXIES_CONCRETEJAVAPROXY");
@ -129,22 +120,6 @@ public enum BiValues {
return new IntegerBiValue((Integer) value);
}
},
DOUBLE {
BiValue build(Object value) {
if (value instanceof IRubyObject) {
return new DoubleBiValue((RubyFloat) value);
}
return new DoubleBiValue((Double) value);
}
},
FLOAT {
BiValue build(Object value) {
if (value instanceof IRubyObject) {
return new DoubleBiValue((RubyFloat) value);
}
return new FloatBiValue((Float) value);
}
},
DECIMAL {
BiValue build(Object value) {
if (value instanceof IRubyObject) {

View file

@ -1,36 +0,0 @@
package org.logstash.bivalues;
import org.jruby.Ruby;
import org.jruby.RubyFloat;
import java.io.ObjectStreamException;
public class DoubleBiValue extends BiValue<RubyFloat, Double> {
public DoubleBiValue(RubyFloat rubyValue) {
this.rubyValue = rubyValue;
javaValue = null;
}
public DoubleBiValue(Double javaValue) {
this.javaValue = javaValue;
rubyValue = null;
}
private DoubleBiValue() {
}
protected void addRuby(Ruby runtime) {
rubyValue = RubyFloat.newFloat(runtime, javaValue);
}
protected void addJava() {
javaValue = rubyValue.getDoubleValue();
}
// 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

@ -1,40 +0,0 @@
package org.logstash.bivalues;
import org.jruby.Ruby;
import org.jruby.RubyFloat;
import java.io.ObjectStreamException;
public class FloatBiValue extends BiValue<RubyFloat, Float> {
public FloatBiValue(RubyFloat rubyValue) {
this.rubyValue = rubyValue;
javaValue = null;
}
public FloatBiValue(Float javaValue) {
this.javaValue = javaValue;
rubyValue = null;
}
private FloatBiValue() {
}
protected void addRuby(Ruby runtime) {
rubyValue = RubyFloat.newFloat(runtime, (double)javaValue);
}
protected void addJava() {
double value = rubyValue.getDoubleValue();
if ((float) value != value) {
throw new ArithmeticException("Float overflow - Incorrect FloatBiValue usage: BiValues should pick DoubleBiValue for RubyFloat");
}
javaValue = (float) value;
}
// 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

@ -9,7 +9,6 @@ import java.math.BigInteger;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyInteger;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
@ -86,24 +85,6 @@ public class BiValueTest extends TestBase {
assertEquals(v, subject.rubyValue(ruby));
}
@Test
public void testDoubleBiValueFromRuby() {
Double s = 12345.678D;
DoubleBiValue subject = new DoubleBiValue(RubyFloat.newFloat(ruby, 12345.678D));
assertTrue(subject.hasRubyValue());
assertFalse(subject.hasJavaValue());
assertEquals(s, subject.javaValue());
}
@Test
public void testDoubleBiValueFromJava() {
RubyFloat v = RubyFloat.newFloat(ruby, 12345.678D);
DoubleBiValue subject = new DoubleBiValue(12345.678D);
assertFalse(subject.hasRubyValue());
assertTrue(subject.hasJavaValue());
assertEquals(v, subject.rubyValue(ruby));
}
@Test
public void testBooleanBiValueFromRuby() {
BooleanBiValue subject = new BooleanBiValue(RubyBoolean.newBoolean(ruby, true));

View file

@ -5,7 +5,6 @@ import java.math.BigInteger;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyInteger;
import org.jruby.RubyNil;
import org.jruby.RubySymbol;
@ -59,30 +58,6 @@ public class BiValuesTest extends TestBase {
assertEquals(ro.getClass(), subject.rubyValue(ruby).getClass());
}
@Test
public void testBiValuesFloatRuby() {
double jo = 1234.567D;
RubyFloat ro = (RubyFloat) JavaUtil.convertJavaToUsableRubyObject(ruby, jo);
BiValue subject = BiValues.newBiValue(ro);
assertEquals(ro, subject.rubyValueUnconverted());
assertEquals(ro.getClass(), subject.rubyValue(ruby).getClass());
assertEquals(jo, subject.javaValue());
assertEquals(Double.class, subject.javaValue().getClass());
}
@Test
public void testBiValuesFloatJava() {
double jo = 1234.567D;
RubyFloat ro = (RubyFloat) JavaUtil.convertJavaToUsableRubyObject(ruby, jo);
BiValue subject = BiValues.newBiValue(jo);
assertEquals(jo, subject.javaValue());
assertEquals(Double.class, subject.javaValue().getClass());
assertEquals(ro, subject.rubyValue(ruby));
assertEquals(ro.getClass(), subject.rubyValue(ruby).getClass());
}
@Test
public void testBiValuesBigDecimalRuby() {
BigDecimal jo = BigDecimal.valueOf(12345.678D);