ds: hashmap: update iterator interface
This commit is contained in:
250
ds/hashmap.c
250
ds/hashmap.c
@@ -23,11 +23,22 @@ struct b_hashmap_bucket {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct b_hashmap_p {
|
struct b_hashmap_p {
|
||||||
|
size_t h_count;
|
||||||
struct b_btree h_buckets;
|
struct b_btree h_buckets;
|
||||||
b_hashmap_key_destructor h_key_dtor;
|
b_hashmap_key_destructor h_key_dtor;
|
||||||
b_hashmap_value_destructor h_value_dtor;
|
b_hashmap_value_destructor h_value_dtor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct b_hashmap_iterator_p {
|
||||||
|
size_t i;
|
||||||
|
b_hashmap_item item;
|
||||||
|
|
||||||
|
b_hashmap *_h;
|
||||||
|
struct b_hashmap_p *_h_p;
|
||||||
|
b_btree_node *_cbn;
|
||||||
|
b_queue_entry *_cqe;
|
||||||
|
};
|
||||||
|
|
||||||
/*** PRIVATE FUNCTIONS ********************************************************/
|
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
static B_BTREE_DEFINE_SIMPLE_GET(
|
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||||
@@ -174,15 +185,17 @@ static b_status hashmap_put(
|
|||||||
put_bucket(&hashmap->h_buckets, bucket);
|
put_bucket(&hashmap->h_buckets, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator it;
|
struct b_queue_entry *entry = b_queue_first(&bucket->bk_items);
|
||||||
b_queue_foreach (&it, &bucket->bk_items) {
|
while (entry) {
|
||||||
struct b_hashmap_bucket_item *item = b_unbox(
|
struct b_hashmap_bucket_item *item
|
||||||
struct b_hashmap_bucket_item, it.entry, bi_entry);
|
= b_unbox(struct b_hashmap_bucket_item, entry, bi_entry);
|
||||||
|
|
||||||
if (compare_key(&item->bi_key, key)) {
|
if (compare_key(&item->bi_key, key)) {
|
||||||
memcpy(&item->bi_value, value, sizeof *value);
|
memcpy(&item->bi_value, value, sizeof *value);
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_hashmap_bucket_item *item = create_bucket_item();
|
struct b_hashmap_bucket_item *item = create_bucket_item();
|
||||||
@@ -194,6 +207,7 @@ static b_status hashmap_put(
|
|||||||
memcpy(&item->bi_value, value, sizeof *value);
|
memcpy(&item->bi_value, value, sizeof *value);
|
||||||
|
|
||||||
b_queue_push_back(&bucket->bk_items, &item->bi_entry);
|
b_queue_push_back(&bucket->bk_items, &item->bi_entry);
|
||||||
|
hashmap->h_count++;
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -208,14 +222,16 @@ static const struct b_hashmap_value *hashmap_get(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator it;
|
struct b_queue_entry *entry = b_queue_first(&bucket->bk_items);
|
||||||
b_queue_foreach (&it, &bucket->bk_items) {
|
while (entry) {
|
||||||
struct b_hashmap_bucket_item *item = b_unbox(
|
struct b_hashmap_bucket_item *item
|
||||||
struct b_hashmap_bucket_item, it.entry, bi_entry);
|
= b_unbox(struct b_hashmap_bucket_item, entry, bi_entry);
|
||||||
|
|
||||||
if (compare_key(&item->bi_key, key)) {
|
if (compare_key(&item->bi_key, key)) {
|
||||||
return &item->bi_value;
|
return &item->bi_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -230,14 +246,16 @@ static bool hashmap_has_key(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator it;
|
struct b_queue_entry *entry = b_queue_first(&bucket->bk_items);
|
||||||
b_queue_foreach (&it, &bucket->bk_items) {
|
while (entry) {
|
||||||
struct b_hashmap_bucket_item *item = b_unbox(
|
struct b_hashmap_bucket_item *item
|
||||||
struct b_hashmap_bucket_item, it.entry, bi_entry);
|
= b_unbox(struct b_hashmap_bucket_item, entry, bi_entry);
|
||||||
|
|
||||||
if (compare_key(&item->bi_key, key)) {
|
if (compare_key(&item->bi_key, key)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -245,19 +263,7 @@ static bool hashmap_has_key(
|
|||||||
|
|
||||||
static size_t hashmap_get_size(const struct b_hashmap_p *hashmap)
|
static size_t hashmap_get_size(const struct b_hashmap_p *hashmap)
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
return hashmap->h_count;
|
||||||
b_btree_iterator it1;
|
|
||||||
b_queue_iterator it2;
|
|
||||||
b_btree_foreach (&it1, &hashmap->h_buckets) {
|
|
||||||
struct b_hashmap_bucket *bucket
|
|
||||||
= b_unbox(struct b_hashmap_bucket, it1.node, bk_node);
|
|
||||||
|
|
||||||
b_queue_foreach (&it2, &bucket->bk_items) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hashmap_is_empty(const struct b_hashmap_p *hashmap)
|
static bool hashmap_is_empty(const struct b_hashmap_p *hashmap)
|
||||||
@@ -300,6 +306,7 @@ static b_status delete_item(
|
|||||||
free(bucket);
|
free(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hashmap->h_count--;
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,19 +377,19 @@ static void hashmap_fini(b_object *obj, void *priv)
|
|||||||
{
|
{
|
||||||
struct b_hashmap_p *map = priv;
|
struct b_hashmap_p *map = priv;
|
||||||
|
|
||||||
b_btree_iterator it1;
|
struct b_btree_node *node = b_btree_first(&map->h_buckets);
|
||||||
b_btree_iterator_begin(&map->h_buckets, &it1);
|
while (node) {
|
||||||
while (b_btree_iterator_is_valid(&it1)) {
|
|
||||||
struct b_hashmap_bucket *b
|
struct b_hashmap_bucket *b
|
||||||
= b_unbox(struct b_hashmap_bucket, it1.node, bk_node);
|
= b_unbox(struct b_hashmap_bucket, node, bk_node);
|
||||||
b_btree_iterator_erase(&it1);
|
struct b_btree_node *next_node = b_btree_next(node);
|
||||||
|
b_btree_delete(&map->h_buckets, node);
|
||||||
|
|
||||||
b_queue_iterator it2;
|
struct b_queue_entry *entry = b_queue_first(&b->bk_items);
|
||||||
b_queue_iterator_begin(&b->bk_items, &it2);
|
while (entry) {
|
||||||
while (b_queue_iterator_is_valid(&it2)) {
|
|
||||||
struct b_hashmap_bucket_item *item = b_unbox(
|
struct b_hashmap_bucket_item *item = b_unbox(
|
||||||
struct b_hashmap_bucket_item, it2.entry, bi_entry);
|
struct b_hashmap_bucket_item, entry, bi_entry);
|
||||||
b_queue_iterator_erase(&it2);
|
struct b_queue_entry *next_entry = b_queue_next(entry);
|
||||||
|
b_queue_delete(&b->bk_items, entry);
|
||||||
|
|
||||||
if (map->h_key_dtor) {
|
if (map->h_key_dtor) {
|
||||||
map->h_key_dtor((void *)item->bi_key.key_data);
|
map->h_key_dtor((void *)item->bi_key.key_data);
|
||||||
@@ -393,85 +400,52 @@ static void hashmap_fini(b_object *obj, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(item);
|
free(item);
|
||||||
|
entry = next_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(b);
|
free(b);
|
||||||
|
node = next_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CLASS DEFINITION *********************************************************/
|
|
||||||
|
|
||||||
B_TYPE_CLASS_DEFINITION_BEGIN(b_hashmap)
|
|
||||||
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
|
||||||
B_INTERFACE_ENTRY(to_string) = NULL;
|
|
||||||
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
|
|
||||||
B_TYPE_CLASS_DEFINITION_END(b_hashmap)
|
|
||||||
|
|
||||||
B_TYPE_DEFINITION_BEGIN(b_hashmap)
|
|
||||||
B_TYPE_ID(0x7bf5bcd1, 0x1ff3, 0x4e43, 0xbed8, 0x7c74f28348bf);
|
|
||||||
B_TYPE_CLASS(b_hashmap_class);
|
|
||||||
B_TYPE_INSTANCE_PRIVATE(struct b_hashmap_p);
|
|
||||||
B_TYPE_INSTANCE_INIT(hashmap_init);
|
|
||||||
B_TYPE_INSTANCE_FINI(hashmap_fini);
|
|
||||||
B_TYPE_DEFINITION_END(b_hashmap)
|
|
||||||
|
|
||||||
/*** ITERATOR FUNCTIONS *******************************************************/
|
/*** ITERATOR FUNCTIONS *******************************************************/
|
||||||
|
|
||||||
static bool hashmap_iterator_next(struct b_iterator *it)
|
static b_iterator *iterable_begin(b_hashmap *hashmap)
|
||||||
{
|
{
|
||||||
return b_hashmap_iterator_next((struct b_hashmap_iterator *)it);
|
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);
|
||||||
|
|
||||||
static b_status hashmap_iterator_erase(struct b_iterator *it)
|
|
||||||
{
|
|
||||||
return b_hashmap_iterator_erase((struct b_hashmap_iterator *)it);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool hashmap_iterator_is_valid(const struct b_iterator *it)
|
|
||||||
{
|
|
||||||
return b_hashmap_iterator_is_valid((struct b_hashmap_iterator *)it);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct b_iterator_ops it_ops = {
|
|
||||||
.it_next = hashmap_iterator_next,
|
|
||||||
.it_erase = hashmap_iterator_erase,
|
|
||||||
.it_close = NULL,
|
|
||||||
.it_is_valid = hashmap_iterator_is_valid,
|
|
||||||
};
|
|
||||||
|
|
||||||
int b_hashmap_iterator_begin(b_hashmap *hashmap, struct b_hashmap_iterator *it)
|
|
||||||
{
|
|
||||||
it->_h = hashmap;
|
it->_h = hashmap;
|
||||||
it->_h_p = b_object_get_private(hashmap, B_TYPE_HASHMAP);
|
it->_h_p = b_object_get_private(hashmap, B_TYPE_HASHMAP);
|
||||||
it->_base.it_ops = &it_ops;
|
|
||||||
|
|
||||||
it->i = 0;
|
it->i = 0;
|
||||||
if (b_hashmap_is_empty(hashmap)) {
|
if (b_hashmap_is_empty(hashmap)) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
b_iterator_set_status(it_obj, B_ERR_NO_DATA);
|
||||||
return -1;
|
return it_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_btree_node *first_node = b_btree_first(&it->_h_p->h_buckets);
|
struct b_btree_node *first_node = b_btree_first(&it->_h_p->h_buckets);
|
||||||
struct b_hashmap_bucket *first_bucket
|
struct b_hashmap_bucket *first_bucket
|
||||||
= b_unbox(struct b_hashmap_bucket, first_node, bk_node);
|
= b_unbox(struct b_hashmap_bucket, first_node, bk_node);
|
||||||
if (!first_bucket) {
|
if (!first_bucket) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
b_iterator_set_status(it_obj, B_ERR_NO_DATA);
|
||||||
return -1;
|
return it_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_queue_entry *first_entry = b_queue_first(&first_bucket->bk_items);
|
struct b_queue_entry *first_entry = b_queue_first(&first_bucket->bk_items);
|
||||||
struct b_hashmap_bucket_item *first_item
|
struct b_hashmap_bucket_item *first_item
|
||||||
= b_unbox(struct b_hashmap_bucket_item, first_entry, bi_entry);
|
= b_unbox(struct b_hashmap_bucket_item, first_entry, bi_entry);
|
||||||
if (!first_item) {
|
if (!first_item) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
b_iterator_set_status(it_obj, B_ERR_NO_DATA);
|
||||||
return -1;
|
return it_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
it->key = &first_item->bi_key;
|
memcpy(&it->item.key, &first_item->bi_key, sizeof it->item.key);
|
||||||
it->value = &first_item->bi_value;
|
memcpy(&it->item.value, &first_item->bi_value, sizeof it->item.value);
|
||||||
|
|
||||||
it->_cbn = first_node;
|
it->_cbn = first_node;
|
||||||
it->_cqe = first_entry;
|
it->_cqe = first_entry;
|
||||||
@@ -479,28 +453,34 @@ int b_hashmap_iterator_begin(b_hashmap *hashmap, struct b_hashmap_iterator *it)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool b_hashmap_iterator_next(struct b_hashmap_iterator *it)
|
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
|
||||||
|
= b_object_get_private(obj, B_TYPE_HASHMAP_ITERATOR);
|
||||||
|
|
||||||
struct b_btree_node *next_node;
|
struct b_btree_node *next_node;
|
||||||
struct b_queue_entry *next_entry;
|
struct b_queue_entry *next_entry;
|
||||||
if (!get_next_node(it->_cbn, it->_cqe, &next_node, &next_entry)) {
|
if (!get_next_node(it->_cbn, it->_cqe, &next_node, &next_entry)) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
return B_ERR_NO_DATA;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_hashmap_bucket_item *next_item
|
struct b_hashmap_bucket_item *next_item
|
||||||
= b_unbox(struct b_hashmap_bucket_item, next_entry, bi_entry);
|
= b_unbox(struct b_hashmap_bucket_item, next_entry, bi_entry);
|
||||||
|
|
||||||
if (!next_item) {
|
if (!next_item) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
return B_ERR_NO_DATA;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it->i++;
|
it->i++;
|
||||||
it->key = &next_item->bi_key;
|
memcpy(&it->item.key, &next_item->bi_key, sizeof it->item.key);
|
||||||
it->value = &next_item->bi_value;
|
memcpy(&it->item.value, &next_item->bi_value, sizeof it->item.value);
|
||||||
|
|
||||||
it->_cbn = next_node;
|
it->_cbn = next_node;
|
||||||
it->_cqe = next_entry;
|
it->_cqe = next_entry;
|
||||||
@@ -508,22 +488,25 @@ bool b_hashmap_iterator_next(struct b_hashmap_iterator *it)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_status b_hashmap_iterator_erase(struct b_hashmap_iterator *it)
|
static enum b_status iterator_erase(b_iterator *obj)
|
||||||
{
|
{
|
||||||
if ((it->key || it->value) && !(it->_cbn && it->_cqe)) {
|
struct b_hashmap_iterator_p *it
|
||||||
|
= b_object_get_private(obj, B_TYPE_HASHMAP_ITERATOR);
|
||||||
|
|
||||||
|
if ((it->item.key.key_data || it->item.value.value_data)
|
||||||
|
&& !(it->_cbn && it->_cqe)) {
|
||||||
return B_ERR_BAD_STATE;
|
return B_ERR_BAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!it->key || !it->_cqe) {
|
if (!it->item.key.key_data || !it->_cqe) {
|
||||||
return B_ERR_OUT_OF_BOUNDS;
|
return B_ERR_NO_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_btree_node *next_node;
|
struct b_btree_node *next_node;
|
||||||
struct b_queue_entry *next_entry;
|
struct b_queue_entry *next_entry;
|
||||||
if (!get_next_node(it->_cbn, it->_cqe, &next_node, &next_entry)) {
|
if (!get_next_node(it->_cbn, it->_cqe, &next_node, &next_entry)) {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
return B_ERR_NO_DATA;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_hashmap_bucket *cur_bucket
|
struct b_hashmap_bucket *cur_bucket
|
||||||
@@ -540,14 +523,14 @@ b_status b_hashmap_iterator_erase(struct b_hashmap_iterator *it)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (next_item) {
|
if (next_item) {
|
||||||
it->key = &next_item->bi_key;
|
memcpy(&it->item.key, &next_item->bi_key, sizeof it->item.key);
|
||||||
it->value = &next_item->bi_value;
|
memcpy(&it->item.value, &next_item->bi_value,
|
||||||
|
sizeof it->item.value);
|
||||||
|
|
||||||
it->_cbn = next_node;
|
it->_cbn = next_node;
|
||||||
it->_cqe = next_entry;
|
it->_cqe = next_entry;
|
||||||
} else {
|
} else {
|
||||||
it->key = NULL;
|
memset(&it->item, 0x0, sizeof it->item);
|
||||||
it->value = NULL;
|
|
||||||
|
|
||||||
it->_cbn = NULL;
|
it->_cbn = NULL;
|
||||||
it->_cqe = NULL;
|
it->_cqe = NULL;
|
||||||
@@ -556,7 +539,60 @@ b_status b_hashmap_iterator_erase(struct b_hashmap_iterator *it)
|
|||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool b_hashmap_iterator_is_valid(const struct b_hashmap_iterator *it)
|
static b_iterator_value iterator_get_value(b_iterator *obj)
|
||||||
{
|
{
|
||||||
return it->key != NULL;
|
struct b_hashmap_iterator_p *it
|
||||||
|
= b_object_get_private(obj, B_TYPE_HASHMAP_ITERATOR);
|
||||||
|
return B_ITERATOR_VALUE_PTR(&it->item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const b_iterator_value iterator_get_cvalue(const b_iterator *obj)
|
||||||
|
{
|
||||||
|
const struct b_hashmap_iterator_p *it
|
||||||
|
= b_object_get_private(obj, B_TYPE_HASHMAP_ITERATOR);
|
||||||
|
return B_ITERATOR_VALUE_CPTR(&it->item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
// ---- b_hashmap DEFINITION
|
||||||
|
B_TYPE_CLASS_DEFINITION_BEGIN(b_hashmap)
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
||||||
|
B_INTERFACE_ENTRY(to_string) = NULL;
|
||||||
|
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_TYPE_CLASS_INTERFACE_END(b_iterable, B_TYPE_ITERABLE)
|
||||||
|
B_TYPE_CLASS_DEFINITION_END(b_hashmap)
|
||||||
|
|
||||||
|
B_TYPE_DEFINITION_BEGIN(b_hashmap)
|
||||||
|
B_TYPE_ID(0x7bf5bcd1, 0x1ff3, 0x4e43, 0xbed8, 0x7c74f28348bf);
|
||||||
|
B_TYPE_CLASS(b_hashmap_class);
|
||||||
|
B_TYPE_IMPLEMENTS(B_TYPE_ITERABLE);
|
||||||
|
B_TYPE_INSTANCE_PRIVATE(struct b_hashmap_p);
|
||||||
|
B_TYPE_INSTANCE_INIT(hashmap_init);
|
||||||
|
B_TYPE_INSTANCE_FINI(hashmap_fini);
|
||||||
|
B_TYPE_DEFINITION_END(b_hashmap)
|
||||||
|
|
||||||
|
// ---- b_hashmap_iterator DEFINITION
|
||||||
|
B_TYPE_CLASS_DEFINITION_BEGIN(b_hashmap_iterator)
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
||||||
|
B_INTERFACE_ENTRY(to_string) = NULL;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
|
||||||
|
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR)
|
||||||
|
B_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
|
||||||
|
B_INTERFACE_ENTRY(it_erase) = iterator_erase;
|
||||||
|
B_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
|
||||||
|
B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR)
|
||||||
|
B_TYPE_CLASS_DEFINITION_END(b_hashmap_iterator)
|
||||||
|
|
||||||
|
B_TYPE_DEFINITION_BEGIN(b_hashmap_iterator)
|
||||||
|
B_TYPE_ID(0xd9658456, 0xdd80, 0x419a, 0xb23a, 0xb513013e6431);
|
||||||
|
B_TYPE_EXTENDS(B_TYPE_ITERATOR);
|
||||||
|
B_TYPE_CLASS(b_hashmap_iterator_class);
|
||||||
|
B_TYPE_INSTANCE_PRIVATE(struct b_hashmap_iterator_p);
|
||||||
|
B_TYPE_DEFINITION_END(b_hashmap_iterator)
|
||||||
|
|||||||
@@ -13,12 +13,17 @@ B_DECLS_BEGIN;
|
|||||||
struct b_hashmap_p;
|
struct b_hashmap_p;
|
||||||
|
|
||||||
#define B_TYPE_HASHMAP (b_hashmap_get_type())
|
#define B_TYPE_HASHMAP (b_hashmap_get_type())
|
||||||
|
#define B_TYPE_HASHMAP_ITERATOR (b_hashmap_iterator_get_type())
|
||||||
|
|
||||||
B_DECLARE_TYPE(b_hashmap);
|
B_DECLARE_TYPE(b_hashmap);
|
||||||
|
B_DECLARE_TYPE(b_hashmap_iterator);
|
||||||
|
|
||||||
B_TYPE_CLASS_DECLARATION_BEGIN(b_hashmap)
|
B_TYPE_CLASS_DECLARATION_BEGIN(b_hashmap)
|
||||||
B_TYPE_CLASS_DECLARATION_END(b_hashmap)
|
B_TYPE_CLASS_DECLARATION_END(b_hashmap)
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DECLARATION_BEGIN(b_hashmap_iterator)
|
||||||
|
B_TYPE_CLASS_DECLARATION_END(b_hashmap_iterator)
|
||||||
|
|
||||||
#define B_HASHMAP_KEY(k, ks) {.key_data = (k), .key_size = (ks)}
|
#define B_HASHMAP_KEY(k, ks) {.key_data = (k), .key_size = (ks)}
|
||||||
#define B_HASHMAP_VALUE(v, vs) {.value_data = (v), .value_size = (vs)}
|
#define B_HASHMAP_VALUE(v, vs) {.value_data = (v), .value_size = (vs)}
|
||||||
|
|
||||||
@@ -54,19 +59,8 @@ typedef struct b_hashmap_item {
|
|||||||
b_hashmap_value value;
|
b_hashmap_value value;
|
||||||
} b_hashmap_item;
|
} b_hashmap_item;
|
||||||
|
|
||||||
typedef struct b_hashmap_iterator {
|
|
||||||
b_iterator _base;
|
|
||||||
size_t i;
|
|
||||||
const b_hashmap_key *key;
|
|
||||||
const b_hashmap_value *value;
|
|
||||||
|
|
||||||
b_hashmap *_h;
|
|
||||||
struct b_hashmap_p *_h_p;
|
|
||||||
b_btree_node *_cbn;
|
|
||||||
b_queue_entry *_cqe;
|
|
||||||
} b_hashmap_iterator;
|
|
||||||
|
|
||||||
BLUE_API b_type b_hashmap_get_type(void);
|
BLUE_API b_type b_hashmap_get_type(void);
|
||||||
|
BLUE_API b_type b_hashmap_iterator_get_type(void);
|
||||||
|
|
||||||
BLUE_API b_hashmap *b_hashmap_create(
|
BLUE_API b_hashmap *b_hashmap_create(
|
||||||
b_hashmap_key_destructor key_dtor, b_hashmap_value_destructor value_dtor);
|
b_hashmap_key_destructor key_dtor, b_hashmap_value_destructor value_dtor);
|
||||||
@@ -81,11 +75,6 @@ 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 int b_hashmap_iterator_begin(b_hashmap *hashmap, b_hashmap_iterator *it);
|
|
||||||
BLUE_API bool b_hashmap_iterator_next(b_hashmap_iterator *it);
|
|
||||||
BLUE_API b_status b_hashmap_iterator_erase(b_hashmap_iterator *it);
|
|
||||||
BLUE_API bool b_hashmap_iterator_is_valid(const b_hashmap_iterator *it);
|
|
||||||
|
|
||||||
B_DECLS_END;
|
B_DECLS_END;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user