/*
    Copyright (c) 2012-2013 250bpm s.r.o.  All rights reserved.

    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 "hash.h"
#include "fast.h"
#include "alloc.h"
#include "cont.h"
#include "err.h"

#define NN_HASH_INITIAL_SLOTS 32

static uint32_t nn_hash_key (uint32_t key);

void nn_hash_init (struct nn_hash *self)
{
    uint32_t i;

    self->slots = NN_HASH_INITIAL_SLOTS;
    self->items = 0;
    self->array = nn_alloc (sizeof (struct nn_list) * NN_HASH_INITIAL_SLOTS,
        "hash map");
    alloc_assert (self->array);
    for (i = 0; i != NN_HASH_INITIAL_SLOTS; ++i)
        nn_list_init (&self->array [i]);
}

void nn_hash_term (struct nn_hash *self)
{
    uint32_t i;

    for (i = 0; i != self->slots; ++i)
        nn_list_term (&self->array [i]);
    nn_free (self->array);
}

void nn_hash_insert (struct nn_hash *self, uint32_t key,
    struct nn_hash_item *item)
{
    struct nn_list_item *it;
    uint32_t i;
    uint32_t oldslots;
    struct nn_list *oldarray;
    struct nn_hash_item *hitm;
    uint32_t newslot;

    i = nn_hash_key (key) % self->slots;

    for (it = nn_list_begin (&self->array [i]);
          it != nn_list_end (&self->array [i]);
          it = nn_list_next (&self->array [i], it))
        nn_assert (nn_cont (it, struct nn_hash_item, list)->key != key);

    item->key = key;
    nn_list_insert (&self->array [i], &item->list,
        nn_list_end (&self->array [i]));
    ++self->items;

    /*  If the hash is getting full, double the amount of slots and
        re-hash all the items. */
    if (nn_slow (self->items * 2 > self->slots && self->slots < 0x80000000)) {

        /*  Allocate new double-sized array of slots. */
        oldslots = self->slots;
        oldarray = self->array;
        self->slots *= 2;
        self->array = nn_alloc (sizeof (struct nn_list) * self->slots,
            "hash map");
        alloc_assert (self->array);
        for (i = 0; i != self->slots; ++i)
            nn_list_init (&self->array [i]);

        /*  Move the items from old slot array to new slot array. */
        for (i = 0; i != oldslots; ++i) {
            while (!nn_list_empty (&oldarray [i])) {
                hitm = nn_cont (nn_list_begin (&oldarray [i]),
                     struct nn_hash_item, list);
                nn_list_erase (&oldarray [i], &hitm->list);
                newslot = nn_hash_key (hitm->key) % self->slots;
                nn_list_insert (&self->array [newslot], &hitm->list,
                    nn_list_end (&self->array [newslot]));
            }

            nn_list_term (&oldarray [i]);
        }

        /*  Deallocate the old array of slots. */
        nn_free (oldarray);
    }
}

void nn_hash_erase (struct nn_hash *self, struct nn_hash_item *item)
{
    uint32_t slot;

    slot = nn_hash_key (item->key) % self->slots;
    nn_list_erase (&self->array [slot], &item->list);
}

struct nn_hash_item *nn_hash_get (struct nn_hash *self, uint32_t key)
{
    uint32_t slot;
    struct nn_list_item *it;
    struct nn_hash_item *item;

    slot = nn_hash_key (key) % self->slots;

    for (it = nn_list_begin (&self->array [slot]);
          it != nn_list_end (&self->array [slot]);
          it = nn_list_next (&self->array [slot], it)) {
        item = nn_cont (it, struct nn_hash_item, list);
        if (item->key == key)
            return item;
    }

    return NULL;
}

uint32_t nn_hash_key (uint32_t key)
{
    /*  TODO: This is a randomly chosen hashing function. Give some thought
        to picking a more fitting one. */
    key = (key ^ 61) ^ (key >> 16);
    key += key << 3;
    key = key ^ (key >> 4);
    key = key * 0x27d4eb2d;
    key = key ^ (key >> 15);

    return key;
}

void nn_hash_item_init (struct nn_hash_item *self)
{
    nn_list_item_init (&self->list);
}

void nn_hash_item_term (struct nn_hash_item *self)
{
    nn_list_item_term (&self->list);
}

