const struct cmap_node *cmap_find(const struct cmap *, uint32_t hash);
struct cmap_node *cmap_find_protected(const struct cmap *, uint32_t hash);
+/* Find node by index or find index by hash. The 'index' of a cmap entry is a
+ * way to combine the specific bucket and the entry of the bucket into a
+ * convenient single integer value. In other words, it is the index of the
+ * entry and each entry has an unique index. It is not used internally by
+ * cmap.
+ * Currently the functions assume index will not be larger than uint32_t. In
+ * OvS table size is usually much smaller than this size.*/
+const struct cmap_node * cmap_find_by_index(const struct cmap *,
+ uint32_t index);
+uint32_t cmap_find_index(const struct cmap *, uint32_t hash);
+
/* Looks up multiple 'hashes', when the corresponding bit in 'map' is 1,
* and sets the corresponding pointer in 'nodes', if the hash value was
* found from the 'cmap'. In other cases the 'nodes' values are not changed,
* int extra_data;
* };
*
- * struct cmap_cursor cursor;
- * struct my_node *iter;
* struct cmap my_map;
+ * struct my_node *my_node;
*
- * cmap_init(&cmap);
+ * cmap_init(&my_map);
* ...add data...
- * CMAP_FOR_EACH (my_node, cmap_node, &cursor, &cmap) {
+ * CMAP_FOR_EACH (my_node, cmap_node, &my_map) {
* ...operate on my_node...
* }
*
struct cmap_cursor cmap_cursor_start(const struct cmap *);
void cmap_cursor_advance(struct cmap_cursor *);
-#define CMAP_FOR_EACH(NODE, MEMBER, CMAP) \
- for (struct cmap_cursor cursor__ = cmap_cursor_start(CMAP); \
- CMAP_CURSOR_FOR_EACH__(NODE, &cursor__, MEMBER); \
+/* Generate a unique name for the cursor with the __COUNTER__ macro to
+ * allow nesting of CMAP_FOR_EACH loops. */
+#define CURSOR_JOIN2(x,y) x##y
+#define CURSOR_JOIN(x, y) CURSOR_JOIN2(x,y)
+
+#define CMAP_FOR_EACH__(NODE, MEMBER, CMAP, CURSOR_NAME) \
+ for (struct cmap_cursor CURSOR_NAME = cmap_cursor_start(CMAP); \
+ CMAP_CURSOR_FOR_EACH__(NODE, &CURSOR_NAME, MEMBER); \
)
+#define CMAP_FOR_EACH(NODE, MEMBER, CMAP) \
+ CMAP_FOR_EACH__(NODE, MEMBER, CMAP, \
+ CURSOR_JOIN(cursor_, __COUNTER__))
+
static inline struct cmap_node *cmap_first(const struct cmap *);
/* Another, less preferred, form of iteration, for use in situations where it