/**
 * @file hash_table.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief libyang generic hash table implementation
 *
 * Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#include "hash_table.h"

#include <assert.h>
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "compat.h"
#include "dict.h"
#include "log.h"
#include "ly_common.h"

LIBYANG_API_DEF uint32_t
lyht_hash_multi(uint32_t hash, const char *key_part, size_t len)
{
    uint32_t i;

    if (key_part && len) {
        for (i = 0; i < len; ++i) {
            hash += key_part[i];
            hash += (hash << 10);
            hash ^= (hash >> 6);
        }
    } else {
        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);
    }

    return hash;
}

LIBYANG_API_DEF uint32_t
lyht_hash(const char *key, size_t len)
{
    uint32_t hash;

    hash = lyht_hash_multi(0, key, len);
    return lyht_hash_multi(hash, NULL, len);
}

static LY_ERR
lyht_init_hlists_and_records(struct ly_ht *ht)
{
    struct ly_ht_rec *rec;
    uint32_t i;

    ht->recs = calloc(ht->size, ht->rec_size);
    LY_CHECK_ERR_RET(!ht->recs, LOGMEM(NULL), LY_EMEM);
    for (i = 0; i < ht->size; i++) {
        rec = lyht_get_rec(ht->recs, ht->rec_size, i);
        if (i != ht->size) {
            rec->next = i + 1;
        } else {
            rec->next = LYHT_NO_RECORD;
        }
    }

    ht->hlists = malloc(sizeof(ht->hlists[0]) * ht->size);
    LY_CHECK_ERR_RET(!ht->hlists, free(ht->recs); LOGMEM(NULL), LY_EMEM);
    for (i = 0; i < ht->size; i++) {
        ht->hlists[i].first = LYHT_NO_RECORD;
        ht->hlists[i].last = LYHT_NO_RECORD;
    }
    ht->first_free_rec = 0;

    return LY_SUCCESS;
}

LIBYANG_API_DEF struct ly_ht *
lyht_new(uint32_t size, uint16_t val_size, lyht_value_equal_cb val_equal, void *cb_data, uint16_t resize)
{
    struct ly_ht *ht;

    /* check that 2^x == size (power of 2) */
    assert(size && !(size & (size - 1)));
    assert(val_equal && val_size);
    assert(resize == 0 || resize == 1);

    if (size < LYHT_MIN_SIZE) {
        size = LYHT_MIN_SIZE;
    }

    ht = malloc(sizeof *ht);
    LY_CHECK_ERR_RET(!ht, LOGMEM(NULL), NULL);

    ht->used = 0;
    ht->size = size;
    ht->val_equal = val_equal;
    ht->cb_data = cb_data;
    ht->resize = resize;

    ht->rec_size = SIZEOF_LY_HT_REC + val_size;
    if (lyht_init_hlists_and_records(ht) != LY_SUCCESS) {
        free(ht);
        return NULL;
    }

    return ht;
}

LIBYANG_API_DEF lyht_value_equal_cb
lyht_set_cb(struct ly_ht *ht, lyht_value_equal_cb new_val_equal)
{
    lyht_value_equal_cb prev;

    prev = ht->val_equal;
    ht->val_equal = new_val_equal;
    return prev;
}

LIBYANG_API_DEF void *
lyht_set_cb_data(struct ly_ht *ht, void *new_cb_data)
{
    void *prev;

    prev = ht->cb_data;
    ht->cb_data = new_cb_data;
    return prev;
}

LIBYANG_API_DEF struct ly_ht *
lyht_dup(const struct ly_ht *orig)
{
    struct ly_ht *ht;

    LY_CHECK_ARG_RET(NULL, orig, NULL);

    ht = lyht_new(orig->size, orig->rec_size - SIZEOF_LY_HT_REC, orig->val_equal, orig->cb_data, orig->resize ? 1 : 0);
    if (!ht) {
        return NULL;
    }

    memcpy(ht->hlists, orig->hlists, sizeof(ht->hlists[0]) * orig->size);
    memcpy(ht->recs, orig->recs, (size_t)orig->size * orig->rec_size);
    ht->used = orig->used;
    return ht;
}

