vppinfra: move unused code to extras/deprecated/vppinfra
[vpp.git] / extras / deprecated / vppinfra / phash.h
diff --git a/extras/deprecated/vppinfra/phash.h b/extras/deprecated/vppinfra/phash.h
new file mode 100644 (file)
index 0000000..3dc59c7
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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) 2005 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.
+*/
+
+#ifndef included_phash_h
+#define included_phash_h
+
+#include <vppinfra/hash.h>     /* for Bob's mixing functions */
+
+typedef struct
+{
+  /* Maybe either pointer to vector or inline word. */
+  uword key;
+
+  /* Hash code (A, B). */
+  u32 a, b;
+} phash_key_t;
+
+/* Table indexed by B. */
+typedef struct
+{
+  /* Vector of key indices with this same value of B. */
+  u32 *keys;
+
+  /* hash=a^tabb[b].val_b */
+  u32 val_b;
+
+  /* High watermark of who has visited this map node. */
+  u32 water_b;
+} phash_tabb_t;
+
+always_inline void
+phash_tabb_free (phash_tabb_t * b)
+{
+  vec_free (b->keys);
+  b->val_b = b->water_b = 0;
+}
+
+typedef struct
+{
+  /* b that currently occupies this hash */
+  u32 b_q;
+
+  /* Queue position of parent that could use this hash. */
+  u32 parent_q;
+
+  /* What to change parent tab[b] to use this hash. */
+  u32 newval_q;
+
+  /* Original value of tab[b]. */
+  u32 oldval_q;
+} phash_tabq_t;
+
+typedef struct
+{
+  u8 a_bits, b_bits, s_bits, a_shift;
+  u32 b_mask;
+  u32 *tab;
+  u32 *scramble;
+
+  /* Seed value for hash mixer. */
+  u64 hash_seed;
+
+  u32 flags;
+
+  /* Key functions want 64 bit keys.
+     Use hash_mix64 rather than hash_mix32. */
+#define PHASH_FLAG_MIX64               (1 << 0)
+#define PHASH_FLAG_MIX32               (0 << 0)
+
+  /* When b_bits is large enough (>= 12) we scramble. */
+#define PHASH_FLAG_USE_SCRAMBLE                (1 << 1)
+
+  /* Slow mode gives smaller tables but at the expense of more run time. */
+#define PHASH_FLAG_SLOW_MODE           (0 << 2)
+#define PHASH_FLAG_FAST_MODE           (1 << 2)
+
+  /* Generate minimal perfect hash instead of perfect hash. */
+#define PHASH_FLAG_NON_MINIMAL         (0 << 3)
+#define PHASH_FLAG_MINIMAL             (1 << 3)
+
+  /* vec_len (keys) for minimal hash;
+     1 << s_bits for non-minimal hash. */
+  u32 hash_max;
+
+  /* Vector of keys. */
+  phash_key_t *keys;
+
+  /* Used by callbacks to identify keys. */
+  void *private;
+
+  /* Key comparison callback. */
+  int (*key_is_equal) (void *private, uword key1, uword key2);
+
+  /* Callback to reduce single key -> hash seeds. */
+  void (*key_seed1) (void *private, uword key, void *seed);
+
+  /* Callback to reduce two key2 -> hash seeds. */
+  void (*key_seed2) (void *private, uword key1, uword key2, void *seed);
+
+  /* Stuff used to compute perfect hash. */
+  u32 random_seed;
+
+  /* Stuff indexed by B. */
+  phash_tabb_t *tabb;
+
+  /* Table of B ordered by number of keys in tabb[b]. */
+  u32 *tabb_sort;
+
+  /* Unique key (or ~0 if none) for a given hash
+     H = A ^ scramble[tab[B].val_b]. */
+  u32 *tabh;
+
+  /* Stuff indexed by q. */
+  phash_tabq_t *tabq;
+
+  /* Stats. */
+  u32 n_seed_trials, n_perfect_calls;
+} phash_main_t;
+
+always_inline void
+phash_main_free_working_memory (phash_main_t * pm)
+{
+  vec_free (pm->tabb);
+  vec_free (pm->tabq);
+  vec_free (pm->tabh);
+  vec_free (pm->tabb_sort);
+  if (!(pm->flags & PHASH_FLAG_USE_SCRAMBLE))
+    vec_free (pm->scramble);
+}
+
+always_inline void
+phash_main_free (phash_main_t * pm)
+{
+  phash_main_free_working_memory (pm);
+  vec_free (pm->tab);
+  vec_free (pm->keys);
+  clib_memset (pm, 0, sizeof (pm[0]));
+}
+
+/* Slow hash computation for general keys. */
+uword phash_hash_slow (phash_main_t * pm, uword key);
+
+/* Main routine to compute perfect hash. */
+clib_error_t *phash_find_perfect_hash (phash_main_t * pm);
+
+/* Validates that hash is indeed perfect. */
+clib_error_t *phash_validate (phash_main_t * pm);
+
+/* Unit test. */
+int phash_test_main (unformat_input_t * input);
+
+#endif /* included_phash_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */