Skip to content

Commit dce4d17

Browse files
committed
Use polymorphism for OrderedMap type when key type is known
PYTHON-231 peer review
1 parent 253279e commit dce4d17

File tree

3 files changed

+25
-29
lines changed

3 files changed

+25
-29
lines changed

cassandra/cqltypes.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
int32_pack, int32_unpack, int64_pack, int64_unpack,
4949
float_pack, float_unpack, double_pack, double_unpack,
5050
varint_pack, varint_unpack)
51-
from cassandra.util import OrderedMap, sortedset, Time
51+
from cassandra.util import OrderedMapSerializedKey, sortedset, Time
5252

5353
apache_cassandra_type_prefix = 'org.apache.cassandra.db.marshal.'
5454

@@ -794,8 +794,7 @@ def deserialize_safe(cls, byts, protocol_version):
794794
length = 2
795795
numelements = unpack(byts[:length])
796796
p = length
797-
themap = OrderedMap()
798-
themap._set_key_type(key_type, protocol_version)
797+
themap = OrderedMapSerializedKey(key_type, protocol_version)
799798
for _ in range(numelements):
800799
key_len = unpack(byts[p:p + length])
801800
p += length

cassandra/util.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -594,13 +594,6 @@ class OrderedMap(Mapping):
594594
595595
'''
596596

597-
cass_key_type = None
598-
protocol_version = None
599-
'''
600-
Set when deserializing a map from the server, when the key type is known.
601-
This avoids re-serializing, and also helps normalize lookups on text types.
602-
'''
603-
604597
def __init__(self, *args, **kwargs):
605598
if len(args) > 1:
606599
raise TypeError('expected at most 1 arguments, got %d' % len(args))
@@ -628,18 +621,6 @@ def _insert(self, key, value):
628621
self._items.append((key, value))
629622
self._index[flat_key] = len(self._items) - 1
630623

631-
def _set_key_type(self, cass_type, protocol_version):
632-
self.cass_key_type = cass_type
633-
self.protocol_version = protocol_version
634-
635-
def _insert_unchecked(self, key, flat_key, value):
636-
'''
637-
Used when building from server response.
638-
cass_key_type must be set in order for lookups to work later
639-
'''
640-
self._items.append((key, value))
641-
self._index[flat_key] = len(self._items) - 1
642-
643624
def __getitem__(self, key):
644625
try:
645626
index = self._index[self._serialize_key(key)]
@@ -675,7 +656,22 @@ def __str__(self):
675656
return '{%s}' % ', '.join("%s: %s" % (k, v) for k, v in self._items)
676657

677658
def _serialize_key(self, key):
678-
return self.cass_key_type.serialize(key, self.protocol_version) if self.cass_key_type else cPickle.dumps(key)
659+
return cPickle.dumps(key)
660+
661+
662+
class OrderedMapSerializedKey(OrderedMap):
663+
664+
def __init__(self, cass_type, protocol_version):
665+
super(OrderedMapSerializedKey, self).__init__()
666+
self.cass_key_type = cass_type
667+
self.protocol_version = protocol_version
668+
669+
def _insert_unchecked(self, key, flat_key, value):
670+
self._items.append((key, value))
671+
self._index[flat_key] = len(self._items) - 1
672+
673+
def _serialize_key(self, key):
674+
return self.cass_key_type.serialize(key, self.protocol_version)
679675

680676

681677
import datetime

tests/unit/test_marshalling.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
from decimal import Decimal
2424
from uuid import UUID
2525

26-
from cassandra.cqltypes import lookup_casstype
27-
from cassandra.util import OrderedMap, sortedset, Time
26+
from cassandra.cqltypes import lookup_casstype, DecimalType, UTF8Type
27+
from cassandra.util import OrderedMap, OrderedMapSerializedKey, sortedset, Time
2828

2929
marshalled_value_pairs = (
3030
# binary form, type, python native type
@@ -75,7 +75,7 @@
7575
(b'', 'MapType(AsciiType, BooleanType)', None),
7676
(b'', 'ListType(FloatType)', None),
7777
(b'', 'SetType(LongType)', None),
78-
(b'\x00\x00', 'MapType(DecimalType, BooleanType)', OrderedMap()),
78+
(b'\x00\x00', 'MapType(DecimalType, BooleanType)', OrderedMapSerializedKey(DecimalType, 0)),
7979
(b'\x00\x00', 'ListType(FloatType)', []),
8080
(b'\x00\x00', 'SetType(IntegerType)', sortedset()),
8181
(b'\x00\x01\x00\x10\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0', 'ListType(TimeUUIDType)', [UUID(bytes=b'\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0')]),
@@ -84,9 +84,10 @@
8484
(b'\x00\x00\x00\x00\x00\x00\x00\x01', 'TimeType', Time(1))
8585
)
8686

87-
ordered_map_value = OrderedMap([(u'\u307fbob', 199),
88-
(u'', -1),
89-
(u'\\', 0)])
87+
ordered_map_value = OrderedMapSerializedKey(UTF8Type, 2)
88+
ordered_map_value._insert(u'\u307fbob', 199)
89+
ordered_map_value._insert(u'', -1)
90+
ordered_map_value._insert(u'\\', 0)
9091

9192
# these following entries work for me right now, but they're dependent on
9293
# vagaries of internal python ordering for unordered types

0 commit comments

Comments
 (0)