diff --git a/ds/hashmap.c b/ds/hashmap.c index 5da6739..596e9fd 100644 --- a/ds/hashmap.c +++ b/ds/hashmap.c @@ -366,6 +366,54 @@ bool b_hashmap_is_empty(const b_hashmap *hashmap) B_CLASS_DISPATCH_STATIC_0(B_TYPE_HASHMAP, hashmap_is_empty, hashmap); } +b_iterator *b_hashmap_begin(b_hashmap *hashmap) +{ + b_hashmap_iterator *it_obj = b_object_create(B_TYPE_HASHMAP_ITERATOR); + struct b_hashmap_iterator_p *it + = b_object_get_private(it_obj, B_TYPE_HASHMAP_ITERATOR); + + it->_h = hashmap; + it->_h_p = b_object_get_private(hashmap, B_TYPE_HASHMAP); + + it->i = 0; + if (b_hashmap_is_empty(hashmap)) { + memset(&it->item, 0x0, sizeof it->item); + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + return it_obj; + } + + struct b_btree_node *first_node = b_btree_first(&it->_h_p->h_buckets); + struct b_hashmap_bucket *first_bucket + = b_unbox(struct b_hashmap_bucket, first_node, bk_node); + if (!first_bucket) { + memset(&it->item, 0x0, sizeof it->item); + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + return it_obj; + } + + struct b_queue_entry *first_entry = b_queue_first(&first_bucket->bk_items); + struct b_hashmap_bucket_item *first_item + = b_unbox(struct b_hashmap_bucket_item, first_entry, bi_entry); + if (!first_item) { + memset(&it->item, 0x0, sizeof it->item); + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + return it_obj; + } + + memcpy(&it->item.key, &first_item->bi_key, sizeof it->item.key); + memcpy(&it->item.value, &first_item->bi_value, sizeof it->item.value); + + it->_cbn = first_node; + it->_cqe = first_entry; + + return it_obj; +} + +const b_iterator *b_hashmap_cbegin(const b_hashmap *hashmap) +{ + return b_hashmap_begin((b_hashmap *)hashmap); +} + /*** VIRTUAL FUNCTIONS ********************************************************/ static void hashmap_init(b_object *obj, void *priv) @@ -410,54 +458,6 @@ static void hashmap_fini(b_object *obj, void *priv) /*** ITERATOR FUNCTIONS *******************************************************/ -static b_iterator *iterable_begin(b_hashmap *hashmap) -{ - b_hashmap_iterator *it_obj = b_object_create(B_TYPE_HASHMAP_ITERATOR); - struct b_hashmap_iterator_p *it - = b_object_get_private(it_obj, B_TYPE_HASHMAP_ITERATOR); - - it->_h = hashmap; - it->_h_p = b_object_get_private(hashmap, B_TYPE_HASHMAP); - - it->i = 0; - if (b_hashmap_is_empty(hashmap)) { - memset(&it->item, 0x0, sizeof it->item); - b_iterator_set_status(it_obj, B_ERR_NO_DATA); - return it_obj; - } - - struct b_btree_node *first_node = b_btree_first(&it->_h_p->h_buckets); - struct b_hashmap_bucket *first_bucket - = b_unbox(struct b_hashmap_bucket, first_node, bk_node); - if (!first_bucket) { - memset(&it->item, 0x0, sizeof it->item); - b_iterator_set_status(it_obj, B_ERR_NO_DATA); - return it_obj; - } - - struct b_queue_entry *first_entry = b_queue_first(&first_bucket->bk_items); - struct b_hashmap_bucket_item *first_item - = b_unbox(struct b_hashmap_bucket_item, first_entry, bi_entry); - if (!first_item) { - memset(&it->item, 0x0, sizeof it->item); - b_iterator_set_status(it_obj, B_ERR_NO_DATA); - return it_obj; - } - - memcpy(&it->item.key, &first_item->bi_key, sizeof it->item.key); - memcpy(&it->item.value, &first_item->bi_value, sizeof it->item.value); - - it->_cbn = first_node; - it->_cqe = first_entry; - - return 0; -} - -static const b_iterator *iterable_cbegin(const b_hashmap *hashmap) -{ - return iterable_begin((b_hashmap *)hashmap); -} - static enum b_status iterator_move_next(const b_iterator *obj) { struct b_hashmap_iterator_p *it @@ -485,7 +485,7 @@ static enum b_status iterator_move_next(const b_iterator *obj) it->_cbn = next_node; it->_cqe = next_entry; - return true; + return B_SUCCESS; } static enum b_status iterator_erase(b_iterator *obj) @@ -562,8 +562,8 @@ B_TYPE_CLASS_DEFINITION_BEGIN(b_hashmap) B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_BEGIN(b_iterable, B_TYPE_ITERABLE) - B_INTERFACE_ENTRY(it_begin) = iterable_begin; - B_INTERFACE_ENTRY(it_cbegin) = iterable_cbegin; + B_INTERFACE_ENTRY(it_begin) = b_hashmap_begin; + B_INTERFACE_ENTRY(it_cbegin) = b_hashmap_cbegin; B_TYPE_CLASS_INTERFACE_END(b_iterable, B_TYPE_ITERABLE) B_TYPE_CLASS_DEFINITION_END(b_hashmap) diff --git a/ds/include/blue/ds/hashmap.h b/ds/include/blue/ds/hashmap.h index 1603968..04063b6 100644 --- a/ds/include/blue/ds/hashmap.h +++ b/ds/include/blue/ds/hashmap.h @@ -75,6 +75,9 @@ BLUE_API bool b_hashmap_has_key(const b_hashmap *hashmap, const b_hashmap_key *k BLUE_API size_t b_hashmap_get_size(const b_hashmap *hashmap); BLUE_API bool b_hashmap_is_empty(const b_hashmap *hashmap); +BLUE_API b_iterator *b_hashmap_begin(b_hashmap *hashmap); +BLUE_API const b_iterator *b_hashmap_cbegin(const b_hashmap *hashmap); + B_DECLS_END; #endif