Ejemplo n.º 1
0
def test_resize(scenario):
    hd = HopscotchDict()

    if scenario == "bad_size":
        with pytest.raises(ValueError):
            hd._resize(25)

    elif scenario == "too_large":
        with pytest.raises(ValueError):
            hd._resize(2**65)

    elif scenario == "nbhd_inc":
        for i in range(32):
            hd[f"test_resize_{i}"] = i

        hd._resize(512)

        assert hd._nbhd_size == 16

        for i in range(32):
            assert hd[f"test_resize_{i}"] == i

    elif scenario == "rsz_col":
        hd[1] = "test_1"
        hd[17] = "test_17"

        hd._resize(16)

        assert hd[1] == "test_1"
        assert hd[17] == "test_17"
Ejemplo n.º 2
0
def test_symmetric_difference():
    hd = HopscotchDict()
    keys = hd.keys()
    items = hd.items()

    hd["a"] = 1
    hd["b"] = 2
    hd["c"] = 3

    s1 = ["a", "b"]
    s2 = ["a", "b", "c", "d"]
    s3 = ["d", "e", "f"]

    s4 = [1, 2]
    s5 = [1, 2, 3, 4]
    s6 = [4, 5, 6]

    assert keys ^ set(s1) == {"c"}
    assert keys.symmetric_difference(s2) == {"d"}

    assert items ^ zip(s1, s4) == {("c", 3)}
    assert items.symmetric_difference(zip(s2, s5)) == {("d", 4)}

    assert keys ^ set(s3) == keys | set(s3)
    assert keys.symmetric_difference(s3) == keys | set(s3)

    assert items ^ zip(s3, s6) == items | zip(s3, s6)
    assert items.symmetric_difference(zip(s3, s6)) == items | zip(s3, s6)
Ejemplo n.º 3
0
def test_contains_and_has_key(gen_dict):
    hd = HopscotchDict(gen_dict)
    for key in hd._keys:
        assert key in hd

    assert "test_contains" not in hd
    assert not hd.has_key("test_contains")  # noqa
Ejemplo n.º 4
0
def test_intersection():
    hd = HopscotchDict()
    keys = hd.keys()
    items = hd.items()

    hd["a"] = 1
    hd["b"] = 2
    hd["c"] = 3

    s1 = ["a", "b"]
    s2 = ["a", "b", "c", "d"]
    s3 = ["d", "e", "f"]

    s4 = [1, 2]
    s5 = [1, 2, 3, 4]
    s6 = [4, 5, 6]

    assert keys & set(s1) == set(s1)
    assert keys.intersection(s2) == keys

    assert items & zip(s1, s4) == set(zip(s1, s4))
    assert items.intersection(zip(s2, s5)) == items

    assert keys & set(s3) == set()
    assert keys.intersection(s3) == set()

    assert items & zip(s3, s6) == set()
    assert items.intersection(zip(s3, s6)) == set()
Ejemplo n.º 5
0
def test_copy(gen_dict):
    hd = HopscotchDict(gen_dict)

    hdc = hd.copy()

    for key in hd._keys:
        assert id(hd[key]) == id(hdc[key])
Ejemplo n.º 6
0
def test_subset():
    hd = HopscotchDict()
    keys = hd.keys()
    items = hd.items()

    hd["a"] = 1
    hd["b"] = 2
    hd["c"] = 3

    s1 = ["a", "b"]
    s2 = ["a", "b", "c"]
    s3 = ["a", "b", "c", "d"]

    s4 = [1, 2]
    s5 = [1, 2, 3]
    s6 = [1, 2, 3, 4]

    assert not keys <= set(s1)
    assert not keys.issubset(s1)

    assert keys <= set(s2)
    assert keys.issubset(s2)

    assert keys <= set(s3)
    assert keys.issubset(s3)

    assert not items <= set(list(zip(s1, s4)))
    assert not items.issubset(list(zip(s1, s4)))

    assert items <= set(list(zip(s2, s5)))
    assert items.issubset(list(zip(s2, s5)))

    assert items <= set(list(zip(s3, s6)))
    assert items.issubset(list(zip(s3, s6)))
