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

#if 0
#ifdef __OPTIMIZE__
#undef CLIB_DEBUG
#endif
#endif

#include <vppinfra/bitmap.h>
#include <vppinfra/error.h>
#include <vppinfra/os.h>
#include <vppinfra/random.h>
#include <vppinfra/time.h>
#include <vppinfra/vhash.h>

#ifdef CLIB_HAVE_VEC128

typedef struct
{
  u32 n_iter;
  u32 seed;
  u32 verbose;
  u32 n_keys;
  u32 log2_size;
  u32 n_key_u32;

  u32 n_vectors_div_4;
  u32 n_vectors_mod_4;

  u32 *keys;
  u32 *results;

  u32 *vhash_get_key_indices;
  u32 *vhash_get_results;

  u32 *vhash_key_indices;
  u32 *vhash_results;

  vhash_t vhash;

  uword **key_hash;

  struct
  {
    u64 n_clocks;
    u64 n_vectors;
    u64 n_calls;
  } get_stats, set_stats, unset_stats;
} test_vhash_main_t;

always_inline u32
test_vhash_key_gather (void *_tm, u32 vi, u32 wi, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  ASSERT (n_key_u32s == tm->n_key_u32);
  ASSERT (wi < n_key_u32s);
  vi = vec_elt (tm->vhash_key_indices, vi);
  return vec_elt (tm->keys, vi * n_key_u32s + wi);
}

always_inline u32x4
test_vhash_4key_gather (void *_tm, u32 vi, u32 wi, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  u32 *p;
  u32x4_union_t x;

  ASSERT (n_key_u32s == tm->n_key_u32);
  ASSERT (wi < n_key_u32s);

  p = vec_elt_at_index (tm->vhash_key_indices, vi + 0);
  x.as_u32[0] = tm->keys[p[0] * n_key_u32s + wi];
  x.as_u32[1] = tm->keys[p[1] * n_key_u32s + wi];
  x.as_u32[2] = tm->keys[p[2] * n_key_u32s + wi];
  x.as_u32[3] = tm->keys[p[3] * n_key_u32s + wi];
  return x.as_u32x4;
}

always_inline u32
test_vhash_get_result (void *_tm,
		       u32 vector_index, u32 result_index, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
  p[0] = result_index;
  return result_index;
}

always_inline u32x4
test_vhash_get_4result (void *_tm,
			u32 vector_index, u32x4 results, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
  *(u32x4 *) p = results;
  return results;
}

always_inline u32
test_vhash_set_result (void *_tm,
		       u32 vector_index, u32 old_result, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
  u32 new_result = p[0];
  p[0] = old_result;
  return new_result;
}

always_inline u32
test_vhash_unset_result (void *_tm, u32 i, u32 old_result, u32 n_key_u32s)
{
  test_vhash_main_t *tm = _tm;
  u32 *p = vec_elt_at_index (tm->vhash_results, i);
  p[0] = old_result;
  return 0;
}

