/* callback to a compare function. should compare 2 element data for their * keys * * Return: true if same and false if not same
*/ typedefbool (*batadv_hashdata_compare_cb)(conststruct hlist_node *, constvoid *);
/* the hashfunction * * Return: an index based on the key in the data of the first argument and the * size the second
*/ typedef u32 (*batadv_hashdata_choose_cb)(constvoid *, u32); typedefvoid (*batadv_hashdata_free_cb)(struct hlist_node *, void *);
/** * struct batadv_hashtable - Wrapper of simple hlist based hashtable
*/ struct batadv_hashtable { /** @table: the hashtable itself with the buckets */ struct hlist_head *table;
/** @list_locks: spinlock for each hash list entry */
spinlock_t *list_locks;
/** @size: size of hashtable */
u32 size;
/** @generation: current (generation) sequence number */
atomic_t generation;
};
/* allocates and clears the hash */ struct batadv_hashtable *batadv_hash_new(u32 size);
/* set class key for all locks */ void batadv_hash_set_lock_class(struct batadv_hashtable *hash, struct lock_class_key *key);
/* free only the hashtable and the hash itself. */ void batadv_hash_destroy(struct batadv_hashtable *hash);
/** * batadv_hash_add() - adds data to the hashtable * @hash: storage hash table * @compare: callback to determine if 2 hash elements are identical * @choose: callback calculating the hash index * @data: data passed to the aforementioned callbacks as argument * @data_node: to be added element * * Return: 0 on success, 1 if the element already is in the hash * and -1 on error.
*/ staticinlineint batadv_hash_add(struct batadv_hashtable *hash,
batadv_hashdata_compare_cb compare,
batadv_hashdata_choose_cb choose, constvoid *data, struct hlist_node *data_node)
{
u32 index; int ret = -1; struct hlist_head *head; struct hlist_node *node;
spinlock_t *list_lock; /* spinlock to protect write access */
if (!hash) goto out;
index = choose(data, hash->size);
head = &hash->table[index];
list_lock = &hash->list_locks[index];
spin_lock_bh(list_lock);
hlist_for_each(node, head) { if (!compare(node, data)) continue;
ret = 1; goto unlock;
}
/* no duplicate found in list, add new element */
hlist_add_head_rcu(data_node, head);
atomic_inc(&hash->generation);
/** * batadv_hash_remove() - Removes data from hash, if found * @hash: hash table * @compare: callback to determine if 2 hash elements are identical * @choose: callback calculating the hash index * @data: data passed to the aforementioned callbacks as argument * * ata could be the structure you use with just the key filled, we just need * the key for comparing. * * Return: returns pointer do data on success, so you can remove the used * structure yourself, or NULL on error
*/ staticinlinevoid *batadv_hash_remove(struct batadv_hashtable *hash,
batadv_hashdata_compare_cb compare,
batadv_hashdata_choose_cb choose, void *data)
{
u32 index; struct hlist_node *node; struct hlist_head *head; void *data_save = NULL;
index = choose(data, hash->size);
head = &hash->table[index];
spin_lock_bh(&hash->list_locks[index]);
hlist_for_each(node, head) { if (!compare(node, data)) continue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.