Ejemplo n.º 7
0
def test_setdefault(existing_key):
    hd = HopscotchDict()
    val = None

    if existing_key:
        hd["test_setdefault"] = val = 1337
    else:
        val = 1017

    assert hd.setdefault("test_setdefault", 1017) == val
Ejemplo n.º 8
0
def test_get(valid_key):
    hd = HopscotchDict()
    val = None

    if valid_key:
        hd["test_get"] = val = 1337
    else:
        val = 1017

    assert hd.get("test_get", 1017) == val
Ejemplo n.º 9
0
def test_items(gen_dict):
    hd = HopscotchDict(gen_dict)
    items = hd.items()
    start_len = len(hd)

    assert len(items) == start_len
    assert all(hd[k] == v for (k, v) in items)

    hd["test_items"] = True

    assert len(items) == start_len + 1
    assert ("test_items", True) in items
Ejemplo n.º 10
0
def test_values(gen_dict):
    hd = HopscotchDict(gen_dict)
    vals = hd.values()
    start_len = len(hd)

    assert len(vals) == start_len
    assert all(v in hd._values for v in vals)

    hd["test_values"] = "test_values"

    assert len(vals) == start_len + 1
    assert "test_values" in vals
Ejemplo n.º 11
0
def test_keys(gen_dict):
    hd = HopscotchDict(gen_dict)
    keys = hd.keys()
    start_len = len(hd)

    assert len(keys) == start_len
    assert all(k in hd for k in keys)

    hd["test_keys"] = True

    assert len(keys) == start_len + 1
    assert "test_keys" in keys
Ejemplo n.º 12
0
def test_reversed(gen_dict):
    hd = HopscotchDict(gen_dict)

    keys = hd.keys()
    if not isinstance(keys, list):
        keys = list(keys)

    rev_keys = list(reversed(hd))

    assert len(keys) == len(rev_keys)
    for i in range(len(keys)):
        assert keys[i] == rev_keys[len(keys) - i - 1]
Ejemplo n.º 13
0
def test_reversed(gen_dict):
    hd = HopscotchDict(gen_dict)
    keys = hd.keys()
    vals = hd.values()
    items = hd.items()

    assert list(reversed(list(reversed(keys)))) == hd._keys
    assert list(reversed(list(reversed(vals)))) == hd._values
    for (i, (k, v)) in enumerate(reversed(list(reversed(items)))):
        assert k == hd._keys[i]
        assert v == hd._values[i]

    hd["test_keys"] = True
Ejemplo n.º 14
0
def test_setitem_happy_path(gen_dict):
    hd = HopscotchDict()

    for (k, v) in gen_dict.items():
        hd[k] = v

    assert len(hd) == len(gen_dict)

    for key in gen_dict:
        assert hd[key] == gen_dict[key]
        expected_lookup_idx = abs(hash(key)) % hd._size
        _, neighbors = hd._get_lookup_index_info(expected_lookup_idx)
        lookup_idx, _ = hd._lookup(key)
        assert lookup_idx in neighbors
Ejemplo n.º 15
0
def test_pop(scenario):
    hd = HopscotchDict()
    val = None

    if scenario == "valid_key":
        hd["test_pop"] = val = 1337
    else:
        val = 0

    if scenario != "invalid_key":
        assert hd.pop("test_pop", 0) == val
    else:
        with pytest.raises(KeyError):
            hd.pop("test_pop")
Ejemplo n.º 16
0
def test_make_lookup_table(tbl_size):
    if tbl_size < 0:
        with pytest.raises(ValueError):
            HopscotchDict._make_lookup_table(tbl_size)
    else:
        tbl, fmt = HopscotchDict._make_lookup_table(tbl_size)

        if tbl_size.bit_length() < 8:
            assert fmt == "b B"
        elif tbl_size.bit_length() < 16:
            assert fmt == ">h H"
        elif tbl_size.bit_length() < 32:
            assert fmt == ">i I"
        else:
            assert fmt == ">l L"
Ejemplo n.º 17
0
def test_lookup(key):
    hd = HopscotchDict()

    hd[7] = "test_lookup_7"
    hd[15] = "test_lookup_15"

    assert hd._lookup(7) == (7, 0)
    assert hd._lookup(15) == (0, 1)

    del hd[7]
    del hd[15]

    lookup_idx = abs(hash(key)) % hd._size
    hd[key] = True
    assert hd._lookup(key)[0] == lookup_idx
