/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/lhash.h>

#include <assert.h>
#include <limits.h>

#include <openssl/mem.h>

/* kMinNumBuckets is the minimum size of the buckets array in an |_LHASH|. */
static const size_t kMinNumBuckets = 16;

/* kMaxAverageChainLength contains the maximum, average chain length. When the
 * average chain length exceeds this value, the hash table will be resized. */
static const size_t kMaxAverageChainLength = 2;
static const size_t kMinAverageChainLength = 1;

_LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp) {
  _LHASH *ret;

  ret = OPENSSL_malloc(sizeof(_LHASH));
  if (ret == NULL) {
    return NULL;
  }
  memset(ret, 0, sizeof(_LHASH));

  ret->num_buckets = kMinNumBuckets;
  ret->buckets = OPENSSL_malloc(sizeof(LHASH_ITEM *) * ret->num_buckets);
  if (ret->buckets == NULL) {
    OPENSSL_free(ret);
    return NULL;
  }
  memset(ret->buckets, 0, sizeof(LHASH_ITEM *) * ret->num_buckets);

  ret->comp = comp;
  if (ret->comp == NULL) {
    ret->comp = (lhash_cmp_func) strcmp;
  }
  ret->hash = hash;
  if (ret->hash == NULL) {
    ret->hash = (lhash_hash_func) lh_strhash;
  }

  return ret;
}

void lh_free(_LHASH *lh) {
  size_t i;
  LHASH_ITEM *n, *next;

  if (lh == NULL) {
    return;
  }

  for (i = 0; i < lh->num_buckets; i++) {
    for (n = lh->buckets[i]; n != NULL; n = next) {
      next = n->next;
      OPENSSL_free(n);
    }
  }

  OPENSSL_free(lh->buckets);
  OPENSSL_free(lh);
}

size_t lh_num_items(const _LHASH *lh) { return lh->num_items; }

/* get_next_ptr_and_hash returns a pointer to the pointer that points to the
 * item equal to |data|. In other words, it searches for an item equal to |data|
 * and, if it's at the start of a chain, then it returns a pointer to an
 * element of |lh->buckets|, otherwise it returns a pointer to the |next|
 * element of the previous item in the chain. If an element equal to |data| is
 * not found, it returns a pointer that points to a NULL pointer. If |out_hash|
 * is not NULL, then it also puts the hash value of |data| in |*out_hash|. */
static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash,
                                          const void *data) {
  const uint32_t hash = lh->hash(data);
  LHASH_ITEM *cur, **ret;

  if (out_hash != NULL) {
    *out_hash = hash;
  }

  ret = &lh->buckets[hash % lh->num_buckets];
  for (cur = *ret; cur != NULL; cur = *ret) {
    if (lh->comp(cur->data, data) == 0) {
      break;
    }
    ret = &cur->next;
  }

  return ret;
}

void *lh_retrieve(const _LHASH *lh, const void *data) {
  LHASH_ITEM **next_ptr;

  next_ptr = get_next_ptr_and_hash(lh, NULL, data);

  if (*next_ptr == NULL) {
    return NULL;
  }

  return (*next_ptr)->data;
}

/* lh_rebucket allocates a new array of |new_num_buckets| pointers and
 * redistributes the existing items into it before making it |lh->buckets| and
 * freeing the old array. */
static void lh_rebucket(_LHASH *lh, const size_t new_num_buckets) {
  LHASH_ITEM **new_buckets, *cur, *next;
  size_t i, alloc_size;

  alloc_size = sizeof(LHASH_ITEM *) * new_num_buckets;
  if (alloc_size / sizeof(LHASH_ITEM*) != new_num_buckets) {
    return;
  }

  new_buckets = OPENSSL_malloc(alloc_size);
  if (new_buckets == NULL) {
    return;
  }
  memset(new_buckets, 0, alloc_size);

  for (i = 0; i < lh->num_buckets; i++) {
    for (cur = lh->buckets[i]; cur != NULL; cur = next) {
      const size_t new_bucket = cur->hash % new_num_buckets;
      next = cur->next;
      cur->next = new_buckets[new_bucket];
      new_buckets[new_bucket] = cur;
    }
  }

  OPENSSL_free(lh->buckets);

  lh->num_buckets = new_num_buckets;
  lh->buckets = new_buckets;
}

