/*
  Copyright (c) 2017 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.
*/

/*
 * cuckoo hash implementation based on paper
 * 'Algorithmic Improvements for Fast Concurrent Cuckoo Hashing'
 * by Xiaozhou Li, David G. Andersen, Michael Kaminsky, Michael J. Freedman
 * and their libcuckoo implementation (https://github.com/efficient/libcuckoo)
 */

/*
 * Note: to instantiate the template multiple times in a single file,
 * #undef __included_cuckoo_template_h__...
 */
#ifndef __included_cuckoo_template_h__
#define __included_cuckoo_template_h__

#include <vppinfra/heap.h>
#include <vppinfra/format.h>
#include <vppinfra/pool.h>
#include <vppinfra/lock.h>
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vppinfra/cache.h>

#ifndef CLIB_CUCKOO_TYPE
#error CLIB_CUCKOO_TYPE not defined
#endif

#ifndef CLIB_CUCKOO_BFS_MAX_STEPS
#error CLIB_CUCKOO_BFS_MAX_STEPS not defined
#endif

#ifndef CLIB_CUCKOO_KVP_PER_BUCKET
#error CLIB_CUCKOO_KVP_PER_BUCKET not defined
#endif

#ifndef CLIB_CUCKOO_LOG2_KVP_PER_BUCKET
#error CLIB_CUCKOO_LOG2_KVP_PER_BUCKET not defined
#endif

#ifndef CLIB_CUCKOO_BFS_MAX_PATH_LENGTH
#error CLIB_CUCKOO_BFS_MAX_PATH_LENGTH not defined
#endif

STATIC_ASSERT (CLIB_CUCKOO_KVP_PER_BUCKET ==
	       (1 << CLIB_CUCKOO_LOG2_KVP_PER_BUCKET),
	       "CLIB_CUCKOO_KVP_PER_BUCKET != (1 << CLIB_CUCKOO_LOG2_KVP_PER_BUCKET");

#define _cv(a, b) a##b
#define __cv(a, b) _cv (a, b)
#define CV(a) __cv (a, CLIB_CUCKOO_TYPE)

#define _cvt(a, b) a##b##_t
#define __cvt(a, b) _cvt (a, b)
#define CVT(a) __cvt (a, CLIB_CUCKOO_TYPE)

typedef u64 clib_cuckoo_bucket_aux_t;

#define CLIB_CUCKOO_USE_COUNT_BIT_WIDTH (1 + CLIB_CUCKOO_LOG2_KVP_PER_BUCKET)

always_inline u64
clib_cuckoo_bucket_aux_get_version (clib_cuckoo_bucket_aux_t aux)
{
  return aux >> (1 + CLIB_CUCKOO_USE_COUNT_BIT_WIDTH);
}

always_inline int
clib_cuckoo_bucket_aux_get_use_count (clib_cuckoo_bucket_aux_t aux)
{
  u64 use_count_mask = (1 << CLIB_CUCKOO_USE_COUNT_BIT_WIDTH) - 1;
  return (aux >> 1) & use_count_mask;
}

always_inline int
clib_cuckoo_bucket_aux_get_writer_flag (clib_cuckoo_bucket_aux_t aux)
{
  return aux & 1;
}

always_inline clib_cuckoo_bucket_aux_t
clib_cuckoo_bucket_aux_pack (u64 version, int use_count, int writer_flag)
{
  return (version << (1 + CLIB_CUCKOO_USE_COUNT_BIT_WIDTH)) +
    (use_count << 1) + writer_flag;
}

always_inline clib_cuckoo_bucket_aux_t
clib_cuckoo_bucket_aux_set_version (clib_cuckoo_bucket_aux_t aux, u64 version)
{
  int use_count = clib_cuckoo_bucket_aux_get_use_count (aux);
  int writer_flag = clib_cuckoo_bucket_aux_get_writer_flag (aux);
  return clib_cuckoo_bucket_aux_pack (version, use_count, writer_flag);
}

