/* hash.c -- hash table maintenance
Copyright (C) 1995, 1999, 2002, 2010 Free Software Foundation, Inc.
Written by Greg McGary <gkm@gnu.org> <greg@mcgary.org>

GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <https://www.gnu.org/licenses/>.  */

#include "makeint.h"

#include "hash.h"

#include <assert.h>

#define CALLOC(t, n) ((t *) xcalloc (sizeof (t) * (n)))
#define MALLOC(t, n) ((t *) xmalloc (sizeof (t) * (n)))
#define REALLOC(o, t, n) ((t *) xrealloc ((o), sizeof (t) * (n)))
#define CLONE(o, t, n) ((t *) memcpy (MALLOC (t, (n)), (o), sizeof (t) * (n)))

static void hash_rehash __P((struct hash_table* ht));
static unsigned long round_up_2 __P((unsigned long rough));

/* Implement double hashing with open addressing.  The table size is
   always a power of two.  The secondary ('increment') hash function
   is forced to return an odd-value, in order to be relatively prime
   to the table size.  This guarantees that the increment can
   potentially hit every slot in the table during collision
   resolution.  */

const void *hash_deleted_item = &hash_deleted_item;

/* Force the table size to be a power of two, possibly rounding up the
   given size.  */

void
hash_init (struct hash_table *ht, unsigned long size,
           hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp)
{
  ht->ht_size = round_up_2 (size);
  ht->ht_empty_slots = ht->ht_size;
  ht->ht_vec = CALLOC (void *, ht->ht_size);
  if (ht->ht_vec == 0)
    {
      fprintf (stderr, _("can't allocate %lu bytes for hash table: memory exhausted"),
               ht->ht_size * (unsigned long) sizeof (void *));
      exit (MAKE_TROUBLE);
    }

  ht->ht_capacity = ht->ht_size - (ht->ht_size / 16); /* 93.75% loading factor */
  ht->ht_fill = 0;
  ht->ht_collisions = 0;
  ht->ht_lookups = 0;
  ht->ht_rehashes = 0;
  ht->ht_in_map = 0;
  ht->ht_hash_1 = hash_1;
  ht->ht_hash_2 = hash_2;
  ht->ht_compare = hash_cmp;
}

/* Load an array of items into 'ht'.  */

void
hash_load (struct hash_table *ht, const void *item_table,
           unsigned long cardinality, unsigned long size)
{
  const char *items = (const char *) item_table;
  while (cardinality--)
    {
      hash_insert (ht, items);
      items += size;
    }
}

/* Returns the address of the table slot matching 'key'.  If 'key' is
   not found, return the address of an empty slot suitable for
   inserting 'key'.  The caller is responsible for incrementing
   ht_fill on insertion.  */

void **
hash_find_slot (struct hash_table *ht, const void *key)
{
  void **slot;
  void **deleted_slot = 0;
  unsigned int hash_2 = 0;
  unsigned int hash_1 = (*ht->ht_hash_1) (key);

  ht->ht_lookups++;
  for (;;)
    {
      hash_1 &= (ht->ht_size - 1);
      slot = &ht->ht_vec[hash_1];

      if (*slot == 0)
        return (deleted_slot ? deleted_slot : slot);
      if (*slot == hash_deleted_item)
        {
          if (deleted_slot == 0)
            deleted_slot = slot;
        }
      else
        {
          if (key == *slot)
            return slot;
          if ((*ht->ht_compare) (key, *slot) == 0)
            return slot;
          ht->ht_collisions++;
        }
      if (!hash_2)
          hash_2 = (*ht->ht_hash_2) (key) | 1;
      hash_1 += hash_2;
    }
}

void *
hash_find_item (struct hash_table *ht, const void *key)
{
  void **slot = hash_find_slot (ht, key);
  return ((HASH_VACANT (*slot)) ? 0 : *slot);
}

