自定义“准线程安全”与“线程安全”的unordered_map泛型基类

准线程安全:map中原素个数改变才加锁,适合读频繁,写不频繁的情况;

 


#include"mutex"
#include"unordered_map"

template
class dict_safe_base
{
private:
    std::unordered_map _map;
    std::mutex _mutex;
public:
    dict_safe_base()
    {
    }

    std::vector visit(std::function(const std::unordered_map&)> visitor_fun)
    {
        std::lock_guard lock(_mutex);

        return visitor_fun(_map);
    }

    V get(K& k)
    {
        std::lock_guard lock(_mutex);

        auto serch = _map.find(k);
        return (_map.end()!=serch) ? serch->second : nullptr;
    }

    void add(K& k, V& v)
    {
        std::lock_guard lock(_mutex);

        _map.insert({k,v});
    }

    void add(const std::unordered_map& m)
    {
        std::lock_guard lock(_mutex);

        _map.insert(m.begin(), m.end());
    }

    void add_replace(K& k, V& v)
    {
        std::lock_guard lock(_mutex);

        _map[k]=v;
    }

    void add_replace(const std::unordered_map& m)
    {
        std::lock_guard lock(_mutex);

        for(auto&d:m)
        {
            _map[d.first]=d.second;
        }
    }

    void erase(K& k)
    {
        std::lock_guard lock(_mutex);

        _map.erase(k);
    }

    void erase(const std::unordered_map& m)
    {
        std::lock_guard lock(_mutex);

        for(auto& k:m)
        {
            _map.erase(k.first);
        }
        //_map.erase(m.begin(), m.end());//不可以,会出错
    }

    void erase(const std::vector& keys)
    {
        std::lock_guard lock(_mutex);

        for(auto& k:keys)
        {
            _map.erase(k);
        }
    }

    uint32_t size()
    {
        std::lock_guard lock(_mutex);

        return _map.size();
    }

    void clear()
    {
        std::lock_guard lock(_mutex);

        _map.clear();
    }

    virtual ~dict_safe_base()
    {
    }
};

struct test_val
{
    test_val(int key, std::string val):val(val),key(key)
    {
    }

    std::string val;
    int key;

    void print()
    {
        std::cout<     }
};
typedef std::shared_ptr test_val_ptr;

std::vector visit_fun(const std::unordered_map& m)
{
    std::vector ret;
    for(auto& d:m)
    {
        if(d.first%2==0)
        {
            ret.push_back(d.second);
        }
    }

    return ret;
}

class test:public dict_safe_base
{

};

int main()
{
    test data;
    std::cout<     for(int i=0;i<3;i++)
    {
        auto kk(std::make_shared(i, "str" + std::to_string(i)));
        data.add(i, kk);
    }
//    0:str0
//    1:str1
//    2:str2
    for(int i=0;i<3;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }
    int i=1;
    data.erase(i);

//    0:str0
//    2:str2
    for(int i=0;i<3;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

    data.clear();

    std::unordered_map dict;
    for(int i=0;i<5;i++)
    {
        auto kk(std::make_shared(i, "str" + std::to_string(i)));
        dict.insert(std::make_pair(i, kk));
    }

//    0:str0
//    1:str1
//    2:str2
//    3:str3
//    4:str4
    data.add(dict);
    for(int i=0;i<5;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

    dict.clear();
    std::vector keys;
    for(int i=0;i<5;i+=2)
    {
        keys.push_back(i);
        auto kk(std::make_shared(i, "str" + std::to_string(i)));
        dict.insert(std::make_pair(i, kk));
    }

//    1:str1
//    3:str3
    data.erase(dict);
    for(int i=0;i<5;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

//    0:str0
//    1:str1
//    2:str2
//    3:str3
//    4:str4
    auto kk(std::make_shared(1, "str" + std::to_string(14)));
    dict.insert(std::make_pair(1, kk));
    data.add(dict);
    for(int i=0;i<5;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

//    0:str0
//    1:str14
//    2:str2
//    3:str3
//    4:str4
//    10:str14
    dict.insert(std::make_pair(10, std::make_shared(10, "str" + std::to_string(14))));
    data.add_replace(dict);
    for(int i=0;i<50;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

//    10:str14
//    0:str0
//    2:str2
//    4:str4
    for(auto&kk:data.visit(visit_fun))
    {
        kk->print();
    }

//    1:str14
//    3:str3
//    10:str14
    data.erase(keys);
    for(int i=0;i<50;i++)
    {
        if(data.get(i))
            data.get(i)->print();
    }

    std::cout<

    return 0;
}

你可能感兴趣的:(C++)