Skip to content

Commit

Permalink
lib/cmap: Return number of nodes from functions modifying the cmap.
Browse files Browse the repository at this point in the history
We already update the count field as the last step of these functions,
so returning the current count is very cheap.  Callers that care about
the count become a bit more efficient, as they avoid extra
non-inlineable function call.

Signed-off-by: Jarno Rajahalme <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
Jarno Rajahalme committed Oct 6, 2014
1 parent 22d38fc commit ee58b46
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 24 deletions.
34 changes: 15 additions & 19 deletions lib/cmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,8 +654,10 @@ cmap_try_insert(struct cmap_impl *impl, struct cmap_node *node, uint32_t hash)
/* Inserts 'node', with the given 'hash', into 'cmap'. The caller must ensure
* that 'cmap' cannot change concurrently (from another thread). If duplicates
* are undesirable, the caller must have already verified that 'cmap' does not
* contain a duplicate of 'node'. */
void
* contain a duplicate of 'node'.
*
* Returns the current number of nodes in the cmap after the insertion. */
size_t
cmap_insert(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
{
struct cmap_impl *impl = cmap_get_impl(cmap);
Expand All @@ -669,7 +671,7 @@ cmap_insert(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
while (OVS_UNLIKELY(!cmap_try_insert(impl, node, hash))) {
impl = cmap_rehash(cmap, impl->mask);
}
impl->n++;
return ++impl->n;
}

static bool
Expand Down Expand Up @@ -705,28 +707,17 @@ cmap_replace__(struct cmap_impl *impl, struct cmap_node *node,
}
}

/* Removes 'node' from 'cmap'. The caller must ensure that 'cmap' cannot
* change concurrently (from another thread).
*
* 'node' must not be destroyed or modified or inserted back into 'cmap' or
* into any other concurrent hash map while any other thread might be accessing
* it. One correct way to do this is to free it from an RCU callback with
* ovsrcu_postpone(). */
void
cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
{
cmap_replace(cmap, node, NULL, hash);
cmap_get_impl(cmap)->n--;
}

/* Replaces 'old_node' in 'cmap' with 'new_node'. The caller must
* ensure that 'cmap' cannot change concurrently (from another thread).
*
* 'old_node' must not be destroyed or modified or inserted back into 'cmap' or
* into any other concurrent hash map while any other thread might be accessing
* it. One correct way to do this is to free it from an RCU callback with
* ovsrcu_postpone(). */
void
* ovsrcu_postpone().
*
* Returns the current number of nodes in the cmap after the replacement. The
* number of nodes decreases by one if 'new_node' is NULL. */
size_t
cmap_replace(struct cmap *cmap, struct cmap_node *old_node,
struct cmap_node *new_node, uint32_t hash)
{
Expand All @@ -738,6 +729,11 @@ cmap_replace(struct cmap *cmap, struct cmap_node *old_node,
ok = cmap_replace__(impl, old_node, new_node, hash, h1)
|| cmap_replace__(impl, old_node, new_node, hash, h2);
ovs_assert(ok);

if (!new_node) {
impl->n--;
}
return impl->n;
}

static bool
Expand Down
26 changes: 21 additions & 5 deletions lib/cmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ void cmap_destroy(struct cmap *);
size_t cmap_count(const struct cmap *);
bool cmap_is_empty(const struct cmap *);

/* Insertion and deletion. */
void cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash);
void cmap_remove(struct cmap *, struct cmap_node *, uint32_t hash);
void cmap_replace(struct cmap *, struct cmap_node *old_node,
struct cmap_node *new_node, uint32_t hash);
/* Insertion and deletion. Return the current count after the operation. */
size_t cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash);
static inline size_t cmap_remove(struct cmap *, struct cmap_node *,
uint32_t hash);
size_t cmap_replace(struct cmap *, struct cmap_node *old_node,
struct cmap_node *new_node, uint32_t hash);

/* Search.
*
Expand Down Expand Up @@ -225,4 +226,19 @@ cmap_first(const struct cmap *cmap)
return cmap_next_position(cmap, &pos);
}

/* Removes 'node' from 'cmap'. The caller must ensure that 'cmap' cannot
* change concurrently (from another thread).
*
* 'node' must not be destroyed or modified or inserted back into 'cmap' or
* into any other concurrent hash map while any other thread might be accessing
* it. One correct way to do this is to free it from an RCU callback with
* ovsrcu_postpone().
*
* Returns the current number of nodes in the cmap after the removal. */
static inline size_t
cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
{
return cmap_replace(cmap, node, NULL, hash);
}

#endif /* cmap.h */

0 comments on commit ee58b46

Please sign in to comment.