void *
hash_insert (struct hash_table *ht, const void *item)
{
  void **slot = hash_find_slot (ht, item);
  const void *old_item = *slot;
  hash_insert_at (ht, item, slot);
  return (void *)((HASH_VACANT (old_item)) ? 0 : old_item);
}

void *
hash_insert_at (struct hash_table *ht, const void *item, const void *slot)
{
  const void *old_item = *(void **) slot;

  /* It's illegal to insert while in hash_map*().  */
  assert (! ht->ht_in_map);

  if (HASH_VACANT (old_item))
    {
      ht->ht_fill++;
      if (old_item == 0)
        ht->ht_empty_slots--;
      old_item = item;
    }
  *(void const **) slot = item;
  if (ht->ht_empty_slots < ht->ht_size - ht->ht_capacity)
    {
      hash_rehash (ht);
      return (void *) hash_find_slot (ht, item);
    }
  else
    return (void *) slot;
}

void *
hash_delete (struct hash_table *ht, const void *item)
{
  void **slot = hash_find_slot (ht, item);
  return hash_delete_at (ht, slot);
}

void *
hash_delete_at (struct hash_table *ht, const void *slot)
{
  void *item = *(void **) slot;
  if (!HASH_VACANT (item))
    {
      *(void const **) slot = hash_deleted_item;
      ht->ht_fill--;
      return item;
    }
  else
    return 0;
}

void
hash_free_items (struct hash_table *ht)
{
  void **vec = ht->ht_vec;
  void **end = &vec[ht->ht_size];

  /* It's illegal to free items while in hash_map*().  */
  assert (! ht->ht_in_map);

  for (; vec < end; vec++)
    {
      void *item = *vec;
      if (!HASH_VACANT (item))
        free (item);
      *vec = 0;
    }
  ht->ht_fill = 0;
  ht->ht_empty_slots = ht->ht_size;
}

void
hash_delete_items (struct hash_table *ht)
{
  void **vec = ht->ht_vec;
  void **end = &vec[ht->ht_size];

  /* It's illegal to delete all items while in hash_map*().  */
  assert (! ht->ht_in_map);

  for (; vec < end; vec++)
    *vec = 0;
  ht->ht_fill = 0;
  ht->ht_collisions = 0;
  ht->ht_lookups = 0;
  ht->ht_rehashes = 0;
  ht->ht_empty_slots = ht->ht_size;
}

void
hash_free (struct hash_table *ht, int free_items)
{
  /* It's illegal to free while in hash_map*().  */
  assert (! ht->ht_in_map);

  if (free_items)
    hash_free_items (ht);
  else
    {
      ht->ht_fill = 0;
      ht->ht_empty_slots = ht->ht_size;
    }
  free (ht->ht_vec);
  ht->ht_vec = 0;
  ht->ht_capacity = 0;
}

void
hash_map (struct hash_table *ht, hash_map_func_t map)
{
  void **slot;
  void **end = &ht->ht_vec[ht->ht_size];

  ht->ht_in_map = 1;

  for (slot = ht->ht_vec; slot < end; slot++)
    {
      if (!HASH_VACANT (*slot))
        (*map) (*slot);
    }

  ht->ht_in_map = 0;
}

void
hash_map_arg (struct hash_table *ht, hash_map_arg_func_t map, void *arg)
{
  void **slot;
  void **end = &ht->ht_vec[ht->ht_size];

  ht->ht_in_map = 1;

  for (slot = ht->ht_vec; slot < end; slot++)
    {
      if (!HASH_VACANT (*slot))
        (*map) (*slot, arg);
    }

  ht->ht_in_map = 0;
}

/* Double the size of the hash table in the event of overflow... */

