/*
 * 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:
 */