always_inline clib_cuckoo_bucket_aux_t
clib_cuckoo_bucket_aux_set_use_count (clib_cuckoo_bucket_aux_t aux,
				      int use_count)
{
  u64 version = clib_cuckoo_bucket_aux_get_version (aux);
  int writer_flag = clib_cuckoo_bucket_aux_get_writer_flag (aux);
  return clib_cuckoo_bucket_aux_pack (version, use_count, writer_flag);
}

always_inline clib_cuckoo_bucket_aux_t
clib_cuckoo_bucket_aux_set_writer_flag (clib_cuckoo_bucket_aux_t aux,
					int writer_flag)
{
  u64 version = clib_cuckoo_bucket_aux_get_version (aux);
  int use_count = clib_cuckoo_bucket_aux_get_use_count (aux);
  return clib_cuckoo_bucket_aux_pack (version, use_count, writer_flag);
}

#define PATH_BITS_REQ \
  (CLIB_CUCKOO_BFS_MAX_PATH_LENGTH * CLIB_CUCKOO_LOG2_KVP_PER_BUCKET)

#if PATH_BITS_REQ <= 8
typedef u8 path_data_t;
#elif PATH_BITS_REQ <= 16
typedef u16 path_data_t;
#elif PATH_BITS_REQ <= 32
typedef u32 path_data_t;
#elif PATH_BITS_REQ <= 64
typedef u64 path_data_t;
#else
#error no suitable datatype for path storage...
#endif

typedef struct
{
  /** bucket where this path begins */
  u64 start;
  /** bucket at end of path */
  u64 bucket;
  /** length of the path */
  u8 length;
  /** holds compressed offsets in buckets along path */
  path_data_t data;
} clib_cuckoo_path_t;

typedef struct
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);

  /** reduced hashes corresponding to elements */
  u8 reduced_hashes[CLIB_CUCKOO_KVP_PER_BUCKET];

  /** auxiliary data - version, writer flag and used count */
  volatile clib_cuckoo_bucket_aux_t aux;

  /** cuckoo elements in this bucket */
    CVT (clib_cuckoo_kv) elts[CLIB_CUCKOO_KVP_PER_BUCKET];
} CVT (clib_cuckoo_bucket);

#define clib_cuckoo_bucket_foreach_idx(var) \
  for (var = 0; var < CLIB_CUCKOO_KVP_PER_BUCKET; var++)

#if CLIB_CUCKOO_OPTIMIZE_UNROLL
#if CLIB_CUCKOO_KVP_PER_BUCKET == 2
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
  do                                                       \
    {                                                      \
      var = 0;                                             \
      body;                                                \
      var = 1;                                             \
      body;                                                \
    }                                                      \
  while (0);
#elif CLIB_CUCKOO_KVP_PER_BUCKET == 4
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
  do                                                       \
    {                                                      \
      var = 0;                                             \
      body;                                                \
      var = 1;                                             \
      body;                                                \
      var = 2;                                             \
      body;                                                \
      var = 3;                                             \
      body;                                                \
    }                                                      \
  while (0);
#elif CLIB_CUCKOO_KVP_PER_BUCKET == 8
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
  do                                                       \
    {                                                      \
      var = 0;                                             \
      body;                                                \
      var = 1;                                             \
      body;                                                \
      var = 2;                                             \
      body;                                                \
      var = 3;                                             \
      body;                                                \
      var = 4;                                             \
      body;                                                \
      var = 5;                                             \
      body;                                                \
      var = 6;                                             \
      body;                                                \
      var = 7;                                             \
      body;                                                \
    }                                                      \
  while (0);
#else
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
  clib_cuckoo_bucket_foreach_idx (var)                     \
  {                                                        \
    body;                                                  \
  }
#endif
#else /* CLIB_CUCKOO_OPTIMIZE_UNROLL */
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
  clib_cuckoo_bucket_foreach_idx (var)                     \
  {                                                        \
    body;                                                  \
  }
#endif /* CLIB_CUCKOO_OPTIMIZE_UNROLL */

#define clib_cuckoo_bucket_foreach_elt_index(var, bucket) \
  for (var = 0; var < CLIB_CUCKOO_KVP_PER_BUCKET; ++i)

