Skip to content

Commit e6372ce

Browse files
committed
Split length and data for Bit [skip ci]
1 parent cfc0404 commit e6372ce

1 file changed

Lines changed: 14 additions & 18 deletions

File tree

pgvector/bit.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22
from struct import pack, unpack_from
3-
from typing import cast
43

54
try:
65
import numpy as np
@@ -12,8 +11,8 @@
1211
class Bit:
1312
def __init__(self, value: bytes | str | list[bool] | np.ndarray[tuple[int], np.dtype[np.bool | np.uint8]]) -> None:
1413
if isinstance(value, bytes):
15-
length = 8 * len(value)
16-
data = value
14+
self._length = 8 * len(value)
15+
self._data = value
1716
elif isinstance(value, (list, str)):
1817
if isinstance(value, list):
1918
def bit_value(v: bool) -> str:
@@ -30,8 +29,9 @@ def bit_value(v: bool) -> str:
3029
if length % 8 != 0:
3130
value += '0' * (8 - (length % 8))
3231

32+
self._length = length
3333
try:
34-
data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
34+
self._data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
3535
except ValueError:
3636
raise ValueError('expected bit string')
3737
elif NUMPY_AVAILABLE and isinstance(value, np.ndarray):
@@ -44,37 +44,31 @@ def bit_value(v: bool) -> str:
4444
if value.ndim != 1:
4545
raise ValueError('expected ndim to be 1')
4646

47-
length = len(value)
48-
data = np.packbits(value).tobytes()
47+
self._length = len(value)
48+
self._data = np.packbits(value).tobytes()
4949
else:
5050
raise ValueError('expected bytes, str, list, or ndarray')
5151

52-
self._value = pack('>i', length) + data
53-
5452
def __repr__(self) -> str:
5553
return f'Bit({self.to_text()})'
5654

5755
def __eq__(self, other: object) -> bool:
5856
if isinstance(other, self.__class__):
59-
return self.to_binary() == other.to_binary()
57+
return self._length == other._length and self._data == other._data
6058
return False
6159

62-
def _length(self) -> int:
63-
length, = cast(tuple[int], unpack_from('>i', self._value))
64-
return length
65-
6660
def to_list(self) -> list[bool]:
6761
# TODO improve
6862
return [v != '0' for v in self.to_text()]
6963

7064
def to_numpy(self) -> np.ndarray[tuple[int], np.dtype[np.bool]]:
71-
return np.unpackbits(np.frombuffer(self._value[4:], dtype=np.uint8), count=self._length()).astype(bool)
65+
return np.unpackbits(np.frombuffer(self._data, dtype=np.uint8), count=self._length).astype(bool)
7266

7367
def to_text(self) -> str:
74-
return ''.join(format(v, '08b') for v in self._value[4:])[:self._length()]
68+
return ''.join(format(v, '08b') for v in self._data)[:self._length]
7569

7670
def to_binary(self) -> bytes:
77-
return self._value
71+
return pack('>i', self._length) + self._data
7872

7973
@classmethod
8074
def from_text(cls, value: str) -> Bit:
@@ -86,10 +80,12 @@ def from_binary(cls, value: bytes) -> Bit:
8680
raise ValueError('expected bytes')
8781

8882
length, = unpack_from('>i', value)
83+
data = value[4:]
8984

90-
if len(value) != 4 + (length + 7) // 8:
85+
if len(data) != (length + 7) // 8:
9186
raise ValueError('invalid length')
9287

9388
bit = cls.__new__(cls)
94-
bit._value = value
89+
bit._length = length
90+
bit._data = data
9591
return bit

0 commit comments

Comments
 (0)