mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
util/ht: add key-value pair iterator support (#6483)
--------- Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>
This commit is contained in:
parent
6f264e7019
commit
e33674578c
3 changed files with 90 additions and 0 deletions
|
|
@ -304,7 +304,9 @@ RZ_API void Ht_(free_iter_state)(RZ_NULLABLE HT_(IterState) *state);
|
||||||
RZ_API RZ_BORROW VALUE_TYPE *Ht_(iter_next_mut)(RzIterator *it);
|
RZ_API RZ_BORROW VALUE_TYPE *Ht_(iter_next_mut)(RzIterator *it);
|
||||||
RZ_API const VALUE_TYPE *Ht_(iter_next)(RzIterator *it);
|
RZ_API const VALUE_TYPE *Ht_(iter_next)(RzIterator *it);
|
||||||
RZ_API const KEY_TYPE *Ht_(iter_next_key)(RzIterator *it);
|
RZ_API const KEY_TYPE *Ht_(iter_next_key)(RzIterator *it);
|
||||||
|
RZ_API const HT_(Kv) *Ht_(iter_next_kv)(RzIterator *it);
|
||||||
|
|
||||||
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter_mut)(RZ_NONNULL HtName_(Ht) *ht);
|
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter_mut)(RZ_NONNULL HtName_(Ht) *ht);
|
||||||
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter)(const RZ_NONNULL HtName_(Ht) *ht);
|
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter)(const RZ_NONNULL HtName_(Ht) *ht);
|
||||||
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter_keys)(const RZ_NONNULL HtName_(Ht) *ht);
|
RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter_keys)(const RZ_NONNULL HtName_(Ht) *ht);
|
||||||
|
RZ_API RZ_OWN RzIterator /* <const HtName_(Ht)> */ *Ht_(as_iter_kv)(const RZ_NONNULL HtName_(Ht) *ht);
|
||||||
|
|
|
||||||
|
|
@ -1029,6 +1029,29 @@ RZ_API const KEY_TYPE *Ht_(iter_next_key)(RzIterator *it) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Advances the iterator \p it and yields the next immutable key-value pair.
|
||||||
|
*
|
||||||
|
* \param it The iterator instance.
|
||||||
|
*/
|
||||||
|
RZ_API const HT_(Kv) *Ht_(iter_next_kv)(RzIterator *it) {
|
||||||
|
rz_return_val_if_fail(it, NULL);
|
||||||
|
HT_(IterState) *state = it->u;
|
||||||
|
|
||||||
|
// Iterate over tables until a table with an element is found.
|
||||||
|
for (; state->ti < state->ht->capacity; state->ti++) {
|
||||||
|
if (H2_IS_EMPTY_OR_DELETED(state->ht->ctrl[state->ti])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
state->kv = HT_SLOT_AT(state->ht, state->ti);
|
||||||
|
state->ti++;
|
||||||
|
return state->kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iteration is done. No elements left to select.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RZ_API RZ_OWN HT_(IterMutState) *Ht_(new_iter_mut_state)(RZ_NONNULL HtName_(Ht) *ht) {
|
RZ_API RZ_OWN HT_(IterMutState) *Ht_(new_iter_mut_state)(RZ_NONNULL HtName_(Ht) *ht) {
|
||||||
rz_return_val_if_fail(ht, NULL);
|
rz_return_val_if_fail(ht, NULL);
|
||||||
HT_(IterMutState) *state = RZ_NEW0(HT_(IterMutState));
|
HT_(IterMutState) *state = RZ_NEW0(HT_(IterMutState));
|
||||||
|
|
@ -1112,3 +1135,22 @@ RZ_API RZ_OWN RzIterator /* <HtName_(Ht)> */ *Ht_(as_iter_keys)(const RZ_NONNULL
|
||||||
}
|
}
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns an iterator over the hash table \p ht. The iterator yields immutable key-value pairs.
|
||||||
|
*
|
||||||
|
* \param ht The hash table to create the iterator for.
|
||||||
|
*
|
||||||
|
* \return The iterator over the hash table key-value pairs or NULL in case of failure.
|
||||||
|
*/
|
||||||
|
RZ_API RZ_OWN RzIterator /* <const HtName_(Ht)> */ *Ht_(as_iter_kv)(const RZ_NONNULL HtName_(Ht) *ht) {
|
||||||
|
rz_return_val_if_fail(ht, NULL);
|
||||||
|
HT_(IterState) *state = Ht_(new_iter_state)(ht);
|
||||||
|
rz_return_val_if_fail(state, NULL);
|
||||||
|
|
||||||
|
RzIterator *iter = rz_iterator_new((rz_iterator_next_cb)Ht_(iter_next_kv), NULL, (rz_iterator_free_cb)Ht_(free_iter_state), state);
|
||||||
|
if (!iter) {
|
||||||
|
Ht_(free_iter_state)(state);
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -766,6 +766,51 @@ bool test_ht_uu_iter(void) {
|
||||||
mu_end;
|
mu_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool test_ht_uu_iter_kv(void) {
|
||||||
|
HtUU *ht = ht_uu_new();
|
||||||
|
ut32 icnt = 0;
|
||||||
|
const HtUUKv *kv;
|
||||||
|
|
||||||
|
RzIterator *it = ht_uu_as_iter_kv(ht);
|
||||||
|
rz_iterator_foreach(it, kv) {
|
||||||
|
icnt++;
|
||||||
|
}
|
||||||
|
rz_iterator_free(it);
|
||||||
|
mu_assert_eq(icnt, 0, "Wrong number of iterations");
|
||||||
|
|
||||||
|
ht_uu_insert(ht, 0x11, 0x1111);
|
||||||
|
ht_uu_insert(ht, 0x22, 0x2222);
|
||||||
|
ht_uu_insert(ht, 0x33, 0x3333);
|
||||||
|
|
||||||
|
bool found_1 = false;
|
||||||
|
bool found_2 = false;
|
||||||
|
bool found_3 = false;
|
||||||
|
|
||||||
|
icnt = 0;
|
||||||
|
it = ht_uu_as_iter_kv(ht);
|
||||||
|
rz_iterator_foreach(it, kv) {
|
||||||
|
icnt++;
|
||||||
|
if (kv->key == 0x11 && kv->value == 0x1111) {
|
||||||
|
found_1 = true;
|
||||||
|
}
|
||||||
|
if (kv->key == 0x22 && kv->value == 0x2222) {
|
||||||
|
found_2 = true;
|
||||||
|
}
|
||||||
|
if (kv->key == 0x33 && kv->value == 0x3333) {
|
||||||
|
found_3 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rz_iterator_free(it);
|
||||||
|
|
||||||
|
mu_assert_eq(icnt, 3, "Wrong number of iterations");
|
||||||
|
mu_assert_true(found_1, "key not found");
|
||||||
|
mu_assert_true(found_2, "key not found");
|
||||||
|
mu_assert_true(found_3, "key not found");
|
||||||
|
|
||||||
|
ht_uu_free(ht);
|
||||||
|
mu_end;
|
||||||
|
}
|
||||||
|
|
||||||
bool test_ht_ss_iter(void) {
|
bool test_ht_ss_iter(void) {
|
||||||
HtSS *ht = ht_ss_new(HT_STR_CONST, HT_STR_CONST);
|
HtSS *ht = ht_ss_new(HT_STR_CONST, HT_STR_CONST);
|
||||||
ut32 icnt = 0;
|
ut32 icnt = 0;
|
||||||
|
|
@ -992,6 +1037,7 @@ int all_tests() {
|
||||||
mu_run_test(test_insert_update_ex);
|
mu_run_test(test_insert_update_ex);
|
||||||
mu_run_test(test_ht_size);
|
mu_run_test(test_ht_size);
|
||||||
mu_run_test(test_ht_uu_iter);
|
mu_run_test(test_ht_uu_iter);
|
||||||
|
mu_run_test(test_ht_uu_iter_kv);
|
||||||
mu_run_test(test_ht_ss_iter);
|
mu_run_test(test_ht_ss_iter);
|
||||||
mu_run_test(test_set_u);
|
mu_run_test(test_set_u);
|
||||||
mu_run_test(test_set_s);
|
mu_run_test(test_set_s);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue