#ifndef KRIMI_DINNER_ENGINE_HASH_H
#define KRIMI_DINNER_ENGINE_HASH_H

#include <stdint.h>

/// \file Hash.h
/// \brief Hash table implementation

/// Special key value used for empty slots
static constexpr uint64_t HASH_EMPTY_KEY = 0;

/// Special key value used for deleted slots
static constexpr uint64_t HASH_TOMBSTONE_KEY = 1;

/// \brief A hash table
class Hash
{
public:
    Hash();
    Hash(uint32_t bucket_count);
    Hash(const Hash& copy);
    Hash& operator=(const Hash& rhs);
    ~Hash();

    /// @brief Retrieves a value
    ///
    /// \param key The key
    /// \param default_value Default value
    /// \return The value for @c key, or @c default_value, if the key was not found
    uint64_t lookup(uint64_t key, uint64_t default_value);

    /// @brief Inserts a value
    ///
    /// Replaces the old value, if a key-value pair with @c key was already inserted.
    /// \param key The key
    /// \param value The value
    /// \return @c true if the insert was successful, @c false otherwise
    bool insert(uint64_t key, uint64_t value);

    /// @brief Removes a key-value pair from the hash table
    ///
    /// \param key The key
    void remove(uint64_t key);

private:
    uint32_t m_bucket_count;
    uint32_t m_used_buckets;
    uint64_t* m_keys;
    uint64_t* m_values;
};

/// Alias for compatibility
using nt_hash = Hash;

#endif