static void
hash_rehash (struct hash_table *ht)
{
  unsigned long old_ht_size = ht->ht_size;
  void **old_vec = ht->ht_vec;
  void **ovp;

  if (ht->ht_fill >= ht->ht_capacity)
    {
      ht->ht_size *= 2;
      ht->ht_capacity = ht->ht_size - (ht->ht_size >> 4);
    }
  ht->ht_rehashes++;
  ht->ht_vec = CALLOC (void *, ht->ht_size);

  for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++)
    {
      if (! HASH_VACANT (*ovp))
        {
          void **slot = hash_find_slot (ht, *ovp);
          *slot = *ovp;
        }
    }
  ht->ht_empty_slots = ht->ht_size - ht->ht_fill;
  free (old_vec);
}

void
hash_print_stats (struct hash_table *ht, FILE *out_FILE)
{
  fprintf (out_FILE, _("Load=%lu/%lu=%.0f%%, "), ht->ht_fill, ht->ht_size,
           100.0 * (double) ht->ht_fill / (double) ht->ht_size);
  fprintf (out_FILE, _("Rehash=%u, "), ht->ht_rehashes);
  fprintf (out_FILE, _("Collisions=%lu/%lu=%.0f%%"), ht->ht_collisions, ht->ht_lookups,
           (ht->ht_lookups
            ? (100.0 * (double) ht->ht_collisions / (double) ht->ht_lookups)
            : 0));
}

/* Dump all items into a NULL-terminated vector.  Use the
   user-supplied vector, or malloc one.  */

void **
hash_dump (struct hash_table *ht, void **vector_0, qsort_cmp_t compare)
{
  void **vector;
  void **slot;
  void **end = &ht->ht_vec[ht->ht_size];

  if (vector_0 == 0)
    vector_0 = MALLOC (void *, ht->ht_fill + 1);
  vector = vector_0;

  for (slot = ht->ht_vec; slot < end; slot++)
    if (!HASH_VACANT (*slot))
      *vector++ = *slot;
  *vector = 0;

  if (compare)
    qsort (vector_0, ht->ht_fill, sizeof (void *), compare);
  return vector_0;
}

/* Round a given number up to the nearest power of 2. */

static unsigned long
round_up_2 (unsigned long n)
{
  n |= (n >> 1);
  n |= (n >> 2);
  n |= (n >> 4);
  n |= (n >> 8);
  n |= (n >> 16);

#if !defined(HAVE_LIMITS_H) || ULONG_MAX > 4294967295
  /* We only need this on systems where unsigned long is >32 bits.  */
  n |= (n >> 32);
#endif

  return n + 1;
}

#define rol32(v, n) \
        ((v) << (n) | ((v) >> (32 - (n))))

/* jhash_mix -- mix 3 32-bit values reversibly. */
#define jhash_mix(a, b, c)                      \
{                                               \
        a -= c;  a ^= rol32(c, 4);  c += b;     \
        b -= a;  b ^= rol32(a, 6);  a += c;     \
        c -= b;  c ^= rol32(b, 8);  b += a;     \
        a -= c;  a ^= rol32(c, 16); c += b;     \
        b -= a;  b ^= rol32(a, 19); a += c;     \
        c -= b;  c ^= rol32(b, 4);  b += a;     \
}

/* jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
#define jhash_final(a, b, c)                    \
{                                               \
        c ^= b; c -= rol32(b, 14);              \
        a ^= c; a -= rol32(c, 11);              \
        b ^= a; b -= rol32(a, 25);              \
        c ^= b; c -= rol32(b, 16);              \
        a ^= c; a -= rol32(c, 4);               \
        b ^= a; b -= rol32(a, 14);              \
        c ^= b; c -= rol32(b, 24);              \
}

/* An arbitrary initial parameter */
#define JHASH_INITVAL           0xdeadbeef

#define sum_get_unaligned_32(r, p)              \
  do {                                          \
    unsigned int val;                           \
    memcpy (&val, (p), 4);                      \
    r += val;                                   \
  } while(0);