/* lh_maybe_resize resizes the |buckets| array if needed. */
static void lh_maybe_resize(_LHASH *lh) {
  size_t avg_chain_length;

  if (lh->callback_depth > 0) {
    /* Don't resize the hash if we are currently iterating over it. */
    return;
  }

  assert(lh->num_buckets >= kMinNumBuckets);
  avg_chain_length = lh->num_items / lh->num_buckets;

  if (avg_chain_length > kMaxAverageChainLength) {
    const size_t new_num_buckets = lh->num_buckets * 2;

    if (new_num_buckets > lh->num_buckets) {
      lh_rebucket(lh, new_num_buckets);
    }
  } else if (avg_chain_length < kMinAverageChainLength &&
             lh->num_buckets > kMinNumBuckets) {
    size_t new_num_buckets = lh->num_buckets / 2;

    if (new_num_buckets < kMinNumBuckets) {
      new_num_buckets = kMinNumBuckets;
    }

    lh_rebucket(lh, new_num_buckets);
  }
}

int lh_insert(_LHASH *lh, void **old_data, void *data) {
  uint32_t hash;
  LHASH_ITEM **next_ptr, *item;

  *old_data = NULL;
  next_ptr = get_next_ptr_and_hash(lh, &hash, data);


  if (*next_ptr != NULL) {
    /* An element equal to |data| already exists in the hash table. It will be
     * replaced. */
    *old_data = (*next_ptr)->data;
    (*next_ptr)->data = data;
    return 1;
  }

  /* An element equal to |data| doesn't exist in the hash table yet. */
  item = OPENSSL_malloc(sizeof(LHASH_ITEM));
  if (item == NULL) {
    return 0;
  }

  item->data = data;
  item->hash = hash;
  item->next = NULL;
  *next_ptr = item;
  lh->num_items++;
  lh_maybe_resize(lh);

  return 1;
}

void *lh_delete(_LHASH *lh, const void *data) {
  LHASH_ITEM **next_ptr, *item, *ret;

  next_ptr = get_next_ptr_and_hash(lh, NULL, data);

  if (*next_ptr == NULL) {
    /* No such element. */
    return NULL;
  }

  item = *next_ptr;
  *next_ptr = item->next;
  ret = item->data;
  OPENSSL_free(item);

  lh->num_items--;
  lh_maybe_resize(lh);

  return ret;
}

static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *),
                              void (*arg_func)(void *, void *), void *arg) {
  size_t i;
  LHASH_ITEM *cur, *next;

  if (lh == NULL) {
    return;
  }

  if (lh->callback_depth < UINT_MAX) {
    /* |callback_depth| is a saturating counter. */
    lh->callback_depth++;
  }

  for (i = 0; i < lh->num_buckets; i++) {
    for (cur = lh->buckets[i]; cur != NULL; cur = next) {
      next = cur->next;
      if (arg_func) {
        arg_func(cur->data, arg);
      } else {
        no_arg_func(cur->data);
      }
    }
  }

  if (lh->callback_depth < UINT_MAX) {
    lh->callback_depth--;
  }

  /* The callback may have added or removed elements and the non-zero value of
   * |callback_depth| will have suppressed any resizing. Thus any needed
   * resizing is done here. */
  lh_maybe_resize(lh);
}

void lh_doall(_LHASH *lh, void (*func)(void *)) {
  lh_doall_internal(lh, func, NULL, NULL);
}

void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) {
  lh_doall_internal(lh, NULL, func, arg);
}

uint32_t lh_strhash(const char *c) {
  /* The following hash seems to work very well on normal text strings
   * no collisions on /usr/dict/words and it distributes on %2^n quite
   * well, not as good as MD5, but still good. */
  unsigned long ret = 0;
  long n;
  unsigned long v;
  int r;

  if ((c == NULL) || (*c == '\0')) {
    return (ret);
  }

  n = 0x100;
  while (*c) {
    v = n | (*c);
    n += 0x100;
    r = (int)((v >> 2) ^ v) & 0x0f;
    ret = (ret << r) | (ret >> (32 - r));
    ret &= 0xFFFFFFFFL;
    ret ^= v * v;
    c++;
  }

  return ((ret >> 16) ^ ret);
}