Ejemplo n.º 18
0
def test_eq_and_neq(scenario):
    hd = HopscotchDict()
    dc = {}

    for i in range(5):
        hd[f"test_eq_and_neq_{i}"] = i
        dc[f"test_eq_and_neq_{i}"] = i

    if scenario == "bad_len" or scenario == "bad_keys":
        dc.pop("test_eq_and_neq_4")

    if scenario == "bad_keys":
        dc["test_eq_and_neq_5"] = 4

    if scenario == "bad_vals":
        dc["test_eq_and_neq_0"] = False

    if scenario == "bad_type":
        assert hd != dc.items()

    elif scenario != "eq":
        assert hd != dc

    else:
        assert hd == dc
Ejemplo n.º 19
0
    def _make_level_tables(levels: int) -> List[HopscotchDict]:
        """
		Creates the dicts used when searching for a value in the trie

		:param levels: The number of levels in the trie
		:return: Search structures for each level of the trie
		"""
        return [HopscotchDict() for _ in range(levels)]
Ejemplo n.º 20
0
def test_iter_and_len(gen_dict):
    hd = HopscotchDict(gen_dict)

    count = 0

    for key in hd:
        count += 1

    assert count == len(hd) == len(gen_dict)
Ejemplo n.º 21
0
    def clear(self) -> None:
        """
		Remove all values from the trie and return it to its starting state
		"""
        self._count = 0
        self._max: Optional[int] = None
        self._min: Optional[int] = None
        self._partitions = XFastTrie(self._maxlen)
        self._subtrees = HopscotchDict()
Ejemplo n.º 22
0
def test_getitem(valid_key):
    hd = HopscotchDict()

    if valid_key:
        hd["test_getitem"] = True
        assert hd["test_getitem"]
    else:
        with pytest.raises(KeyError):
            assert hd["test_getitem"]
Ejemplo n.º 23
0
def test_get_displaced_neighbors(with_collisions):
    hd = HopscotchDict()

    if with_collisions:
        hd[1] = "test_get_displaced_neighbors_1"
        hd[9] = "test_get_displaced_neighbors_9"
        hd[3] = "test_get_displaced_neighbors_3"
        hd[17] = "test_get_displaced_neighbors_17"
        hd[6] = "test_get_displaced_neighbors_6"
        hd[14] = "test_get_displaced_neighbors_14"

        assert hd._size == 8

        lookup_offset = calcsize(hd._pack_fmt) * 1
        _, nbhd = unpack_from(hd._pack_fmt, hd._lookup_table, lookup_offset)
        assert hd._get_displaced_neighbors(1, nbhd, hd._nbhd_size, hd._size) == [
            1,
            2,
            4,
        ]

        lookup_offset = calcsize(hd._pack_fmt) * 3
        _, nbhd = unpack_from(hd._pack_fmt, hd._lookup_table, lookup_offset)
        assert hd._get_displaced_neighbors(3, nbhd, hd._nbhd_size, hd._size) == [3]

        lookup_offset = calcsize(hd._pack_fmt) * 6
        _, nbhd = unpack_from(hd._pack_fmt, hd._lookup_table, lookup_offset)
        assert hd._get_displaced_neighbors(6, nbhd, hd._nbhd_size, hd._size) == [6, 7]

    else:
        with pytest.raises(ValueError):
            hd._get_displaced_neighbors(-1, 0, hd._nbhd_size, hd._size)

        with pytest.raises(ValueError):
            hd._get_displaced_neighbors(10, 0, hd._nbhd_size, hd._size)

        for i in range(6):
            hd[i] = f"test_get_displaced_neighbors_{i}"

        for i in range(6):
            lookup_offset = calcsize(hd._pack_fmt) * i
            _, nbhd = unpack_from(hd._pack_fmt, hd._lookup_table, lookup_offset)
            assert hd._get_displaced_neighbors(i, nbhd, hd._nbhd_size, hd._size) == [i]
