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

#ifdef CLIB_HAVE_VEC128

/* Overflow search buckets have an extra u32x4 for saving key_hash data.
   This makes it easier to refill main search bucket from overflow vector. */
typedef struct
{
  /* 4 results for this bucket. */
  u32x4_union_t result;

  /* 4 hash codes for this bucket.  These are used to refill main
     search buckets from overflow buckets when space becomes available. */
  u32x4_union_t key_hash;

  /* n_key_u32s u32x4s of key data follow. */
  u32x4_union_t key[0];
} vhash_overflow_search_bucket_t;

always_inline void
set_overflow_result (vhash_overflow_search_bucket_t * b,
		     u32 i, u32 result, u32 key_hash)
{
  b->result.as_u32[i] = result;
  b->key_hash.as_u32[i] = key_hash;
}

always_inline void
free_overflow_bucket (vhash_overflow_buckets_t * ob,
		      vhash_overflow_search_bucket_t * b, u32 i)
{
  u32 o = (u32x4_union_t *) b - ob->search_buckets;
  ASSERT (o < vec_len (ob->search_buckets));
  vec_add1 (ob->free_indices, 4 * o + i);
}

always_inline vhash_overflow_search_bucket_t *
get_overflow_search_bucket (vhash_overflow_buckets_t * obs, u32 i,
			    u32 n_key_u32s)
{
  return ((vhash_overflow_search_bucket_t *)
	  vec_elt_at_index (obs->search_buckets, i));
}

always_inline vhash_overflow_search_bucket_t *
next_overflow_bucket (vhash_overflow_search_bucket_t * b, u32 n_key_u32s)
{
  return (vhash_overflow_search_bucket_t *) & b->key[n_key_u32s];
}

#define foreach_vhash_overflow_bucket(b,ob,n_key_u32s)			\
  for ((b) = (vhash_overflow_search_bucket_t *) ob->search_buckets;	\
       (u32x4_union_t *) (b) < vec_end (ob->search_buckets);		\
       b = next_overflow_bucket (b, n_key_u32s))

u32
vhash_get_overflow (vhash_t * h, u32 key_hash, u32 vi, u32 n_key_u32s)
{
  vhash_overflow_buckets_t *ob = vhash_get_overflow_buckets (h, key_hash);
  vhash_overflow_search_bucket_t *b;
  u32 i, result = 0;

  foreach_vhash_overflow_bucket (b, ob, n_key_u32s)
  {
    u32x4 r = b->result.as_u32x4;

    for (i = 0; i < n_key_u32s; i++)
      r &= vhash_bucket_compare (h, &b->key[0], i, vi);

    result = vhash_merge_results (r);
    if (result)
      break;
  }

  return result;
}

u32
vhash_set_overflow (vhash_t * h,
		    u32 key_hash, u32 vi, u32 new_result, u32 n_key_u32s)
{
  vhash_overflow_buckets_t *ob = vhash_get_overflow_buckets (h, key_hash);
  vhash_overflow_search_bucket_t *b;
  u32 i_set, i, old_result;

  foreach_vhash_overflow_bucket (b, ob, n_key_u32s)
  {
    u32x4 r;

    r = b->result.as_u32x4;
    for (i = 0; i < n_key_u32s; i++)
      r &= vhash_bucket_compare (h, &b->key[0], i, vi);

    old_result = vhash_merge_results (r);
    if (old_result)
      {
	i_set = vhash_non_empty_result_index (r);
	set_overflow_result (b, i_set, new_result, key_hash);
	return old_result;
      }
  }

  /* Check free list. */
  if (vec_len (ob->free_indices) == 0)
    {
      /* Out of free overflow buckets.  Resize. */
      u32 j, *p;
      i = vec_len (ob->search_buckets);
      vec_resize_aligned (ob->search_buckets,
			  sizeof (b[0]) / sizeof (u32x4) + n_key_u32s,
			  CLIB_CACHE_LINE_BYTES);
      vec_add2 (ob->free_indices, p, 4);
      for (j = 0; j < 4; j++)
	p[j] = 4 * i + j;
    }

  i = vec_pop (ob->free_indices);

  i_set = i & 3;
  b = ((vhash_overflow_search_bucket_t *)
       vec_elt_at_index (ob->search_buckets, i / 4));

  /* Insert result. */
  set_overflow_result (b, i_set, new_result, key_hash);

  /* Insert key. */
  for (i = 0; i < n_key_u32s; i++)
    b->key[i].as_u32[i_set] = vhash_get_key_word (h, i, vi);

  ob->n_overflow++;
  h->n_elts++;

  return /* old result was invalid */ 0;
}

