Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/src/zserio/hashcode.py: 100%
90 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
1"""
2The module provides utility methods for hash code calculation.
3"""
5import typing
7from zserio.float import float_to_uint32, float_to_uint64
9HASH_SEED = 23
10HASH_PRIME_NUMBER = 37
13def calc_hashcode_bool(seed_value: int, value: bool) -> int:
14 """
15 Calculates hash code for a boolean value.
17 :param seed_value: Seed value (current hash code).
18 :param value: Value to use.
19 :returns: Calculated hash code.
20 """
22 return calc_hashcode_int32(seed_value, 1 if value else 0)
25def calc_hashcode_int32(seed_value: int, value: int) -> int:
26 """
27 Calculates hash code for a 32-bit integral value.
29 :param seed_value: Seed value (current hash code).
30 :param value: Value to use.
31 :returns: Calculated hash code.
32 """
34 if value is None:
35 return calc_hashcode_int32(seed_value, 0)
37 return (HASH_PRIME_NUMBER * seed_value + value) & 0xFFFFFFFF
40def calc_hashcode_int64(seed_value: int, value: int) -> int:
41 """
42 Calculates hash code for a 64-bit integral value.
44 :param seed_value: Seed value (current hash code).
45 :param value: Value to use.
46 :returns: Calculated hash code.
47 """
49 if value is None:
50 return calc_hashcode_int32(seed_value, 0)
52 int_value_for_hash = (value & 0xFFFFFFFF) ^ ((value & 0xFFFFFFFFFFFFFFFF) >> 32)
53 return (HASH_PRIME_NUMBER * seed_value + int_value_for_hash) & 0xFFFFFFFF
56def calc_hashcode_float32(seed_value: int, value: float) -> int:
57 """
58 Calculates hash code for a 32-bit float value.
60 :param seed_value: Seed value (current hash code).
61 :param value: Value to use.
62 :returns: Calculated hash code.
63 """
65 if value is None:
66 return calc_hashcode_int32(seed_value, 0)
68 int_value = float_to_uint32(value)
69 return calc_hashcode_int32(seed_value, int_value)
72def calc_hashcode_float64(seed_value: int, value: float) -> int:
73 """
74 Calculates hash code for a 64-bit float value.
76 :param seed_value: Seed value (current hash code).
77 :param value: Value to use.
78 :returns: Calculated hash code.
79 """
81 if value is None:
82 return calc_hashcode_int32(seed_value, 0)
84 int_value = float_to_uint64(value)
85 return calc_hashcode_int64(seed_value, int_value)
88def calc_hashcode_bytes(seed_value: int, value: bytearray) -> int:
89 """
90 Calculates hash code for a bytes value.
92 :param seed_value: Seed value (current hash code).
93 :param value: Value to use.
94 :returns: Calculated hash code.
95 """
97 if value is None:
98 return calc_hashcode_int32(seed_value, 0)
100 result = seed_value
101 for element in value:
102 result = calc_hashcode_int32(result, element)
104 return result
107def calc_hashcode_string(seed_value: int, value: str) -> int:
108 """
109 Calculates hash code for a string value.
111 :param seed_value: Seed value (current hash code).
112 :param value: Value to use.
113 :returns: Calculated hash code.
114 """
116 if value is None:
117 return calc_hashcode_int32(seed_value, 0)
119 result = seed_value
120 for element in value:
121 result = calc_hashcode_int32(result, ord(element))
123 return result
126def calc_hashcode_object(seed_value: int, value: typing.Any) -> int:
127 """
128 Calculates hash code for an object value.
130 This is used for all objects (in zserio runtime or generated) which override the default __hash__ method.
132 :param seed_value: Seed value (current hash code).
133 :param value: Value to use.
134 :returns: Calculated hash code.
135 """
137 # using __hash__ to prevent 32-bit Python hash() truncation
138 # pylint: disable=unnecessary-dunder-call
139 return calc_hashcode_int32(seed_value, value.__hash__() if value else 0)
142def calc_hashcode_bool_array(seed_value: int, value: typing.List[bool]) -> int:
143 """
144 Calculates hash code for a boolean array value.
146 :param seed_value: Seed value (current hash code).
147 :param value: Value to use.
148 :returns: Calculated hash code.
149 """
151 if value is None:
152 return calc_hashcode_int32(seed_value, 0)
154 result = seed_value
155 for element in value:
156 result = calc_hashcode_bool(result, element)
157 return result
160def calc_hashcode_int_array(seed_value: int, value: typing.List[int]) -> int:
161 """
162 Calculates hash code for an integral array value.
164 :param seed_value: Seed value (current hash code).
165 :param value: Value to use.
166 :returns: Calculated hash code.
167 """
169 if value is None:
170 return calc_hashcode_int32(seed_value, 0)
172 result = seed_value
173 for element in value:
174 result = calc_hashcode_int32(result, element)
175 return result
178def calc_hashcode_float32_array(seed_value: int, value: typing.List[int]) -> int:
179 """
180 Calculates hash code for a 32-bit float array value.
182 :param seed_value: Seed value (current hash code).
183 :param value: Value to use.
184 :returns: Calculated hash code.
185 """
187 if value is None:
188 return calc_hashcode_int32(seed_value, 0)
190 result = seed_value
191 for element in value:
192 result = calc_hashcode_float32(result, element)
193 return result
196def calc_hashcode_float64_array(seed_value: int, value: typing.List[int]) -> int:
197 """
198 Calculates hash code for a 64-bit float array value.
200 :param seed_value: Seed value (current hash code).
201 :param value: Value to use.
202 :returns: Calculated hash code.
203 """
205 if value is None:
206 return calc_hashcode_int32(seed_value, 0)
208 result = seed_value
209 for element in value:
210 result = calc_hashcode_float64(result, element)
211 return result
214def calc_hashcode_bytes_array(seed_value: int, value: typing.List[bytearray]) -> int:
215 """
216 Calculates hash code for a bytes array value.
218 :param seed_value: Seed value (current hash code).
219 :param value: Value to use.
220 :returns: Calculated hash code.
221 """
223 if value is None:
224 return calc_hashcode_int32(seed_value, 0)
226 result = seed_value
227 for element in value:
228 result = calc_hashcode_bytes(result, element)
229 return result
232def calc_hashcode_string_array(seed_value: int, value: typing.List[str]) -> int:
233 """
234 Calculates hash code for a string array value.
236 :param seed_value: Seed value (current hash code).
237 :param value: Value to use.
238 :returns: Calculated hash code.
239 """
241 if value is None:
242 return calc_hashcode_int32(seed_value, 0)
244 result = seed_value
245 for element in value:
246 result = calc_hashcode_string(result, element)
247 return result
250def calc_hashcode_object_array(seed_value: int, value: typing.List[typing.Any]) -> int:
251 """
252 Calculates hash code for an object array value.
254 This is used for arrays of all objects (in zserio runtime or generated) which override the default
255 __hash__ method.
257 :param seed_value: Seed value (current hash code).
258 :param value: Value to use.
259 :returns: Calculated hash code.
260 """
262 if value is None:
263 return calc_hashcode_int32(seed_value, 0)
265 result = seed_value
266 for element in value:
267 result = calc_hashcode_object(result, element)
268 return result