LIBYANG_API_DEF void
lyht_free(struct ly_ht *ht, void (*val_free)(void *val_p))
{
    struct ly_ht_rec *rec;
    uint32_t hlist_idx;
    uint32_t rec_idx;

    if (!ht) {
        return;
    }

    if (val_free) {
        LYHT_ITER_ALL_RECS(ht, hlist_idx, rec_idx, rec) {
            val_free(&rec->val);
        }
    }
    free(ht->hlists);
    free(ht->recs);
    free(ht);
}

/**
 * @brief Resize a hash table.
 *
 * @param[in] ht Hash table to resize.
 * @param[in] operation Operation to perform. 1 to enlarge, -1 to shrink, 0 to only rehash all records.
 * @param[in] check Whether to check if the value has already been inserted or not.
 * @return LY_ERR value.
 */
static LY_ERR
lyht_resize(struct ly_ht *ht, int operation, int check)
{
    struct ly_ht_rec *rec;
    struct ly_ht_hlist *old_hlists;
    unsigned char *old_recs;
    uint32_t old_first_free_rec;
    uint32_t i, old_size;
    uint32_t rec_idx;

    old_hlists = ht->hlists;
    old_recs = ht->recs;
    old_size = ht->size;
    old_first_free_rec = ht->first_free_rec;

    if (operation > 0) {
        /* double the size */
        ht->size <<= 1;
    } else if (operation < 0) {
        /* half the size */
        ht->size >>= 1;
    }

    if (lyht_init_hlists_and_records(ht) != LY_SUCCESS) {
        ht->hlists = old_hlists;
        ht->recs = old_recs;
        ht->size = old_size;
        ht->first_free_rec = old_first_free_rec;
        return LY_EMEM;
    }

    /* reset used, it will increase again */
    ht->used = 0;

    /* add all the old records into the new records array */
    for (i = 0; i < old_size; i++) {
        for (rec_idx = old_hlists[i].first, rec = lyht_get_rec(old_recs, ht->rec_size, rec_idx);
                rec_idx != LYHT_NO_RECORD;
                rec_idx = rec->next, rec = lyht_get_rec(old_recs, ht->rec_size, rec_idx)) {
            LY_ERR ret;

            if (check) {
                ret = lyht_insert(ht, rec->val, rec->hash, NULL);
            } else {
                ret = lyht_insert_no_check(ht, rec->val, rec->hash, NULL);
            }

            assert(!ret);
            (void)ret;
        }
    }

    /* final touches */
    free(old_recs);
    free(old_hlists);
    return LY_SUCCESS;
}

/**
 * @brief Search for a record with specific value and hash.
 *
 * @param[in] ht Hash table to search in.
 * @param[in] val_p Pointer to the value to find.
 * @param[in] hash Hash to find.
 * @param[in] mod Whether the operation modifies the hash table (insert or remove) or not (find).
 * @param[in] val_equal Callback for checking value equivalence.
 * @param[out] col Optional collision number of @p rec_p, 0 for no collision.
 * @param[out] rec_p Found exact matching record, may be a collision of @p crec_p.
 * @return LY_ENOTFOUND if no record found,
 * @return LY_SUCCESS if record was found.
 */
static LY_ERR
lyht_find_rec(const struct ly_ht *ht, void *val_p, uint32_t hash, ly_bool mod, lyht_value_equal_cb val_equal,
        uint32_t *col, struct ly_ht_rec **rec_p)
{
    uint32_t hlist_idx = hash & (ht->size - 1);
    struct ly_ht_rec *rec;
    uint32_t rec_idx;

    if (col) {
        *col = 0;
    }
    *rec_p = NULL;

    LYHT_ITER_HLIST_RECS(ht, hlist_idx, rec_idx, rec) {
        if ((rec->hash == hash) && val_equal(val_p, &rec->val, mod, ht->cb_data)) {
            *rec_p = rec;
            return LY_SUCCESS;
        }

        if (col) {
            *col = *col + 1;
        }
    }

    /* not found even in collisions */
    return LY_ENOTFOUND;
}

LIBYANG_API_DEF LY_ERR
lyht_find(const struct ly_ht *ht, void *val_p, uint32_t hash, void **match_p)
{
    struct ly_ht_rec *rec;

    if (match_p) {
        *match_p = NULL;
    }

    lyht_find_rec(ht, val_p, hash, 0, ht->val_equal, NULL, &rec);

    if (rec && match_p) {
        *match_p = rec->val;
    }
    return rec ? LY_SUCCESS : LY_ENOTFOUND;
}

