unordered_map线程安全版

1. 设计原因

项目需要使用一个可以支持多线程的轻量级数据库,但类似于Mysql等完备的现成数据库过于大型,会造成功能冗余,于是决定基于std::unorder_map实现线程安全版哈希桶用于存放数据。

2. 采用unorder_map的原因

原先设计是用一个std::vetor存储数据,但vector查询效率低下,无法满足嵌入式需求,后面考虑使用map实现,可是map为红黑树,在性能上仍然不够理想,由此决定采用哈希表做为核心容器,可是自制哈希表需要手写哈希函数,较为复杂,最终决定采用std::unorder_map实现,该容器为标准库维护的哈希桶,平均查询性能为O(1),且对哈希冲突的处理较为完善。

3. 改造unorder_map的原因

unorder_map并未对多线程程序做线程安全处理,在多线程工程下容易出现bug,于是乎我决定采用mutex在需要修改数据时对unorder_map进行上锁。

4. 实现

#pragma once

/**
 * @file database.hpp
 * @author jiyilin 2474803745@qq.com
 * @brief this is a database system
 * @version 0.1
 * @date 2023-07-23
 *
 * @copyright Copyright (c) 2023
 *
 */

#include <unordered_map>
#include <mutex>

namespace DBMS
{
    /**
     * @brief this is a hashi bucket based database
     *
     * @tparam    INDEX             : hashi bucket key value
     * @tparam    DATA              : data

     * @memberof  Data              : hashi bucket for saving data
     * @memberof  m_read_write_lock : readers writer lock
     */
    template <typename INDEX, typename DATA>
    class DataBase
    {
    private:
        std::unordered_map<INDEX, DATA> Data;

        std::mutex m_read_write_lock;

    public:
        /**
         * @brief Construct a new Data Base object
         *
         */
        DataBase() : m_read_write_lock(){};

        /**
         * @brief this function is used to add a key value pair to the database
         *
         * @param index  : key
         * @param value  : data
         * @return true  : successfully added
         * @return false : add failed
         */
        bool Insert(INDEX index, DATA value)
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            if (this->Data.count(index) != 0)
            {
                Log_WARM << index << "already exists , unable to add the data" << Log_END;
                return false;
            }

            try
            {
                this->Data.insert(std::pair(index, value));
            }
            catch (const std::exception &e)
            {
                Log_ERROR << e.what() << Log_END;
                return false;
            }

            return true;
        }

        /**
         * @brief this function is used to search for data in the database
         *
         * @param index  : key for the value to be searched for
         * @param value  : return search results
         * @return true  : the data to be searched exists
         * @return false : the data to be searched does not exist
         */
        bool Find(INDEX index, DATA &value)
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            auto target = this->Data.find(index);
            if (target == this->Data.end())
            {
                return false;
            }

            value = (*target).second;
            return true;
        }

        /**
         * @brief this function is used to delete a record in the database
         *
         * @param index  : key to be deleted
         * @return true  : successfully deleted
         * @return false : delete failed
         */
        bool Delete(INDEX index)
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            auto target = this->Data.find(index);
            if (target == this->Data.end())
            {
                Log_WARM << index << "not present" << Log_END;
                return false;
            }

            this->Data.erase((*target).first);
            return true;
        }

        /**
         * @brief this function is used to modify database data
         *
         * @param index  : the key of the key value pair to be modified
         * @param value  : new data to be written
         * @return true  : successfully modified
         * @return false : modification failed
         */
        bool Change(INDEX index, DATA value)
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            auto target = this->Data.find(index);
            if (target == this->Data.end())
            {
                Log_WARM << index << "not present" << Log_END;
                return false;
            }

            (*target).second = value;
            return true;
        }

        /**
         * @brief determine if the database is empty
         *
         * @return true  : database has no data
         * @return false : database has data
         */
        bool is_empty()
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            return this->Data.empty();
        }

        /**
         * @brief get database size
         *
         * @return int
         */
        int size()
        {
            std::unique_lock<std::mutex> lock(this->m_read_write_lock);

            return this->Data.size();
        }

        /**
         * @brief Destroy the Data Base object
         *
         */
        ~DataBase(){};
    };

} // namespace DBMS

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值