u32
vhash_unset_overflow (vhash_t * h, u32 key_hash, u32 vi, u32 n_key_u32s)
{
  vhash_overflow_buckets_t *ob = vhash_get_overflow_buckets (h, key_hash);
  vhash_overflow_search_bucket_t *b;
  u32 i_set, i, old_result;

  foreach_vhash_overflow_bucket (b, ob, n_key_u32s)
  {
    u32x4 r;

    r = b->result.as_u32x4;
    for (i = 0; i < n_key_u32s; i++)
      r &= vhash_bucket_compare (h, &b->key[0], i, vi);

    old_result = vhash_merge_results (r);
    if (old_result)
      {
	i_set = vhash_non_empty_result_index (r);

	/* Invalidate result and invert key hash so that this will
	   never match since all keys in this overflow bucket have
	   matching key hashs. */
	set_overflow_result (b, i_set, 0, ~key_hash);

	free_overflow_bucket (ob, b, i_set);

	ASSERT (ob->n_overflow > 0);
	ob->n_overflow--;
	h->n_elts--;
	return old_result;
      }
  }

  /* Could not find key. */
  return 0;
}

void
vhash_unset_refill_from_overflow (vhash_t * h,
				  vhash_search_bucket_t * sb,
				  u32 key_hash, u32 n_key_u32s)
{
  vhash_overflow_buckets_t *obs = vhash_get_overflow_buckets (h, key_hash);
  vhash_overflow_search_bucket_t *ob;
  u32 i, j, i_refill, bucket_mask = h->bucket_mask.as_u32[0];

  /* Find overflow element with matching key hash. */
  foreach_vhash_overflow_bucket (ob, obs, n_key_u32s)
  {
    for (i = 0; i < 4; i++)
      {
	if (!ob->result.as_u32[i])
	  continue;
	if ((ob->key_hash.as_u32[i] & bucket_mask)
	    != (key_hash & bucket_mask))
	  continue;

	i_refill = vhash_empty_result_index (sb->result.as_u32x4);
	sb->result.as_u32[i_refill] = ob->result.as_u32[i];
	for (j = 0; j < n_key_u32s; j++)
	  sb->key[j].as_u32[i_refill] = ob->key[j].as_u32[i];
	set_overflow_result (ob, i, 0, ~key_hash);
	free_overflow_bucket (obs, ob, i);
	return;
      }
  }
}

void
vhash_init (vhash_t * h, u32 log2_n_keys, u32 n_key_u32, u32 * hash_seeds)
{
  uword i, j, m;
  vhash_search_bucket_t *b;

  clib_memset (h, 0, sizeof (h[0]));

  /* Must have at least 4 keys (e.g. one search bucket). */
  log2_n_keys = clib_max (log2_n_keys, 2);

  h->log2_n_keys = log2_n_keys;
  h->n_key_u32 = n_key_u32;
  m = pow2_mask (h->log2_n_keys) & ~3;
  for (i = 0; i < VECTOR_WORD_TYPE_LEN (u32); i++)
    h->bucket_mask.as_u32[i] = m;

  /* Allocate and zero search buckets. */
  i = (sizeof (b[0]) / sizeof (u32x4) + n_key_u32) << (log2_n_keys - 2);
  vec_validate_aligned (h->search_buckets, i - 1, CLIB_CACHE_LINE_BYTES);

  for (i = 0; i < ARRAY_LEN (h->find_first_zero_table); i++)
    h->find_first_zero_table[i] = min_log2 (first_set (~i));

  for (i = 0; i < ARRAY_LEN (h->hash_seeds); i++)
    for (j = 0; j < VECTOR_WORD_TYPE_LEN (u32); j++)
      h->hash_seeds[i].as_u32[j] = hash_seeds[i];
}

static_always_inline u32
vhash_main_key_gather (void *_vm, u32 vi, u32 wi, u32 n_key_u32)
{
  vhash_main_t *vm = _vm;
  return vec_elt (vm->keys, vi * n_key_u32 + wi);
}

