summaryrefslogtreecommitdiffstats
path: root/vppinfra/vppinfra/mhash.c
diff options
context:
space:
mode:
Diffstat (limited to 'vppinfra/vppinfra/mhash.c')
-rw-r--r--vppinfra/vppinfra/mhash.c408
1 files changed, 0 insertions, 408 deletions
diff --git a/vppinfra/vppinfra/mhash.c b/vppinfra/vppinfra/mhash.c
deleted file mode 100644
index c917e164cd9..00000000000
--- a/vppinfra/vppinfra/mhash.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- Copyright (c) 2010 Eliot Dresselhaus
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <vppinfra/mhash.h>
-
-always_inline u32
-load_partial_u32 (void *d, uword n)
-{
- if (n == 4)
- return ((u32 *) d)[0];
- if (n == 3)
- return ((u16 *) d)[0] | (((u8 *) d)[2] << 16);
- if (n == 2)
- return ((u16 *) d)[0];
- if (n == 1)
- return ((u8 *) d)[0];
- ASSERT (0);
- return 0;
-}
-
-always_inline u32
-mhash_key_sum_inline (void *data, uword n_data_bytes, u32 seed)
-{
- u32 *d32 = data;
- u32 a, b, c, n_left;
-
- a = b = c = seed;
- n_left = n_data_bytes;
- a ^= n_data_bytes;
-
- while (n_left > 12)
- {
- a += d32[0];
- b += d32[1];
- c += d32[2];
- hash_v3_mix32 (a, b, c);
- n_left -= 12;
- d32 += 3;
- }
-
- if (n_left > 8)
- {
- c += load_partial_u32 (d32 + 2, n_left - 8);
- n_left = 8;
- }
- if (n_left > 4)
- {
- b += load_partial_u32 (d32 + 1, n_left - 4);
- n_left = 4;
- }
- if (n_left > 0)
- a += load_partial_u32 (d32 + 0, n_left - 0);
-
- hash_v3_finalize32 (a, b, c);
-
- return c;
-}
-
-#define foreach_mhash_key_size \
- _ (2) _ (3) _ (4) _ (5) _ (6) _ (7) \
- _ (8) _ (12) _ (16) _ (20) \
- _ (24) _ (28) _ (32) _ (36) \
- _ (40) _ (44) _ (48) _ (52) \
- _ (56) _ (60) _ (64)
-
-#define _(N_KEY_BYTES) \
- static uword \
- mhash_key_sum_##N_KEY_BYTES (hash_t * h, uword key) \
- { \
- mhash_t * hv = uword_to_pointer (h->user, mhash_t *); \
- return mhash_key_sum_inline (mhash_key_to_mem (hv, key), \
- (N_KEY_BYTES), \
- hv->hash_seed); \
- } \
- \
- static uword \
- mhash_key_equal_##N_KEY_BYTES (hash_t * h, uword key1, uword key2) \
- { \
- mhash_t * hv = uword_to_pointer (h->user, mhash_t *); \
- void * k1 = mhash_key_to_mem (hv, key1); \
- void * k2 = mhash_key_to_mem (hv, key2); \
- return ! memcmp (k1, k2, (N_KEY_BYTES)); \
- }
-
-foreach_mhash_key_size
-#undef _
-static uword
-mhash_key_sum_c_string (hash_t * h, uword key)
-{
- mhash_t *hv = uword_to_pointer (h->user, mhash_t *);
- void *k = mhash_key_to_mem (hv, key);
- return mhash_key_sum_inline (k, strlen (k), hv->hash_seed);
-}
-
-static uword
-mhash_key_equal_c_string (hash_t * h, uword key1, uword key2)
-{
- mhash_t *hv = uword_to_pointer (h->user, mhash_t *);
- void *k1 = mhash_key_to_mem (hv, key1);
- void *k2 = mhash_key_to_mem (hv, key2);
- return strcmp (k1, k2) == 0;
-}
-
-static uword
-mhash_key_sum_vec_string (hash_t * h, uword key)
-{
- mhash_t *hv = uword_to_pointer (h->user, mhash_t *);
- void *k = mhash_key_to_mem (hv, key);
- return mhash_key_sum_inline (k, vec_len (k), hv->hash_seed);
-}
-
-static uword
-mhash_key_equal_vec_string (hash_t * h, uword key1, uword key2)
-{
- mhash_t *hv = uword_to_pointer (h->user, mhash_t *);
- void *k1 = mhash_key_to_mem (hv, key1);
- void *k2 = mhash_key_to_mem (hv, key2);
- return vec_len (k1) == vec_len (k2) && memcmp (k1, k2, vec_len (k1)) == 0;
-}
-
-/* The CLIB hash user pointer must always point to a valid mhash_t.
- Now, the address of mhash_t can change (think vec_resize).
- So we must always be careful that it points to the correct
- address. */
-always_inline void
-mhash_sanitize_hash_user (mhash_t * mh)
-{
- uword *hash = mh->hash;
- hash_t *h = hash_header (hash);
- h->user = pointer_to_uword (mh);
-}
-
-void
-mhash_init (mhash_t * h, uword n_value_bytes, uword n_key_bytes)
-{
- static struct
- {
- hash_key_sum_function_t *key_sum;
- hash_key_equal_function_t *key_equal;
- } t[] =
- {
-#define _(N_KEY_BYTES) \
- [N_KEY_BYTES] = { \
- .key_sum = mhash_key_sum_##N_KEY_BYTES, \
- .key_equal = mhash_key_equal_##N_KEY_BYTES, \
- },
-
- foreach_mhash_key_size
-#undef _
- [MHASH_C_STRING_KEY] =
- {
- .key_sum = mhash_key_sum_c_string,.key_equal = mhash_key_equal_c_string,},
- [MHASH_VEC_STRING_KEY] =
- {
- .key_sum = mhash_key_sum_vec_string,.key_equal =
- mhash_key_equal_vec_string,},};
-
- if (mhash_key_vector_is_heap (h))
- heap_free (h->key_vector_or_heap);
- else
- vec_free (h->key_vector_or_heap);
- vec_free (h->key_vector_free_indices);
- {
- int i;
- for (i = 0; i < vec_len (h->key_tmps); i++)
- vec_free (h->key_tmps[i]);
- }
- vec_free (h->key_tmps);
- hash_free (h->hash);
-
- memset (h, 0, sizeof (h[0]));
- h->n_key_bytes = n_key_bytes;
-
-#if 0
- if (h->n_key_bytes > 0)
- {
- vec_validate (h->key_tmp, h->n_key_bytes - 1);
- _vec_len (h->key_tmp) = 0;
- }
-#endif
-
- ASSERT (n_key_bytes < ARRAY_LEN (t));
- h->hash = hash_create2 ( /* elts */ 0,
- /* user */ pointer_to_uword (h),
- /* value_bytes */ n_value_bytes,
- t[n_key_bytes].key_sum, t[n_key_bytes].key_equal,
- /* format pair/arg */
- 0, 0);
-}
-
-static uword
-mhash_set_tmp_key (mhash_t * h, const void *key)
-{
- u8 *key_tmp;
- int my_cpu = os_get_cpu_number ();
-
- vec_validate (h->key_tmps, my_cpu);
- key_tmp = h->key_tmps[my_cpu];
-
- vec_reset_length (key_tmp);
-
- if (mhash_key_vector_is_heap (h))
- {
- uword is_c_string = h->n_key_bytes == MHASH_C_STRING_KEY;
-
- if (is_c_string)
- vec_add (key_tmp, key, strlen (key) + 1);
- else
- vec_add (key_tmp, key, vec_len (key));
- }
- else
- vec_add (key_tmp, key, h->n_key_bytes);
-
- h->key_tmps[my_cpu] = key_tmp;
-
- return ~0;
-}
-
-hash_pair_t *
-mhash_get_pair (mhash_t * h, const void *key)
-{
- uword ikey;
- mhash_sanitize_hash_user (h);
- ikey = mhash_set_tmp_key (h, key);
- return hash_get_pair (h->hash, ikey);
-}
-
-typedef struct
-{
- u32 heap_handle;
-
- /* Must conincide with vec_header. */
- vec_header_t vec;
-} mhash_string_key_t;
-
-uword
-mhash_set_mem (mhash_t * h, void *key, uword * new_value, uword * old_value)
-{
- u8 *k;
- uword ikey, i, l = 0, n_key_bytes, old_n_elts, key_alloc_from_free_list = 0;
-
- mhash_sanitize_hash_user (h);
-
- if (mhash_key_vector_is_heap (h))
- {
- mhash_string_key_t *sk;
- uword is_c_string = h->n_key_bytes == MHASH_C_STRING_KEY;
- uword handle;
-
- n_key_bytes = is_c_string ? (strlen (key) + 1) : vec_len (key);
- i =
- heap_alloc (h->key_vector_or_heap, n_key_bytes + sizeof (sk[0]),
- handle);
-
- sk = (void *) (h->key_vector_or_heap + i);
- sk->heap_handle = handle;
- sk->vec.len = n_key_bytes;
- clib_memcpy (sk->vec.vector_data, key, n_key_bytes);
-
- /* Advance key past vector header. */
- i += sizeof (sk[0]);
- }
- else
- {
- key_alloc_from_free_list = (l =
- vec_len (h->key_vector_free_indices)) > 0;
- if (key_alloc_from_free_list)
- {
- i = h->key_vector_free_indices[l - 1];
- k = vec_elt_at_index (h->key_vector_or_heap, i);
- _vec_len (h->key_vector_free_indices) = l - 1;
- }
- else
- {
- vec_add2 (h->key_vector_or_heap, k, h->n_key_bytes);
- i = k - h->key_vector_or_heap;
- }
-
- n_key_bytes = h->n_key_bytes;
- clib_memcpy (k, key, n_key_bytes);
- }
- ikey = i;
-
- old_n_elts = hash_elts (h->hash);
- h->hash = _hash_set3 (h->hash, ikey, new_value, old_value);
-
- /* If element already existed remove duplicate key. */
- if (hash_elts (h->hash) == old_n_elts)
- {
- hash_pair_t *p;
-
- /* Fetch old key for return value. */
- p = hash_get_pair (h->hash, ikey);
- ikey = p->key;
-
- /* Remove duplicate key. */
- if (mhash_key_vector_is_heap (h))
- {
- mhash_string_key_t *sk;
- sk = (void *) (h->key_vector_or_heap + i - sizeof (sk[0]));
- heap_dealloc (h->key_vector_or_heap, sk->heap_handle);
- }
- else
- {
- if (key_alloc_from_free_list)
- {
- h->key_vector_free_indices[l] = i;
- _vec_len (h->key_vector_free_indices) = l + 1;
- }
- else
- _vec_len (h->key_vector_or_heap) -= h->n_key_bytes;
- }
- }
-
- return ikey;
-}
-
-uword
-mhash_unset (mhash_t * h, void *key, uword * old_value)
-{
- hash_pair_t *p;
- uword i;
-
- mhash_sanitize_hash_user (h);
- i = mhash_set_tmp_key (h, key);
-
- p = hash_get_pair (h->hash, i);
- if (!p)
- return 0;
-
- ASSERT (p->key != ~0);
- i = p->key;
-
- if (mhash_key_vector_is_heap (h))
- {
- mhash_string_key_t *sk;
- sk = (void *) (h->key_vector_or_heap + i) - sizeof (sk[0]);
- heap_dealloc (h->key_vector_or_heap, sk->heap_handle);
- }
- else
- vec_add1 (h->key_vector_free_indices, i);
-
- hash_unset3 (h->hash, i, old_value);
- return 1;
-}
-
-u8 *
-format_mhash_key (u8 * s, va_list * va)
-{
- mhash_t *h = va_arg (*va, mhash_t *);
- u32 ki = va_arg (*va, u32);
- void *k = mhash_key_to_mem (h, ki);
-
- if (mhash_key_vector_is_heap (h))
- {
- uword is_c_string = h->n_key_bytes == MHASH_C_STRING_KEY;
- u32 l = is_c_string ? strlen (k) : vec_len (k);
- vec_add (s, k, l);
- }
- else if (h->format_key)
- s = format (s, "%U", h->format_key, k);
- else
- s = format (s, "%U", format_hex_bytes, k, h->n_key_bytes);
-
- return s;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */