Add iterator API
This commit is contained in:
@@ -39,6 +39,15 @@ struct UHTable {
|
|||||||
struct UHNode **buckets;
|
struct UHNode **buckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Iterator for the iterator API */
|
||||||
|
struct UHIter {
|
||||||
|
//internal fields
|
||||||
|
struct UHNode **it;
|
||||||
|
struct UHNode **next;
|
||||||
|
size_t cur_bucket;
|
||||||
|
size_t cur_hash;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a hash table.
|
* Initialize a hash table.
|
||||||
* @param table hash table to initialize
|
* @param table hash table to initialize
|
||||||
@@ -246,4 +255,32 @@ void uc_htable_remove(struct UHTable *table, struct UHNode *node);
|
|||||||
int uc_htable_resize(struct UHTable *table, size_t buckets);
|
int uc_htable_resize(struct UHTable *table, size_t buckets);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get the first node with the given hash.
|
||||||
|
*
|
||||||
|
* @param table table
|
||||||
|
* @param iter opaque iterator
|
||||||
|
* @param hash hash to find
|
||||||
|
* @return the first node found or NULL
|
||||||
|
*/
|
||||||
|
struct UHNode *uc_htable_iter_first_hash(struct UHTable *table,
|
||||||
|
struct UHIter *iter, size_t hash);
|
||||||
|
/** Get the next node with the given hash, the iterator
|
||||||
|
* must previously have been passed to uc_htable_iter_first_hash
|
||||||
|
* which returned a non-NULL value
|
||||||
|
*
|
||||||
|
* @param iter opaque iterator
|
||||||
|
* @return the next node found or NULL
|
||||||
|
*/
|
||||||
|
struct UHNode *uc_htable_iter_next_hash(struct UHIter *iter);
|
||||||
|
|
||||||
|
/** Remove the node pointed to by the current iterator,
|
||||||
|
* uc_htable_iter_first_hash or uc_htable_iter_next_hash
|
||||||
|
* must previously have returned non-NULL. The node
|
||||||
|
* returned by the previous call is the one removed.
|
||||||
|
* It is safe to continue iterating after this
|
||||||
|
*
|
||||||
|
* @param iter indicated node to remove
|
||||||
|
*/
|
||||||
|
void uc_htable_iter_remove(struct UHIter *iter);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -171,3 +171,47 @@ int uc_htable_resize(struct UHTable *table, size_t buckets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct UHNode *uc_htable_iter_first_hash(struct UHTable *table,
|
||||||
|
struct UHIter *iter, size_t hash)
|
||||||
|
{
|
||||||
|
size_t bucket = uc_htable_bucket(table, hash);
|
||||||
|
struct UHNode **it= &table->buckets[bucket];
|
||||||
|
|
||||||
|
while (*it) {
|
||||||
|
if ((*it)->hash == hash) {
|
||||||
|
iter->it = it;
|
||||||
|
iter->cur_bucket = bucket;
|
||||||
|
iter->cur_hash = (*it)->hash;
|
||||||
|
iter->next = &(*it)->next;
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = &(*it)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UHNode *uc_htable_iter_next_hash(struct UHIter *iter)
|
||||||
|
{
|
||||||
|
struct UHNode **it = iter->next;
|
||||||
|
|
||||||
|
while (*it) {
|
||||||
|
if ((*it)->hash == iter->cur_hash) {
|
||||||
|
iter->it = it;
|
||||||
|
iter->next = &(*it)->next;
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
it = &(*it)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uc_htable_iter_remove(struct UHIter *iter)
|
||||||
|
{
|
||||||
|
if (*iter->it) {
|
||||||
|
*iter->it = *iter->next;
|
||||||
|
iter->it = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user