/**
 * @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) */
    LY_CHECK_ARG_RET(NULL, !(size & (size - 1)), val_size, val_equal, (resize == 0) || (resize == 1), NULL);

    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;
}