Ejemplo n.º 24
0
def test_clear():
    hd = HopscotchDict()

    for i in range(256):
        hd[f"test_clear_{i}"] = i

    hd.clear()

    assert hd._count == 0
    assert hd._size == 8
    assert hd._nbhd_size == 8

    assert len(hd._keys) == 0
    assert len(hd._values) == 0

    for lookup_idx in range(hd._size):
        data_idx, neighbors = hd._get_lookup_index_info(lookup_idx)
        assert data_idx == hd.FREE_ENTRY
        assert len(neighbors) == 0
Ejemplo n.º 25
0
def test_union():
    hd = HopscotchDict()
    keys = hd.keys()
    items = hd.items()

    hd["a"] = 1
    hd["b"] = 2
    hd["c"] = 3

    s1 = ["a", "b"]
    s2 = ["a", "b", "c", "d"]

    s3 = [1, 2]
    s4 = [1, 2, 3, 4]

    assert keys | set(s1) == keys
    assert keys.union(s2) == set(s2)

    assert items | zip(s1, s3) == items
    assert items.union(zip(s2, s4)) == set(list(zip(s2, s4)))
Ejemplo n.º 26
0
class HopscotchStateMachine(RuleBasedStateMachine):
    def __init__(self):
        super().__init__()
        self.d = HopscotchDict()

    def teardown(self):
        keys = list(self.d.keys())

        for key in keys:
            del self.d[key]

    @invariant()
    def valid_neighborhoods(self):
        for lookup_idx in range(self.d._size):
            _, neighbors = self.d._get_lookup_index_info(lookup_idx)
            for neighbor in neighbors:
                data_idx = self.d._get_lookup_index_info(neighbor)[0]
                assert abs(hash(self.d._keys[data_idx])) % self.d._size == lookup_idx

    @invariant()
    def no_missing_data(self):
        assert len(self.d._keys) == len(self.d._values)

    @invariant()
    def bounded_density(self):
        if self.d._count > 0:
            assert self.d._count / self.d._size <= self.d.MAX_DENSITY

    @rule(k=dict_keys, v=dict_values)
    def add_entry(self, k, v):
        self.d[k] = v

    @rule(k=dict_keys)
    def remove_entry(self, k):
        if k not in self.d._keys:
            with pytest.raises(KeyError):
                del self.d[k]
        else:
            del self.d[k]
Ejemplo n.º 27
0
def test_lookup_fails(scenario):
    hd = HopscotchDict()

    if scenario == "missing":
        assert hd._lookup("test_lookup") == (None, None)

    elif scenario == "free":
        hd[4] = "test_lookup"
        hd._set_lookup_index_info(4, data=hd.FREE_ENTRY)

        with pytest.raises(RuntimeError):
            hd._lookup(4)
Ejemplo n.º 28
0
def test_get_lookup_index_info(gen_dict, lookup_idx):
    hd = HopscotchDict(gen_dict)

    if lookup_idx < 0 or lookup_idx >= hd._size:
        with pytest.raises(ValueError):
            hd._get_lookup_index_info(lookup_idx)
    else:
        data_idx, neighbors = hd._get_lookup_index_info(lookup_idx)
        for idx in neighbors:
            data_idx, _ = hd._get_lookup_index_info(idx)
            assert abs(hash(hd._keys[data_idx])) % hd._size == lookup_idx
Ejemplo n.º 29
0
def test_popitem(gen_dict):
    hd = HopscotchDict()

    if not gen_dict:
        with pytest.raises(KeyError):
            hd.popitem()
    else:
        hd.update(gen_dict)

        key = hd._keys[-1]
        val = hd._values[-1]

        cur_len = len(hd)
        assert (key, val) == hd.popitem()
        assert len(hd) == cur_len - 1
        assert key not in hd
Ejemplo n.º 30
0
def test_get_open_neighbor(gen_dict, lookup_idx):
    hd = HopscotchDict(gen_dict)

    if lookup_idx < 0 or lookup_idx >= hd._size:
        with pytest.raises(ValueError):
            hd._get_open_neighbor(lookup_idx)
    else:
        open_idx = hd._get_open_neighbor(lookup_idx)
        for idx in range(
            lookup_idx, open_idx if open_idx is not None else lookup_idx + hd._nbhd_size
        ):
            data_idx, _ = hd._get_lookup_index_info(idx)
            assert data_idx != hd.FREE_ENTRY