ds: hashmap: update iterator interface
This commit is contained in:
102
ds/hashmap.c
102
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_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 ********************************************************/
|
/*** VIRTUAL FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
static void hashmap_init(b_object *obj, void *priv)
|
static void hashmap_init(b_object *obj, void *priv)
|
||||||
@@ -410,54 +458,6 @@ static void hashmap_fini(b_object *obj, void *priv)
|
|||||||
|
|
||||||
/*** ITERATOR FUNCTIONS *******************************************************/
|
/*** 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)
|
static enum b_status iterator_move_next(const b_iterator *obj)
|
||||||
{
|
{
|
||||||
struct b_hashmap_iterator_p *it
|
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->_cbn = next_node;
|
||||||
it->_cqe = next_entry;
|
it->_cqe = next_entry;
|
||||||
|
|
||||||
return true;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status iterator_erase(b_iterator *obj)
|
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_END(b_object, B_TYPE_OBJECT)
|
||||||
|
|
||||||
B_TYPE_CLASS_INTERFACE_BEGIN(b_iterable, B_TYPE_ITERABLE)
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_iterable, B_TYPE_ITERABLE)
|
||||||
B_INTERFACE_ENTRY(it_begin) = iterable_begin;
|
B_INTERFACE_ENTRY(it_begin) = b_hashmap_begin;
|
||||||
B_INTERFACE_ENTRY(it_cbegin) = iterable_cbegin;
|
B_INTERFACE_ENTRY(it_cbegin) = b_hashmap_cbegin;
|
||||||
B_TYPE_CLASS_INTERFACE_END(b_iterable, B_TYPE_ITERABLE)
|
B_TYPE_CLASS_INTERFACE_END(b_iterable, B_TYPE_ITERABLE)
|
||||||
B_TYPE_CLASS_DEFINITION_END(b_hashmap)
|
B_TYPE_CLASS_DEFINITION_END(b_hashmap)
|
||||||
|
|
||||||
|
|||||||
@@ -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 size_t b_hashmap_get_size(const b_hashmap *hashmap);
|
||||||
BLUE_API bool b_hashmap_is_empty(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;
|
B_DECLS_END;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user