Skip to content

Commit d4715e0

Browse files
Merge pull request #33 from borgbackup/separate-endianness
HashTableNT: deal with byte_order separately
2 parents 9fa09c9 + 6150f11 commit d4715e0

File tree

5 files changed

+14
-6
lines changed

5 files changed

+14
-6
lines changed

src/borghash/HashTableNT.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cdef class HashTableNT:
22
cdef int key_size
3+
cdef object byte_order
34
cdef object value_type
45
cdef object value_format
56
cdef object value_struct

src/borghash/HashTableNT.pyx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ assert len(MAGIC) == 8
1717
VERSION = 1 # version of the on-disk (serialized) format produced by .write().
1818
HEADER_FMT = "<8sII" # magic, version, meta length
1919

20+
BYTE_ORDER = dict(big=">", little="<", network="!", native="=") # struct format chars
21+
2022
_NoDefault = object()
2123

2224
cdef class HashTableNT:
2325
def __init__(self, items=None, *,
2426
key_size: int, value_type: Any, value_format: Any,
25-
capacity: int = MIN_CAPACITY) -> None:
27+
capacity: int = MIN_CAPACITY, byte_order="little") -> None:
2628
if not isinstance(key_size, int) or not key_size > 0:
2729
raise ValueError("key_size must be an integer and > 0.")
2830
if type(value_type) is not type:
@@ -33,10 +35,13 @@ cdef class HashTableNT:
3335
raise TypeError("value_format's and value_type's element names must correspond.")
3436
if not all(isinstance(fmt, str) and len(fmt) > 0 for fmt in value_format):
3537
raise ValueError("value_format's elements must be str and non-empty.")
38+
if byte_order not in BYTE_ORDER:
39+
raise ValueError("byte_order must be one of: {','.join(BYTE_ORDER.keys())}")
3640
self.key_size = key_size
3741
self.value_type = value_type
3842
self.value_format = value_format
39-
self.value_struct = struct.Struct("".join(value_format))
43+
self.byte_order = byte_order
44+
self.value_struct = struct.Struct(BYTE_ORDER[byte_order] + "".join(value_format))
4045
self.value_size = self.value_struct.size
4146
self.inner = HashTable(key_size=self.key_size, value_size=self.value_size, capacity=capacity)
4247
_fill(self, items)
@@ -164,6 +169,7 @@ cdef class HashTableNT:
164169
meta = {
165170
'key_size': self.key_size,
166171
'value_size': self.value_size,
172+
'byte_order': self.byte_order,
167173
'value_type_name': self.value_type.__name__,
168174
'value_type_fields': self.value_type._fields,
169175
'value_format_name': self.value_format.__class__.__name__,
@@ -210,7 +216,8 @@ cdef class HashTableNT:
210216
value_type = namedtuple(meta['value_type_name'], meta['value_type_fields'])
211217
value_format_t = namedtuple(meta['value_format_name'], meta['value_format_fields'])
212218
value_format = value_format_t(*meta['value_format'])
213-
ht = cls(key_size=meta['key_size'], value_format=value_format, value_type=value_type, capacity=meta['capacity'])
219+
ht = cls(key_size=meta['key_size'], value_format=value_format, value_type=value_type,
220+
capacity=meta['capacity'], byte_order=meta['byte_order'])
214221
count = 0
215222
ksize, vsize = meta['key_size'], meta['value_size']
216223
for i in range(meta['used']):

src/borghash/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def demo():
1616
count = 50000
1717
value_type = namedtuple("Chunk", ["refcount", "size"])
1818
value_format_t = namedtuple("ChunkFormat", ["refcount", "size"])
19-
value_format = value_format_t(refcount="<I", size="I")
19+
value_format = value_format_t(refcount="I", size="I")
2020
# 256bit (32Byte) key, 2x 32bit (4Byte) values
2121
ht = HashTableNT(key_size=32, value_type=value_type, value_format=value_format)
2222

tests/benchmark_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
VALUE_TYPE = namedtuple("value_type", "value")
1313
VALUE_FMT_TYPE = namedtuple("value_format", "value")
14-
VALUE_FMT = VALUE_FMT_TYPE("<I")
14+
VALUE_FMT = VALUE_FMT_TYPE("I")
1515
KEY_SIZE = len(H2(0))
1616
VALUE_SIZE = len(struct.pack("".join(VALUE_FMT), 0))
1717
VALUE_BITS = VALUE_SIZE * 8

tests/hashtablent_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
key_size = 32 # 32 bytes = 256bits key
1111
value_type = namedtuple("vt", "v1 v2 v3")
1212
value_format_t = namedtuple("vf", "v1 v2 v3")
13-
value_format = value_format_t(v1="<I", v2="I", v3="I") # 3x little endian 32bit unsigned int
13+
value_format = value_format_t(v1="I", v2="I", v3="I") # 3x little endian 32bit unsigned int
1414

1515
key1, value1 = b"a" * 32, value_type(11, 12, 13)
1616
key2, value2 = b"b" * 32, value_type(21, 22, 23)

0 commit comments

Comments
 (0)