static_always_inline u32x4
vhash_main_4key_gather (void *_vm, u32 vi, u32 wi, u32 n_key_u32s)
{
  vhash_main_t *vm = _vm;
  u32x4_union_t x;

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

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

static_always_inline u32
vhash_main_set_result (void *_vm, u32 vi, u32 old_result, u32 n_key_u32)
{
  vhash_main_t *vm = _vm;
  u32 *p = vec_elt_at_index (vm->results, vi);
  u32 new_result = p[0];
  p[0] = old_result;
  return new_result;
}

static_always_inline u32
vhash_main_get_result (void *_vm, u32 vi, u32 old_result, u32 n_key_u32)
{
  vhash_main_t *vm = _vm;
  vec_elt (vm->results, vi) = old_result;
  return old_result;
}

static_always_inline u32x4
vhash_main_get_4result (void *_vm, u32 vi, u32x4 old_result, u32 n_key_u32)
{
  vhash_main_t *vm = _vm;
  u32x4 *p = (u32x4 *) vec_elt_at_index (vm->results, vi);
  p[0] = old_result;
  return old_result;
}

#define _(N_KEY_U32)							\
  static_always_inline u32						\
  vhash_main_key_gather_##N_KEY_U32 (void * _vm, u32 vi, u32 i)		\
  { return vhash_main_key_gather (_vm, vi, i, N_KEY_U32); }		\
									\
  static_always_inline u32x4						\
  vhash_main_4key_gather_##N_KEY_U32 (void * _vm, u32 vi, u32 i)	\
  { return vhash_main_4key_gather (_vm, vi, i, N_KEY_U32); }		\
									\
  clib_pipeline_stage_static						\
  (vhash_main_gather_keys_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_gather_4key_stage						\
       (vm->vhash,							\
	/* vector_index */ i,						\
	vhash_main_4key_gather_##N_KEY_U32,				\
	vm,								\
	N_KEY_U32);							\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_gather_keys_mod_stage_##N_KEY_U32,			\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_gather_key_stage						\
       (vm->vhash,							\
	/* vector_index */ vm->n_vectors_div_4,				\
	/* n_vectors */ vm->n_vectors_mod_4,				\
	vhash_main_key_gather_##N_KEY_U32,				\
	vm,								\
	N_KEY_U32);							\
   })									\
									\
  clib_pipeline_stage							\
  (vhash_main_hash_finalize_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_finalize_stage (vm->vhash, i, N_KEY_U32);			\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_hash_finalize_mod_stage_##N_KEY_U32,			\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_finalize_stage (vm->vhash, vm->n_vectors_div_4, N_KEY_U32);	\
   })									\
									\
  clib_pipeline_stage_static						\
  (vhash_main_get_stage_##N_KEY_U32,					\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_get_4_stage (vm->vhash,					\
			/* vector_index */ i,				\
			vhash_main_get_4result,				\
			vm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_get_mod_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_get_stage (vm->vhash,					\
		      /* vector_index */ vm->n_vectors_div_4,		\
		      /* n_vectors */ vm->n_vectors_mod_4,		\
		      vhash_main_get_result,				\
		      vm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_static						\
  (vhash_main_set_stage_##N_KEY_U32,					\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_set_stage (vm->vhash,					\
		      /* vector_index */ i,				\
		      /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32),	\
		      vhash_main_set_result,				\
		      vm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_set_mod_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_set_stage (vm->vhash,					\
		      /* vector_index */ vm->n_vectors_div_4,		\
		      /* n_vectors */ vm->n_vectors_mod_4,		\
		      vhash_main_set_result,				\
		      vm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_static						\
  (vhash_main_unset_stage_##N_KEY_U32,					\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_unset_stage (vm->vhash,					\
		      /* vector_index */ i,				\
		      /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32),	\
		      vhash_main_get_result,				\
		      vm, N_KEY_U32);					\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_unset_mod_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_unset_stage (vm->vhash,					\
		      /* vector_index */ vm->n_vectors_div_4,		\
		      /* n_vectors */ vm->n_vectors_mod_4,		\
		      vhash_main_get_result,				\
		      vm, N_KEY_U32);					\
   })

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

#undef _

#define _(N_KEY_U32)							\
  clib_pipeline_stage							\
  (vhash_main_hash_mix_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_mix_stage (vm->vhash, i, N_KEY_U32);				\
   })									\
									\
  clib_pipeline_stage_no_inline						\
  (vhash_main_hash_mix_mod_stage_##N_KEY_U32,				\
   vhash_main_t *, vm, i,						\
   {									\
     vhash_mix_stage (vm->vhash, vm->n_vectors_div_4, N_KEY_U32);	\
   })

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

#undef _

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

static void
vhash_main_op (vhash_main_t * vm, vhash_main_op_t op)
{
  u32 n_keys = vec_len (vm->results);

  vm->n_key_u32 = vm->vhash->n_key_u32;

  vhash_validate_sizes (vm->vhash, vm->n_key_u32, n_keys);

  vm->n_vectors_div_4 = n_keys / 4;
  vm->n_vectors_mod_4 = n_keys % 4;

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

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_3_stage				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_get_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_3_stage				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_set_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_3_stage				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_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				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_stage_##N_KEY_U32,		\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_get_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_4_stage				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_stage_##N_KEY_U32,		\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_set_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_4_stage				\
	      (vm->n_vectors_div_4,				\
	       vm,						\
	       vhash_main_gather_keys_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_stage_##N_KEY_U32,		\
	       vhash_main_hash_finalize_stage_##N_KEY_U32,	\
	       vhash_main_unset_stage_##N_KEY_U32);		\
	  break;

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

#undef _
	}
    }


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