#define clib_cuckoo_foreach_bucket(var, h, body)        \
  do                                                    \
    {                                                   \
      CVT (clib_cuckoo_bucket) *__buckets = h->buckets; \
      vec_foreach (var, __buckets)                      \
      {                                                 \
        body;                                           \
      }                                                 \
    }                                                   \
  while (0)

typedef struct CV (clib_cuckoo)
{
  /** vector of elements containing key-value pairs and auxiliary data */
  CVT (clib_cuckoo_bucket) * volatile buckets;

  /** garbage to be freed once its safe to do so .. */
  CVT (clib_cuckoo_bucket) * *to_be_freed;

  /** hash table name */
  const char *name;

  /** pool of cuckoo paths (reused when doing bfd search) */
  clib_cuckoo_path_t *paths;

  /**
   * vector used as queue when doing cuckoo path searches - holds offsets
   * in paths pool
   */
  uword *bfs_search_queue;

  /**
   * writer lock - whether this lock is taken or not has zero effect on
   * readers
   */
  clib_spinlock_t writer_lock;

  /** caller context passed to callback with garbage notification */
  void *garbage_ctx;

  /**
   * garbage notify function - called when some garbage needs to be collected
   * in main thread while other threads are stopped
   */
  void (*garbage_callback) (struct CV (clib_cuckoo) * h, void *garbage_ctx);

#if CLIB_CUCKOO_DEBUG_COUNTERS
  u64 steps_exceeded;
  u64 bfs_queue_emptied;
  u64 fast_adds;
  u64 slow_adds;
  u64 rehashes;
#endif

} CVT (clib_cuckoo);

void CV (clib_cuckoo_init) (CVT (clib_cuckoo) * h, const char *name,
			    uword nbuckets,
			    void (*garbage_callback) (CVT (clib_cuckoo) *,
						      void *),
			    void *garbage_ctx);

void CV (clib_cuckoo_garbage_collect) (CVT (clib_cuckoo) * h);

void CV (clib_cuckoo_free) (CVT (clib_cuckoo) * h);

int CV (clib_cuckoo_add_del) (CVT (clib_cuckoo) * h,
			      CVT (clib_cuckoo_kv) * add_v, int is_add,
			      int dont_overwrite);
int CV (clib_cuckoo_search) (CVT (clib_cuckoo) * h,
			     CVT (clib_cuckoo_kv) * search_v,
			     CVT (clib_cuckoo_kv) * return_v);

void CV (clib_cuckoo_foreach_key_value_pair) (CVT (clib_cuckoo) * h,
					      void *callback, void *arg);

float CV (clib_cuckoo_calc_load) (CVT (clib_cuckoo) * h);

format_function_t CV (format_cuckoo);
format_function_t CV (format_cuckoo_kvp);

always_inline u8
clib_cuckoo_reduce_hash (u64 hash)
{
  u32 v32 = ((u32) hash) ^ ((u32) (hash >> 32));
  u16 v16 = ((u16) v32) ^ ((u16) (v32 >> 16));
  u8 v8 = ((u8) v16) ^ ((u8) (v16 >> 8));
  return v8;
}

always_inline u64
clib_cuckoo_get_other_bucket (u64 nbuckets, u64 bucket, u8 reduced_hash)
{
  u64 mask = (nbuckets - 1);
  return (bucket ^ ((reduced_hash + 1) * 0xc6a4a7935bd1e995)) & mask;
}

