+void *cso_hash_find_data_from_template(struct cso_hash *hash,
+ unsigned hash_key,
+ void *templ,
+ int size);
+
+struct cso_node *cso_hash_data_next(struct cso_node *node);
+
+static inline bool
+cso_hash_iter_is_null(struct cso_hash_iter iter)
+{
+ return !iter.node || iter.node == iter.hash->end;
+}
+
+static inline void *
+cso_hash_iter_data(struct cso_hash_iter iter)
+{
+ if (!iter.node || iter.hash->end == iter.node)
+ return NULL;
+ return iter.node->value;
+}
+
+static inline struct cso_node **
+cso_hash_find_node(struct cso_hash *hash, unsigned akey)
+{
+ struct cso_node **node;
+
+ if (hash->numBuckets) {
+ node = &hash->buckets[akey % hash->numBuckets];
+ assert(*node == hash->end || (*node)->next);
+ while (*node != hash->end && (*node)->key != akey)
+ node = &(*node)->next;
+ } else {
+ node = &hash->end;
+ }
+ return node;
+}
+
+/**
+ * Return an iterator pointing to the first entry in the collision list.
+ */
+static inline struct cso_hash_iter
+cso_hash_find(struct cso_hash *hash, unsigned key)
+{
+ struct cso_node **nextNode = cso_hash_find_node(hash, key);
+ struct cso_hash_iter iter = {hash, *nextNode};
+ return iter;
+}