/* 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 <string.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);
}