#define _(N_KEY_U32)							\
  always_inline u32							\
  test_vhash_key_gather_##N_KEY_U32 (void * _tm, u32 vi, u32 i)		\
  { return test_vhash_key_gather (_tm, vi, i, N_KEY_U32); }		\
									\
  always_inline u32x4							\
  test_vhash_key_gather_4_##N_KEY_U32 (void * _tm, u32 vi, u32 i)	\
  {  return test_vhash_4key_gather (_tm, vi, i, N_KEY_U32); }		\
									\
  clib_pipeline_stage							\
  (test_vhash_gather_keys_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_gather_4key_stage						\
       (&tm->vhash,							\
	/* vector_index */ i,						\
	test_vhash_key_gather_4_##N_KEY_U32,				\
	tm,								\
	N_KEY_U32);							\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_gather_keys_mod_stage_##N_KEY_U32,			\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_gather_key_stage						\
       (&tm->vhash,							\
	/* vector_index */ tm->n_vectors_div_4,				\
	/* n_vectors */ tm->n_vectors_mod_4,				\
	test_vhash_key_gather_##N_KEY_U32,				\
	tm,								\
	N_KEY_U32);							\
   })									\
									\
  clib_pipeline_stage							\
  (test_vhash_hash_finalize_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_finalize_stage (&tm->vhash, i, N_KEY_U32);			\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_hash_finalize_mod_stage_##N_KEY_U32,			\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_finalize_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32);	\
   })									\
									\
  clib_pipeline_stage							\
  (test_vhash_get_stage_##N_KEY_U32,					\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_get_4_stage (&tm->vhash,					\
			/* vector_index */ i,				\
			test_vhash_get_4result,				\
			tm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_get_mod_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_get_stage (&tm->vhash,					\
		      /* vector_index */ tm->n_vectors_div_4,		\
		      /* n_vectors */ tm->n_vectors_mod_4,		\
		      test_vhash_get_result,				\
		      tm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage							\
  (test_vhash_set_stage_##N_KEY_U32,					\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_set_stage (&tm->vhash,					\
		      /* vector_index */ i,				\
		      /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32),	\
		      test_vhash_set_result,				\
		      tm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_set_mod_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_set_stage (&tm->vhash,					\
		      /* vector_index */ tm->n_vectors_div_4,		\
		      /* n_vectors */ tm->n_vectors_mod_4,		\
		      test_vhash_set_result,				\
		      tm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage							\
  (test_vhash_unset_stage_##N_KEY_U32,					\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_unset_stage (&tm->vhash,					\
			/* vector_index */ i,				\
			/* n_vectors */ VECTOR_WORD_TYPE_LEN (u32),	\
			test_vhash_unset_result,			\
			tm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_unset_mod_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_unset_stage (&tm->vhash,					\
			/* vector_index */ tm->n_vectors_div_4,		\
			/* n_vectors */ tm->n_vectors_mod_4,		\
			test_vhash_unset_result,			\
			tm, N_KEY_U32);					\
   })

_(1);
_(2);
_(3);
_(4);
_(5);
_(6);

#undef _

#define _(N_KEY_U32)							\
  clib_pipeline_stage							\
  (test_vhash_hash_mix_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_mix_stage (&tm->vhash, i, N_KEY_U32);			\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (test_vhash_hash_mix_mod_stage_##N_KEY_U32,				\
   test_vhash_main_t *, tm, i,						\
   {									\
     vhash_mix_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32);	\
   })

_(4);
_(5);
_(6);

#undef _

typedef enum
{
  GET, SET, UNSET,
} test_vhash_op_t;

static void
test_vhash_op (test_vhash_main_t * tm,
	       u32 * key_indices,
	       u32 * results, uword n_keys, test_vhash_op_t op)
{
  vhash_validate_sizes (&tm->vhash, tm->n_key_u32, n_keys);

  tm->vhash_results = results;
  tm->vhash_key_indices = key_indices;
  tm->n_vectors_div_4 = n_keys / 4;
  tm->n_vectors_mod_4 = n_keys % 4;

  if (tm->n_vectors_div_4 > 0)
    {
      switch (tm->n_key_u32)
	{
	default:
	  ASSERT (0);
	  break;

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_3_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_get_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_3_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_set_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_3_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_unset_stage_##N_KEY_U32);		\
	  break;

	  _(1);
	  _(2);
	  _(3);

#undef _

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_4_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_stage_##N_KEY_U32,		\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_get_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_4_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_stage_##N_KEY_U32,		\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_set_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_4_stage				\
	      (tm->n_vectors_div_4,				\
	       tm,						\
	       test_vhash_gather_keys_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_stage_##N_KEY_U32,		\
	       test_vhash_hash_finalize_stage_##N_KEY_U32,	\
	       test_vhash_unset_stage_##N_KEY_U32);		\
	  break;

	  _(4);
	  _(5);
	  _(6);

#undef _
	}
    }


  if (tm->n_vectors_mod_4 > 0)
    {
      switch (tm->n_key_u32)
	{
	default:
	  ASSERT (0);
	  break;

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_get_mod_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_set_mod_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_unset_mod_stage_##N_KEY_U32);		\
	break;

	  _(1);
	  _(2);
	  _(3);

#undef _

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_4_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_get_mod_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_4_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_set_mod_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_4_stage				\
	      (1,						\
	       tm,						\
	       test_vhash_gather_keys_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_mix_mod_stage_##N_KEY_U32,	\
	       test_vhash_hash_finalize_mod_stage_##N_KEY_U32,	\
	       test_vhash_unset_mod_stage_##N_KEY_U32);		\
	  break;

	  _(4);
	  _(5);
	  _(6);

#undef _
	}
    }
}

int
test_vhash_main (unformat_input_t * input)
{
  clib_error_t *error = 0;
  test_vhash_main_t _tm, *tm = &_tm;
  vhash_t *vh = &tm->vhash;
  uword i, j;

  memset (tm, 0, sizeof (tm[0]));
  tm->n_iter = 100;
  tm->seed = 1;
  tm->n_keys = 1;
  tm->n_key_u32 = 1;
  tm->log2_size = 8;
  tm->verbose = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "iter %d", &tm->n_iter))
	;
      else if (unformat (input, "seed %d", &tm->seed))
	;
      else if (unformat (input, "n-keys %d", &tm->n_keys))
	;
      else if (unformat (input, "log2-size %d", &tm->log2_size))
	;
      else if (unformat (input, "key-words %d", &tm->n_key_u32))
	;
      else if (unformat (input, "verbose %=", &tm->verbose, 1))
	;
      else
	{
	  error = clib_error_create ("unknown input `%U'\n",
				     format_unformat_error, input);
	  goto done;
	}
    }

  if (tm->seed == 0)
    tm->seed = random_default_seed ();

  clib_warning ("iter %d seed %d n-keys %d log2-size %d key-words %d",
		tm->n_iter, tm->seed, tm->n_keys, tm->log2_size,
		tm->n_key_u32);

  {
    u32 seeds[3];
    seeds[0] = seeds[1] = seeds[2] = 0xdeadbeef;
    vhash_init (vh, tm->log2_size, tm->n_key_u32, seeds);
  }

  /* Choose unique keys. */
  vec_resize (tm->keys, tm->n_keys * tm->n_key_u32);
  vec_resize (tm->key_hash, tm->n_key_u32);
  for (i = j = 0; i < vec_len (tm->keys); i++, j++)
    {
      j = j == tm->n_key_u32 ? 0 : j;
      do
	{
	  tm->keys[i] = random_u32 (&tm->seed);
	}
      while (hash_get (tm->key_hash[j], tm->keys[i]));
      hash_set (tm->key_hash[j], tm->keys[i], 0);
    }

  vec_resize (tm->results, tm->n_keys);
  for (i = 0; i < vec_len (tm->results); i++)
    {
      do
	{
	  tm->results[i] = random_u32 (&tm->seed);
	}
      while (tm->results[i] == ~0);
    }

  vec_resize_aligned (tm->vhash_get_results, tm->n_keys,
		      CLIB_CACHE_LINE_BYTES);
  vec_clone (tm->vhash_get_key_indices, tm->results);
  for (i = 0; i < vec_len (tm->vhash_get_key_indices); i++)
    tm->vhash_get_key_indices[i] = i;

  {
    uword *is_set_bitmap = 0;
    uword *to_set_bitmap = 0;
    uword *to_unset_bitmap = 0;
    u32 *to_set = 0, *to_unset = 0;
    u32 *to_set_results = 0, *to_unset_results = 0;
    u64 t[2];

    for (i = 0; i < tm->n_iter; i++)
      {
	vec_reset_length (to_set);
	vec_reset_length (to_unset);
	vec_reset_length (to_set_results);
	vec_reset_length (to_unset_results);

	do
	  {
	    to_set_bitmap = clib_bitmap_random (to_set_bitmap,
						tm->n_keys, &tm->seed);
	  }
	while (clib_bitmap_is_zero (to_set_bitmap));
	to_unset_bitmap = clib_bitmap_dup_and (to_set_bitmap, is_set_bitmap);
	to_set_bitmap = clib_bitmap_andnot (to_set_bitmap, to_unset_bitmap);

	/* *INDENT-OFF* */
	clib_bitmap_foreach (j, to_set_bitmap, ({
	      vec_add1 (to_set, j);
	      vec_add1 (to_set_results, tm->results[j]);
	}));
	/* *INDENT-ON* */
	/* *INDENT-OFF* */
	clib_bitmap_foreach (j, to_unset_bitmap, ({
	      vec_add1 (to_unset, j);
	      vec_add1 (to_unset_results, 0xdeadbeef);
	}));
	/* *INDENT-ON* */

	if (vec_len (to_set) > 0)
	  {
	    t[0] = clib_cpu_time_now ();
	    test_vhash_op (tm, to_set, to_set_results, vec_len (to_set), SET);
	    t[1] = clib_cpu_time_now ();
	    tm->set_stats.n_clocks += t[1] - t[0];
	    tm->set_stats.n_vectors += vec_len (to_set);
	    tm->set_stats.n_calls += 1;
	    is_set_bitmap = clib_bitmap_or (is_set_bitmap, to_set_bitmap);
	  }

	t[0] = clib_cpu_time_now ();
	test_vhash_op (tm, tm->vhash_get_key_indices,
		       tm->vhash_get_results,
		       vec_len (tm->vhash_get_key_indices), GET);
	t[1] = clib_cpu_time_now ();
	tm->get_stats.n_clocks += t[1] - t[0];
	tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices);
	tm->get_stats.n_calls += 1;

	for (j = 0; j < vec_len (tm->vhash_get_results); j++)
	  {
	    u32 r0 = tm->vhash_get_results[j];
	    u32 r1 = tm->results[j];
	    if (clib_bitmap_get (is_set_bitmap, j))
	      {
		if (r0 != r1)
		  os_panic ();
	      }
	    else
	      {
		if (r0 != ~0)
		  os_panic ();
	      }
	  }

	if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
	  os_panic ();

	if (vec_len (to_unset) > 0)
	  {
	    t[0] = clib_cpu_time_now ();
	    test_vhash_op (tm, to_unset, to_unset_results,
			   vec_len (to_unset), UNSET);
	    t[1] = clib_cpu_time_now ();
	    tm->unset_stats.n_clocks += t[1] - t[0];
	    tm->unset_stats.n_vectors += vec_len (to_unset);
	    tm->unset_stats.n_calls += 1;
	    is_set_bitmap =
	      clib_bitmap_andnot (is_set_bitmap, to_unset_bitmap);
	  }

	t[0] = clib_cpu_time_now ();
	test_vhash_op (tm, tm->vhash_get_key_indices,
		       tm->vhash_get_results,
		       vec_len (tm->vhash_get_key_indices), GET);
	t[1] = clib_cpu_time_now ();
	tm->get_stats.n_clocks += t[1] - t[0];
	tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices);
	tm->get_stats.n_calls += 1;

	for (j = 0; j < vec_len (tm->vhash_get_results); j++)
	  {
	    u32 r0 = tm->vhash_get_results[j];
	    u32 r1 = tm->results[j];
	    if (clib_bitmap_get (is_set_bitmap, j))
	      {
		if (r0 != r1)
		  os_panic ();
	      }
	    else
	      {
		if (r0 != ~0)
		  os_panic ();
	      }
	  }

	if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
	  os_panic ();
      }

    vhash_resize (vh, tm->log2_size + 1);

    test_vhash_op (tm, tm->vhash_get_key_indices,
		   tm->vhash_get_results,
		   vec_len (tm->vhash_get_key_indices), GET);

    for (j = 0; j < vec_len (tm->vhash_get_results); j++)
      {
	u32 r0 = tm->vhash_get_results[j];
	u32 r1 = tm->results[j];
	if (clib_bitmap_get (is_set_bitmap, j))
	  {
	    if (r0 != r1)
	      os_panic ();
	  }
	else
	  {
	    if (r0 != ~0)
	      os_panic ();
	  }
      }

    if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
      os_panic ();
  }

  {
    clib_time_t ct;

    clib_time_init (&ct);

    clib_warning ("%.4e clocks/get %.4e gets/call %.4e gets/sec",
		  (f64) tm->get_stats.n_clocks /
		  (f64) tm->get_stats.n_vectors,
		  (f64) tm->get_stats.n_vectors / (f64) tm->get_stats.n_calls,
		  (f64) tm->get_stats.n_vectors /
		  (f64) (tm->get_stats.n_clocks * ct.seconds_per_clock));
    if (tm->set_stats.n_calls > 0)
      clib_warning ("%.4e clocks/set %.4e sets/call %.4e sets/sec",
		    (f64) tm->set_stats.n_clocks /
		    (f64) tm->set_stats.n_vectors,
		    (f64) tm->set_stats.n_vectors /
		    (f64) tm->set_stats.n_calls,
		    (f64) tm->set_stats.n_vectors /
		    (f64) (tm->set_stats.n_clocks * ct.seconds_per_clock));
    if (tm->unset_stats.n_calls > 0)
      clib_warning ("%.4e clocks/unset %.4e unsets/call %.4e unsets/sec",
		    (f64) tm->unset_stats.n_clocks /
		    (f64) tm->unset_stats.n_vectors,
		    (f64) tm->unset_stats.n_vectors /
		    (f64) tm->unset_stats.n_calls,
		    (f64) tm->unset_stats.n_vectors /
		    (f64) (tm->unset_stats.n_clocks * ct.seconds_per_clock));
  }

done:
  if (error)
    clib_error_report (error);
  return 0;
}

#endif /* CLIB_HAVE_VEC128 */

#ifndef CLIB_HAVE_VEC128
int
test_vhash_main (unformat_input_t * input)
{
  clib_error ("compiled without vector support");
  return 0;
}
#endif

#ifdef CLIB_UNIX
int
main (int argc, char *argv[])
{
  unformat_input_t i;
  int r;

  unformat_init_command_line (&i, argv);
  r = test_vhash_main (&i);
  unformat_free (&i);
  return r;
}
#endif

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