-
Notifications
You must be signed in to change notification settings - Fork 13.9k
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
KAFKA-4769: Add Float serializer, deserializer, serde #2554
Conversation
Please review any of @guozhangwang @enothereska @dguy @mjsax |
deserializer.close(); | ||
} | ||
|
||
@Test(expected = SerializationException.class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These exception-related tests are missing for most of the existing serdes, but I decided to add them after inspecting the results of the code coverage report.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then, would it better to add exception-related tests to the other SerDe
s also? How do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO out of scope for this PR, which is adding Float support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree. It would be much better for me to do the following work.
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
@@ -111,6 +117,10 @@ public ByteArraySerde() { | |||
return (Serde<T>) Long(); | |||
} | |||
|
|||
if (Float.class.isAssignableFrom(type)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a question: Would type instanceof Float
be better? Or, you decided to use Class#isAssignableFrom
method for consistency only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, note that type
is a Class<T>
-- a check with instanceof
would not work because it requires an instance of a class, whereas serdeFrom(Class<T> type)
means we must work with a class object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha! Understood. Thanks for your answer! 😄
Refer to this link for build results (access rights to CI server needed): |
LGTM |
@@ -119,6 +120,49 @@ public void testLongSerializer() { | |||
} | |||
|
|||
@Test | |||
public void testFloatSerializer() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldSerializeDeserializeFloat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -119,6 +120,49 @@ public void testLongSerializer() { | |||
} | |||
|
|||
@Test | |||
public void testFloatSerializer() { | |||
Float[] floats = new Float[]{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please use final
everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Deserializer<Float> deserializer = Serdes.Float().deserializer(); | ||
|
||
for (Float value : floats) { | ||
assertEquals("Should get the original double after serialization and deserialization", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd prefer we use asserThat, i.e., assertThat(value, equalTo(deserializer.deserialize(...))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (didn't know it was ok to use it, the existing tests didn't)
value, deserializer.deserialize(topic, serializer.serialize(topic, value))); | ||
} | ||
|
||
assertEquals("Should support null in serialization and deserialization", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this into a different test, i.e., shouldSupportNullInFloatSerde
or similiar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
assertEquals("Should support null in serialization and deserialization", | ||
null, deserializer.deserialize(topic, serializer.serialize(topic, null))); | ||
|
||
serializer.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these calls aren't needed, right? close
does nothing anyway. And if they did do something, then you'd probably want to do it in tearDown
rather than here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these calls aren't needed, right?
close
does nothing anyway.
Yes, close doesn't do anything in this specific case, but that behavior is not part of the contract afaict. Hence IMHO we should always close it.
And if they did do something, then you'd probably want to do it in
tearDown
rather than here.
That would only work if we created a global serde/serializer/deserializer instance that we'd re-use between tests. It's a matter of personal preference I admit, but I'd rather avoid doing that (I'm ok with the re-usable topic
variable though). That said, I don't have a strong opinion. If we do change the pattern, then the existing tests should be updated, too (though outside of this PR) for the sake of consistency.
deserializer.close(); | ||
} | ||
|
||
@Test(expected = SerializationException.class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a rule w.r.t using @expected
the rule is that it should only be used for single line tests where you can guarantee that the exception can only come from the line that is being executed. In all other cases you should use try{...}catch(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@Test | ||
public void floatSerializerShouldReturnNullForNull() { | ||
final Serializer<Float> serializer = Serdes.Float().serializer(); | ||
assertThat(null, equalTo(serializer.serialize(topic, null))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be: assertThat(serializer.serialize(topic, null), nullValue())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@Test | ||
public void floatDeserializerShouldReturnNullForNull() { | ||
final Deserializer<Float> deserializer = Serdes.Float().deserializer(); | ||
assertThat(null, equalTo(deserializer.deserialize(topic, null))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one, too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
|
||
@Override | ||
public byte[] serialize(String topic, Float data) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: (Sorry should've mentioned previously) would you mind making the params final, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
FYI: I squashed the commits. Ping @guozhangwang for final review. |
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
if (data == null) | ||
return null; | ||
|
||
long bits = Float.floatToIntBits(data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using floatToIntBits rather than floatToRawIntBits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cmccabe No strong reason either way. AFAIK there's no specific contract or requirement for handling NaN. Thoughts?
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LGTM and merged to trunk. |
No description provided.