LIBYANG_API_DEF LY_ERR
lyht_find_with_val_cb(const struct ly_ht *ht, void *val_p, uint32_t hash, lyht_value_equal_cb val_equal, void **match_p)
{
    struct ly_ht_rec *rec;

    lyht_find_rec(ht, val_p, hash, 0, val_equal ? val_equal : ht->val_equal, NULL, &rec);

    if (rec && match_p) {
        *match_p = rec->val;
    }
    return rec ? LY_SUCCESS : LY_ENOTFOUND;
}

LIBYANG_API_DEF LY_ERR
lyht_find_next_with_collision_cb(const struct ly_ht *ht, void *val_p, uint32_t hash,
        lyht_value_equal_cb collision_val_equal, void **match_p)
{
    struct ly_ht_rec *rec;
    uint32_t rec_idx;
    uint32_t i;

    /* find the record of the previously found value */
    if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, &i, &rec)) {
        /* not found, cannot happen */
        LOGINT_RET(NULL);
    }

    for (rec_idx = rec->next, rec = lyht_get_rec(ht->recs, ht->rec_size, rec_idx);
            rec_idx != LYHT_NO_RECORD;
            rec_idx = rec->next, rec = lyht_get_rec(ht->recs, ht->rec_size, rec_idx)) {

        if (rec->hash != hash) {
            continue;
        }

        if (collision_val_equal) {
            if (collision_val_equal(val_p, &rec->val, 0, ht->cb_data)) {
                /* even the value matches */
                if (match_p) {
                    *match_p = rec->val;
                }
                return LY_SUCCESS;
            }
        } else if (ht->val_equal(val_p, &rec->val, 0, ht->cb_data)) {
            /* even the value matches */
            if (match_p) {
                *match_p = rec->val;
            }
            return LY_SUCCESS;
        }
    }

    /* the last equal value was already returned */
    return LY_ENOTFOUND;
}

LIBYANG_API_DEF LY_ERR
lyht_find_next(const struct ly_ht *ht, void *val_p, uint32_t hash, void **match_p)
{
    return lyht_find_next_with_collision_cb(ht, val_p, hash, NULL, match_p);
}

static LY_ERR
_lyht_insert_with_resize_cb(struct ly_ht *ht, void *val_p, uint32_t hash, lyht_value_equal_cb resize_val_equal,
        void **match_p, int check)
{
    uint32_t hlist_idx = hash & (ht->size - 1);
    LY_ERR r, ret = LY_SUCCESS;
    struct ly_ht_rec *rec, *prev_rec;
    lyht_value_equal_cb old_val_equal = NULL;
    uint32_t rec_idx;

    if (check) {
        if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, &rec) == LY_SUCCESS) {
            if (rec && match_p) {
                *match_p = rec->val;
            }
            return LY_EEXIST;
        }
    }

    rec_idx = ht->first_free_rec;
    assert(rec_idx < ht->size);
    rec = lyht_get_rec(ht->recs, ht->rec_size, rec_idx);
    ht->first_free_rec = rec->next;

    if (ht->hlists[hlist_idx].first == LYHT_NO_RECORD) {
        ht->hlists[hlist_idx].first = rec_idx;
    } else {
        prev_rec = lyht_get_rec(ht->recs, ht->rec_size, ht->hlists[hlist_idx].last);
        prev_rec->next = rec_idx;
    }
    rec->next = LYHT_NO_RECORD;
    ht->hlists[hlist_idx].last = rec_idx;

    rec->hash = hash;
    memcpy(&rec->val, val_p, ht->rec_size - SIZEOF_LY_HT_REC);
    if (match_p) {
        *match_p = (void *)&rec->val;
    }

    /* check size & enlarge if needed */
    ++ht->used;
    if (ht->resize) {
        r = (ht->used * LYHT_HUNDRED_PERCENTAGE) / ht->size;
        if ((ht->resize == 1) && (r >= LYHT_FIRST_SHRINK_PERCENTAGE)) {
            /* enable shrinking */
            ht->resize = 2;
        }
        if ((ht->resize == 2) && (r >= LYHT_ENLARGE_PERCENTAGE)) {
            if (resize_val_equal) {
                old_val_equal = lyht_set_cb(ht, resize_val_equal);
            }

            /* enlarge */
            ret = lyht_resize(ht, 1, check);
            /* if hash_table was resized, we need to find new matching value */
            if ((ret == LY_SUCCESS) && match_p) {
                ret = lyht_find(ht, val_p, hash, match_p);
                assert(!ret);
            }

            if (resize_val_equal) {
                lyht_set_cb(ht, old_val_equal);
            }
        }
    }
    return ret;
}