always_inline clib_cuckoo_lookup_info_t
CV (clib_cuckoo_calc_lookup) (CVT (clib_cuckoo_bucket) * buckets, u64 hash)
{
  clib_cuckoo_lookup_info_t lookup;
  u64 nbuckets = vec_len (buckets);
  u64 mask = (nbuckets - 1);
  lookup.bucket1 = hash & mask;
#if CLIB_CUCKOO_OPTIMIZE_PREFETCH
  CLIB_PREFETCH (vec_elt_at_index (buckets, lookup.bucket1),
		 sizeof (*buckets), LOAD);
#endif
  u8 reduced_hash = clib_cuckoo_reduce_hash (hash);
  lookup.bucket2 =
    clib_cuckoo_get_other_bucket (nbuckets, lookup.bucket1, reduced_hash);
#if CLIB_CUCKOO_OPTIMIZE_PREFETCH
  CLIB_PREFETCH (vec_elt_at_index (buckets, lookup.bucket2),
		 sizeof (*buckets), LOAD);
#endif
  lookup.reduced_hash = reduced_hash;
  ASSERT (lookup.bucket1 < nbuckets);
  ASSERT (lookup.bucket2 < nbuckets);
  return lookup;
}

/**
 * search for key within bucket
 */
always_inline int CV (clib_cuckoo_bucket_search) (CVT (clib_cuckoo_bucket) *
						  b,
						  CVT (clib_cuckoo_kv) * kvp,
						  u8 reduced_hash)
{
  clib_cuckoo_bucket_aux_t bucket_aux;
  u8 writer_flag;
  do
    {
      bucket_aux = b->aux;
      writer_flag = clib_cuckoo_bucket_aux_get_writer_flag (bucket_aux);
    }
  while (PREDICT_FALSE (writer_flag));	/* loop while writer flag is set */

  int i;
#if CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH
  const int use_count = clib_cuckoo_bucket_aux_get_use_count (bucket_aux);
#endif
  /* *INDENT-OFF* */
  clib_cuckoo_bucket_foreach_idx_unrolled (i, {
#if CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH
    if (i > use_count)
      {
        break;
      }
#endif
    if (
#if CLIB_CUCKOO_OPTIMIZE_CMP_REDUCED_HASH
        reduced_hash == b->reduced_hashes[i] &&
#endif
        0 == memcmp (&kvp->key, &b->elts[i].key, sizeof (kvp->key)))
      {
        kvp->value = b->elts[i].value;
        clib_cuckoo_bucket_aux_t bucket_aux2 = b->aux;
        if (PREDICT_TRUE (clib_cuckoo_bucket_aux_get_version (bucket_aux) ==
                          clib_cuckoo_bucket_aux_get_version (bucket_aux2)))
          {
            /* yay, fresh data */
            return CLIB_CUCKOO_ERROR_SUCCESS;
          }
        else
          {
            /* oops, modification detected */
            return CLIB_CUCKOO_ERROR_AGAIN;
          }
      }
  });
  /* *INDENT-ON* */
  return CLIB_CUCKOO_ERROR_NOT_FOUND;
}

always_inline int CV (clib_cuckoo_search_inline) (CVT (clib_cuckoo) * h,
						  CVT (clib_cuckoo_kv) * kvp)
{
  clib_cuckoo_lookup_info_t lookup;
  int rv;

  u64 hash = CV (clib_cuckoo_hash) (kvp);
  CVT (clib_cuckoo_bucket) * buckets;
again:
  buckets = h->buckets;
  lookup = CV (clib_cuckoo_calc_lookup) (buckets, hash);
  do
    {
      rv =
	CV (clib_cuckoo_bucket_search) (vec_elt_at_index
					(buckets, lookup.bucket1), kvp,
					lookup.reduced_hash);
    }
  while (PREDICT_FALSE (CLIB_CUCKOO_ERROR_AGAIN == rv));
  if (CLIB_CUCKOO_ERROR_SUCCESS == rv)
    {
      return CLIB_CUCKOO_ERROR_SUCCESS;
    }

  rv =
    CV (clib_cuckoo_bucket_search) (vec_elt_at_index
				    (buckets, lookup.bucket2), kvp,
				    lookup.reduced_hash);
  if (PREDICT_FALSE (CLIB_CUCKOO_ERROR_AGAIN == rv))
    {
      /*
       * change to 2nd bucket could bump the item to 1st bucket and the bucket
       * indexes might not even be valid anymore - restart the search
       */
      goto again;
    }
  return rv;
}

#endif /* __included_cuckoo_template_h__ */

/** @endcond */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
