You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2019/08/09 19:13:06 UTC
[tinkerpop] 08/23: Added double and float graphbinary serialization
in python
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch TINKERPOP-2279
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 16626d2d0c9db306829ef0225af8152e556d381b
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Fri Jul 26 12:37:58 2019 -0400
Added double and float graphbinary serialization in python
---
.../GraphBinaryReaderWriterRoundTripTest.java | 3 ++
.../gremlin_python/structure/io/graphbinaryV1.py | 61 +++++++++++++++++++++-
.../tests/structure/io/test_graphbinaryV1.py | 22 ++++++++
3 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
index d278602..48e324c 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java
@@ -165,6 +165,9 @@ public class GraphBinaryReaderWriterRoundTripTest {
new Object[] {"Integer", 1, null},
new Object[] {"Float", 2f, null},
new Object[] {"Double", 3.1d, null},
+ new Object[] {"Double", Double.NaN, null},
+ new Object[] {"Double", Double.POSITIVE_INFINITY, null},
+ new Object[] {"Double", Double.NEGATIVE_INFINITY, null},
new Object[] {"Long", 10122L, null},
new Object[] {"IntegerZero", 0, null},
new Object[] {"FloatZero", 0f, null},
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphbinaryV1.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphbinaryV1.py
index f84d2a0..4a5dd0e 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphbinaryV1.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphbinaryV1.py
@@ -54,6 +54,9 @@ class DataType(Enum):
string = 0x03
date = 0x04
timestamp = 0x05
+ clazz = 0x06
+ double = 0x07
+ float = 0x08
list = 0x09
@@ -123,8 +126,8 @@ class _GraphBinaryTypeIO(object):
"set_": "set", "list_": "list", "all_": "all", "with_": "with"}
@classmethod
- def as_bytes(cls, graphbin_type, size=None, *args):
- ba = bytearray([graphbin_type.value])
+ def as_bytes(cls, graphbin_type=None, size=None, *args):
+ ba = bytearray() if graphbin_type is None else bytearray([graphbin_type.value])
if size is not None:
ba.extend(struct.pack(">i", size))
@@ -218,6 +221,60 @@ class TimestampIO(_GraphBinaryTypeIO):
return statics.timestamp(struct.unpack(">q", buff.read(8))[0] / 1000.0)
+def _long_bits_to_double(bits):
+ return struct.unpack('d', struct.pack('Q', bits))[0]
+
+
+NAN = _long_bits_to_double(0x7ff8000000000000)
+POSITIVE_INFINITY = _long_bits_to_double(0x7ff0000000000000)
+NEGATIVE_INFINITY = _long_bits_to_double(0xFff0000000000000)
+
+
+class FloatIO(LongIO):
+
+ python_type = FloatType
+ graphbinary_type = DataType.float
+ graphbinary_base_type = DataType.float
+ byte_format = ">f"
+
+ @classmethod
+ def dictify(cls, obj, writer):
+ if math.isnan(obj):
+ return cls.as_bytes(cls.graphbinary_base_type, None, struct.pack(cls.byte_format, NAN))
+ elif math.isinf(obj) and obj > 0:
+ return cls.as_bytes(cls.graphbinary_base_type, None, struct.pack(cls.byte_format, POSITIVE_INFINITY))
+ elif math.isinf(obj) and obj < 0:
+ return cls.as_bytes(cls.graphbinary_base_type, None, struct.pack(cls.byte_format, NEGATIVE_INFINITY))
+ else:
+ return cls.as_bytes(cls.graphbinary_base_type, None, struct.pack(cls.byte_format, obj))
+
+ @classmethod
+ def objectify(cls, buff, reader):
+ return struct.unpack(cls.byte_format, buff.read(4))[0]
+
+
+class DoubleIO(FloatIO):
+ """
+ Floats basically just fall through to double serialization.
+ """
+
+ graphbinary_type = DataType.double
+ graphbinary_base_type = DataType.double
+ byte_format = ">d"
+
+ @classmethod
+ def objectify(cls, buff, reader):
+ return struct.unpack(cls.byte_format, buff.read(8))[0]
+
+
+class TypeSerializer(_GraphBinaryTypeIO):
+ python_type = TypeType
+
+ @classmethod
+ def dictify(cls, typ, writer):
+ return writer.toDict(typ())
+
+
class StringIO(_GraphBinaryTypeIO):
python_type = str
diff --git a/gremlin-python/src/main/jython/tests/structure/io/test_graphbinaryV1.py b/gremlin-python/src/main/jython/tests/structure/io/test_graphbinaryV1.py
index db58545..75b4392 100644
--- a/gremlin-python/src/main/jython/tests/structure/io/test_graphbinaryV1.py
+++ b/gremlin-python/src/main/jython/tests/structure/io/test_graphbinaryV1.py
@@ -54,6 +54,28 @@ class TestGraphSONWriter(object):
output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
assert x == output
+ def test_float(self):
+ x = float(100.001)
+ output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
+ assert x == output
+
+ x = float('nan')
+ output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
+ assert math.isnan(output)
+
+ x = float('-inf')
+ output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
+ assert math.isinf(output) and output < 0
+
+ x = float('inf')
+ output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
+ assert math.isinf(output) and output > 0
+
+ def test_double(self):
+ x = 100.001
+ output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))
+ assert x == output
+
def test_date(self):
x = calendar.timegm(datetime.datetime(2016, 12, 14, 16, 14, 36, 295000).utctimetuple())
output = self.graphbinary_reader.readObject(self.graphbinary_writer.writeObject(x))