hash: retrieve a key given its position
authorYari Adan Petralanda <yari.adan.petralanda@ericsson.com>
Mon, 4 Jul 2016 08:59:52 +0000 (10:59 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Sun, 10 Jul 2016 12:56:45 +0000 (14:56 +0200)
The function rte_hash_get_key_with_position is added in this patch.
As the position returned when adding a key is frequently used as an
offset into an array of user data, this function performs the operation
of retrieving a key given this offset.

A possible use case would be to delete a key from the hash table when
its entry in the array of data has certain value. For instance, the key
could be a flow 5-tuple, and the value stored in the array a time
stamp.

Signed-off-by: Juan Antonio Montesinos <juan.antonio.montesinos.delgado@ericsson.com>
Signed-off-by: Yari Adan Petralanda <yari.adan.petralanda@ericsson.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
app/test/test_hash.c
lib/librte_hash/rte_cuckoo_hash.c
lib/librte_hash/rte_hash.h
lib/librte_hash/rte_hash_version.map

index 7e41725..29abcd9 100644 (file)
@@ -420,6 +420,46 @@ static int test_add_update_delete(void)
        return 0;
 }
 
+/*
+ * Sequence of operations for retrieving a key with its position
+ *
+ *  - create table
+ *  - add key
+ *  - get the key with its position: hit
+ *  - delete key
+ *  - try to get the deleted key: miss
+ *
+ */
+static int test_hash_get_key_with_position(void)
+{
+       struct rte_hash *handle = NULL;
+       int pos, expectedPos, result;
+       void *key;
+
+       ut_params.name = "hash_get_key_w_pos";
+       handle = rte_hash_create(&ut_params);
+       RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+       pos = rte_hash_add_key(handle, &keys[0]);
+       print_key_info("Add", &keys[0], pos);
+       RETURN_IF_ERROR(pos < 0, "failed to add key (pos0=%d)", pos);
+       expectedPos = pos;
+
+       result = rte_hash_get_key_with_position(handle, pos, &key);
+       RETURN_IF_ERROR(result != 0, "error retrieving a key");
+
+       pos = rte_hash_del_key(handle, &keys[0]);
+       print_key_info("Del", &keys[0], pos);
+       RETURN_IF_ERROR(pos != expectedPos,
+                       "failed to delete key (pos0=%d)", pos);
+
+       result = rte_hash_get_key_with_position(handle, pos, &key);
+       RETURN_IF_ERROR(result != -ENOENT, "non valid key retrieved");
+
+       rte_hash_free(handle);
+       return 0;
+}
+
 /*
  * Sequence of operations for find existing hash table
  *
@@ -1442,6 +1482,8 @@ test_hash(void)
                return -1;
        if (test_hash_add_delete_jhash_3word() < 0)
                return -1;
+       if (test_hash_get_key_with_position() < 0)
+               return -1;
        if (test_hash_find_existing() < 0)
                return -1;
        if (test_add_update_delete() < 0)
index e3cc3a7..26e54f6 100644 (file)
@@ -877,6 +877,26 @@ rte_hash_del_key(const struct rte_hash *h, const void *key)
        return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
 }
 
+int
+rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
+                              void **key)
+{
+       RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
+
+       struct rte_hash_key *k, *keys = h->key_store;
+       k = (struct rte_hash_key *) ((char *) keys + (position + 1) *
+                                    h->key_entry_size);
+       *key = k->key;
+
+       if (position !=
+           __rte_hash_lookup_with_hash(h, *key, rte_hash_hash(h, *key),
+                                       NULL)) {
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
 /* Lookup bulk stage 0: Prefetch input key */
 static inline void
 lookup_stage0(unsigned *idx, uint64_t *lookup_mask,
index c9612fb..622c180 100644 (file)
@@ -271,6 +271,24 @@ rte_hash_del_key(const struct rte_hash *h, const void *key);
 int32_t
 rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t sig);
 
+/**
+ * Find a key in the hash table given the position.
+ * This operation is multi-thread safe.
+ *
+ * @param h
+ *   Hash table to get the key from.
+ * @param position
+ *   Position returned when the key was inserted.
+ * @param key
+ *   Output containing a pointer to the key
+ * @return
+ *   - 0 if retrieved successfully
+ *   - EINVAL if the parameters are invalid.
+ *   - ENOENT if no valid key is found in the given position.
+ */
+int
+rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
+                              void **key);
 
 /**
  * Find a key-value pair in the hash table.
index 4f25436..52a2576 100644 (file)
@@ -38,3 +38,10 @@ DPDK_2.2 {
        rte_hash_set_cmp_func;
 
 } DPDK_2.1;
+
+DPDK_16.07 {
+       global:
+
+       rte_hash_get_key_with_position;
+
+} DPDK_2.2;