unsigned int
jhash(unsigned const char *k, int length)
{
  unsigned int a, b, c;

  /* Set up the internal state */
  a = b = c = JHASH_INITVAL + length;

  /* All but the last block: affect some 32 bits of (a,b,c) */
  while (length > 12) {
    sum_get_unaligned_32(a, k);
    sum_get_unaligned_32(b, k + 4);
    sum_get_unaligned_32(c, k + 8);
    jhash_mix(a, b, c);
    length -= 12;
    k += 12;
  }

  if (!length)
    return c;

  if (length > 8)
    {
      sum_get_unaligned_32(a, k);
      length -= 4;
      k += 4;
    }
  if (length > 4)
    {
      sum_get_unaligned_32(b, k);
      length -= 4;
      k += 4;
    }

  if (length == 4)
    c += (unsigned)k[3]<<24;
  if (length >= 3)
    c += (unsigned)k[2]<<16;
  if (length >= 2)
    c += (unsigned)k[1]<<8;
  c += k[0];
  jhash_final(a, b, c);
  return c;
}

#define UINTSZ sizeof (unsigned int)

#ifdef WORDS_BIGENDIAN
/* The ifs are ordered from the first byte in memory to the last.
   Help the compiler optimize by using static memcpy length.  */
#define sum_up_to_nul(r, p, plen, flag)   \
  do {                                    \
    unsigned int val = 0;                 \
    size_t pn = (plen);                   \
    if (pn >= UINTSZ)                     \
      memcpy (&val, (p), UINTSZ);         \
    else                                  \
      memcpy (&val, (p), pn);             \
    if ((val & 0xFF000000) == 0)          \
      flag = 1;                           \
    else if ((val & 0xFF0000) == 0)       \
      r += val & ~0xFFFF, flag = 1;       \
    else if ((val & 0xFF00) == 0)         \
      r += val & ~0xFF, flag = 1;         \
    else                                  \
      r += val, flag = (val & 0xFF) == 0; \
  } while (0)
#else
/* First detect the presence of zeroes.  If there is none, we can
   sum the 4 bytes directly.  Otherwise, the ifs are ordered as in the
   big endian case, from the first byte in memory to the last.
   Help the compiler optimize by using static memcpy length.  */
#define sum_up_to_nul(r, p, plen, flag)              \
  do {                                               \
    unsigned int val = 0;                            \
    size_t pn = (plen);                              \
    if (pn >= UINTSZ)                                \
      memcpy (&val, (p), UINTSZ);                    \
    else                                             \
      memcpy (&val, (p), pn);                        \
    flag = ((val - 0x01010101) & ~val) & 0x80808080; \
    if (!flag)                                       \
      r += val;                                      \
    else if (val & 0xFF)                             \
      {                                              \
        if ((val & 0xFF00) == 0)                     \
          r += val & 0xFF;                           \
        else if ((val & 0xFF0000) == 0)              \
          r += val & 0xFFFF;                         \
        else                                         \
          r += val;                                  \
      }                                              \
  } while (0)
#endif

unsigned int
jhash_string(unsigned const char *k)
{
  unsigned int a, b, c;
  unsigned int have_nul = 0;
  unsigned const char *start = k;
  size_t klen = strlen ((const char*)k);

  /* Set up the internal state */
  a = b = c = JHASH_INITVAL;

  /* All but the last block: affect some 32 bits of (a,b,c) */
  for (;;) {
    sum_up_to_nul(a, k, klen, have_nul);
    if (have_nul)
      break;
    k += UINTSZ;
    assert (klen >= UINTSZ);
    klen -= UINTSZ;

    sum_up_to_nul(b, k, klen, have_nul);
    if (have_nul)
      break;
    k += UINTSZ;
    assert (klen >= UINTSZ);
    klen -= UINTSZ;

    sum_up_to_nul(c, k, klen, have_nul);
    if (have_nul)
      break;
    k += UINTSZ;
    assert (klen >= UINTSZ);
    klen -= UINTSZ;
    jhash_mix(a, b, c);
  }

  jhash_final(a, b, c);
  return c + (unsigned) (k - start);
}