#define _(N_KEY_U32)						\
	case N_KEY_U32:						\
	  if (op == GET)					\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_get_mod_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_set_mod_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_3_stage				\
	      (1,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_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,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_get_mod_stage_##N_KEY_U32);		\
	  else if (op == SET)					\
	    clib_pipeline_run_4_stage				\
	      (1,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_set_mod_stage_##N_KEY_U32);		\
	  else							\
	    clib_pipeline_run_4_stage				\
	      (1,						\
	       vm,						\
	       vhash_main_gather_keys_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_mix_mod_stage_##N_KEY_U32,	\
	       vhash_main_hash_finalize_mod_stage_##N_KEY_U32,	\
	       vhash_main_unset_mod_stage_##N_KEY_U32);		\
	  break;

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

#undef _
	}
    }
}

void
vhash_main_get (vhash_main_t * vm)
{
  vhash_main_op (vm, GET);
}

void
vhash_main_set (vhash_main_t * vm)
{
  vhash_main_op (vm, SET);
}

void
vhash_main_unset (vhash_main_t * vm)
{
  vhash_main_op (vm, UNSET);
}

u32
vhash_resize_incremental (vhash_resize_t * vr, u32 vector_index,
			  u32 n_keys_this_call)
{
  vhash_t *old = vr->old;
  vhash_main_t *vm = &vr->new;
  vhash_t *new = vm->vhash;
  uword i, j, n_key_u32;

  n_key_u32 = old->n_key_u32;

  if (vector_index == 0)
    {
      u32 hash_seeds[3];
      hash_seeds[0] = old->hash_seeds[0].as_u32[0];
      hash_seeds[1] = old->hash_seeds[1].as_u32[0];
      hash_seeds[2] = old->hash_seeds[2].as_u32[0];
      vhash_init (new, old->log2_n_keys + 1, n_key_u32, hash_seeds);
    }

  vec_reset_length (vm->keys);
  vec_reset_length (vm->results);

  if (0 == (vector_index >> old->log2_n_keys))
    {
      for (i = vector_index; 0 == (i >> (old->log2_n_keys - 2)); i++)
	{
	  vhash_search_bucket_t *b =
	    vhash_get_search_bucket_with_index (old, 4 * i, n_key_u32);
	  u32 r, *k;

#define _(I)					\
  if ((r = b->result.as_u32[I]) != 0)		\
    {						\
      vec_add1 (vm->results, r - 1);		\
      vec_add2 (vm->keys, k, n_key_u32);	\
      for (j = 0; j < n_key_u32; j++)		\
	k[j] = b->key[j].as_u32[I];		\
    }

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

#undef _

	  if (vec_len (vm->results) >= n_keys_this_call)
	    {
	      vhash_main_op (vm, SET);
	      return i;
	    }
	}
    }

  /* Add overflow buckets. */
  {
    vhash_overflow_buckets_t *ob;
    vhash_overflow_search_bucket_t *b;

    for (ob = old->overflow_buckets;
	 ob < old->overflow_buckets + ARRAY_LEN (old->overflow_buckets); ob++)
      {
	foreach_vhash_overflow_bucket (b, ob, old->n_key_u32)
	{
	  u32 r, *k;

#define _(I)					\
  if ((r = b->result.as_u32[I]) != 0)		\
    {						\
      vec_add1 (vm->results, r - 1);		\
      vec_add2 (vm->keys, k, n_key_u32);	\
      for (j = 0; j < n_key_u32; j++)		\
	k[j] = b->key[j].as_u32[I];		\
    }

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

#undef _
	}
      }
  }

  vhash_main_op (vm, SET);

  /* Let caller know we are done. */
  return ~0;
}

void
vhash_resize (vhash_t * old, u32 log2_n_keys)
{
  static vhash_resize_t vr;
  vhash_t new;
  u32 i = 0;

  vr.old = old;
  vr.new.vhash = &new;

  while (1)
    {
      i = vhash_resize_incremental (&vr, i, 1024);
      if (i == ~0)
	break;
    }

  vhash_free (old);
  *old = new;
}

#endif /* CLIB_HAVE_VEC128 */

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