LIBYANG_API_DEF LY_ERR
lyht_insert_with_resize_cb(struct ly_ht *ht, void *val_p, uint32_t hash, lyht_value_equal_cb resize_val_equal,
        void **match_p)
{
    return _lyht_insert_with_resize_cb(ht, val_p, hash, resize_val_equal, match_p, 1);
}

LIBYANG_API_DEF LY_ERR
lyht_insert(struct ly_ht *ht, void *val_p, uint32_t hash, void **match_p)
{
    return _lyht_insert_with_resize_cb(ht, val_p, hash, NULL, match_p, 1);
}

LIBYANG_API_DEF LY_ERR
lyht_insert_no_check(struct ly_ht *ht, void *val_p, uint32_t hash, void **match_p)
{
    return _lyht_insert_with_resize_cb(ht, val_p, hash, NULL, match_p, 0);
}

LIBYANG_API_DEF LY_ERR
lyht_remove_with_resize_cb(struct ly_ht *ht, void *val_p, uint32_t hash, lyht_value_equal_cb resize_val_equal)
{
    struct ly_ht_rec *found_rec, *prev_rec, *rec;
    uint32_t hlist_idx = hash & (ht->size - 1);
    LY_ERR r, ret = LY_SUCCESS;
    lyht_value_equal_cb old_val_equal = NULL;
    uint32_t prev_rec_idx;
    uint32_t rec_idx;

    if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, &found_rec)) {
        LOGARG(NULL, hash);
        return LY_ENOTFOUND;
    }

    prev_rec_idx = LYHT_NO_RECORD;
    LYHT_ITER_HLIST_RECS(ht, hlist_idx, rec_idx, rec) {
        if (rec == found_rec) {
            break;
        }
        prev_rec_idx = rec_idx;
    }

    if (prev_rec_idx == LYHT_NO_RECORD) {
        ht->hlists[hlist_idx].first = rec->next;
        if (rec->next == LYHT_NO_RECORD) {
            ht->hlists[hlist_idx].last = LYHT_NO_RECORD;
        }
    } else {
        prev_rec = lyht_get_rec(ht->recs, ht->rec_size, prev_rec_idx);
        prev_rec->next = rec->next;
        if (rec->next == LYHT_NO_RECORD) {
            ht->hlists[hlist_idx].last = prev_rec_idx;
        }
    }

    rec->next = ht->first_free_rec;
    ht->first_free_rec = rec_idx;

    /* check size & shrink if needed */
    --ht->used;
    if (ht->resize == 2) {
        r = (ht->used * LYHT_HUNDRED_PERCENTAGE) / ht->size;
        if ((r < LYHT_SHRINK_PERCENTAGE) && (ht->size > LYHT_MIN_SIZE)) {
            if (resize_val_equal) {
                old_val_equal = lyht_set_cb(ht, resize_val_equal);
            }

            /* shrink */
            ret = lyht_resize(ht, -1, 1);

            if (resize_val_equal) {
                lyht_set_cb(ht, old_val_equal);
            }
        }
    }

    return ret;
}

LIBYANG_API_DEF LY_ERR
lyht_remove(struct ly_ht *ht, void *val_p, uint32_t hash)
{
    return lyht_remove_with_resize_cb(ht, val_p, hash, NULL);
}

LIBYANG_API_DEF uint32_t
lyht_get_fixed_size(uint32_t item_count)
{
    if (item_count == 0) {
        return 1;
    }

    /* return next power of 2 (greater or equal) */
    item_count--;
    item_count |= item_count >> 1;
    item_count |= item_count >> 2;
    item_count |= item_count >> 4;
    item_count |= item_count >> 8;
    item_count |= item_count >> 16;

    return item_count + 1;
}
