Merge pull request #9370 from ThomasWaldmann/fix-hashindex-1.4
Some checks failed
CI / lint (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
Windows CI / msys2-ucrt64 (push) Has been cancelled
CI / asan_ubsan (push) Has been cancelled
CI / native_tests (push) Has been cancelled
CI / vm_tests (Haiku, false, haiku, r1beta5) (push) Has been cancelled
CI / vm_tests (NetBSD, false, netbsd, 10.1) (push) Has been cancelled
CI / vm_tests (OpenBSD, false, openbsd, 7.7) (push) Has been cancelled
CI / vm_tests (borg-freebsd-14-x86_64-gh, FreeBSD, true, freebsd, 14.3) (push) Has been cancelled

Fix hashindex .iteritems (1.4-maint)
This commit is contained in:
TW 2026-02-19 00:24:15 +01:00 committed by GitHub
commit 86f6b8e7ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 11 deletions

View file

@ -205,7 +205,7 @@ cdef class NSIndex(IndexBase):
def __getitem__(self, key):
assert len(key) == self.key_size
data = <uint32_t *>hashindex_get(self.index, <unsigned char *>key)
if not data:
if data == NULL:
raise KeyError(key)
cdef uint32_t segment = _le32toh(data[0])
assert segment <= _MAX_VALUE, "maximum number of segments reached"
@ -237,8 +237,8 @@ cdef class NSIndex(IndexBase):
iter.index = self.index
if marker:
key = hashindex_get(self.index, <unsigned char *>marker)
if marker is None:
raise IndexError
if key == NULL:
raise KeyError("marker not found")
iter.key = key - self.key_size
return iter
@ -296,7 +296,7 @@ cdef class ChunkIndex(IndexBase):
def __getitem__(self, key):
assert len(key) == self.key_size
data = <uint32_t *>hashindex_get(self.index, <unsigned char *>key)
if not data:
if data == NULL:
raise KeyError(key)
cdef uint32_t refcount = _le32toh(data[0])
assert refcount <= _MAX_VALUE, "invalid reference count"
@ -324,7 +324,7 @@ cdef class ChunkIndex(IndexBase):
"""Increase refcount for 'key', return (refcount, size, csize)."""
assert len(key) == self.key_size
data = <uint32_t *>hashindex_get(self.index, <unsigned char *>key)
if not data:
if data == NULL:
raise KeyError(key)
cdef uint32_t refcount = _le32toh(data[0])
assert refcount <= _MAX_VALUE, "invalid reference count"
@ -337,7 +337,7 @@ cdef class ChunkIndex(IndexBase):
"""Decrease refcount for 'key', return (refcount, size, csize)."""
assert len(key) == self.key_size
data = <uint32_t *>hashindex_get(self.index, <unsigned char *>key)
if not data:
if data == NULL:
raise KeyError(key)
cdef uint32_t refcount = _le32toh(data[0])
# Never decrease a reference count of zero
@ -354,8 +354,8 @@ cdef class ChunkIndex(IndexBase):
iter.index = self.index
if marker:
key = hashindex_get(self.index, <unsigned char *>marker)
if marker is None:
raise IndexError
if key == NULL:
raise KeyError("marker not found")
iter.key = key - self.key_size
return iter
@ -406,7 +406,7 @@ cdef class ChunkIndex(IndexBase):
break
our_values = <const uint32_t*> (key + self.key_size)
master_values = <const uint32_t*> hashindex_get(master, key)
if not master_values:
if master_values == NULL:
raise ValueError('stats_against: key contained in self but not in master_index.')
our_refcount = _le32toh(our_values[0])
chunk_size = _le32toh(master_values[1])
@ -434,7 +434,7 @@ cdef class ChunkIndex(IndexBase):
cdef _add(self, unsigned char *key, uint32_t *data):
cdef uint64_t refcount1, refcount2, result64
values = <uint32_t*> hashindex_get(self.index, key)
if values:
if values != NULL:
refcount1 = _le32toh(values[0])
refcount2 = _le32toh(data[0])
assert refcount1 <= _MAX_VALUE, "invalid reference count"

View file

@ -3,7 +3,37 @@ import random
import pytest
from ..hashindex import NSIndex
from borg.hashindex import NSIndex, ChunkIndex
def test_nsindex_iteritems_marker():
nsindex = NSIndex()
nsindex[b'\xbb'*32] = (123, 456)
nsindex[b'\xaa'*32] = (234, 567)
# marker exists
items = list(nsindex.iteritems(marker=b'\xbb'*32))
assert len(items) == 1
assert items[0][0] == b'\xaa'*32
# marker does not exist
with pytest.raises(KeyError, match="marker not found"):
list(nsindex.iteritems(marker=b'\xcc'*32))
def test_chunkindex_iteritems_marker():
chunkindex = ChunkIndex()
chunkindex[b'\xbb'*32] = (1, 100, 50)
chunkindex[b'\xaa'*32] = (1, 200, 100)
# marker exists
items = list(chunkindex.iteritems(marker=b'\xbb'*32))
assert len(items) == 1
assert items[0][0] == b'\xaa'*32
# marker does not exist
with pytest.raises(KeyError, match="marker not found"):
list(chunkindex.iteritems(marker=b'\xcc'*32))
@pytest.mark.skipif("BORG_TESTS_SLOW" not in os.environ, reason="slow tests not enabled, use BORG_TESTS_SLOW=1")