#ifndef _WRITE_COPY_HPP_ #define _WRITE_COPY_HPP_ //add之前如果有数据,需要把运行中更改的数据进行保存。 #include #include #include #include #include #include #include #include "visit.h" template struct write_copy_base:acceptor { void accept(visitor &v) { for(std::pair me:m_map) { v.visit(me.second); } } std::unordered_map m_map; int m_version=0; write_copy_base() {} int version()const { return m_version; } int set_version(int v) { return m_version=++v; } V get(K k)const { return m_map[k]; } V get(K k) { auto serch = m_map.find(k); if(serch != m_map.end()) return serch->second; else return nullptr; } std::shared_ptr clone()const { std::shared_ptr ret=std::make_shared(); ret->m_map.insert(m_map.begin(),m_map.end()); ret->set_version(m_version); return ret; } std::shared_ptr clone_add(const std::unordered_map&m)const { std::shared_ptr ret=std::move(clone()); ret->_add(m); return ret; } std::shared_ptr clone_add(K k,V v)const { std::shared_ptr ret=std::move(clone()); ret->_add(k,v); return ret; } std::shared_ptr clone_remove(K k)const { std::shared_ptr ret=std::move(clone()); ret->_remove(k); return ret; } std::shared_ptr clone_remove(const std::vector&list)const { std::shared_ptr ret=std::move(clone()); ret->_remove(list); return ret; } virtual ~write_copy_base() { // std::for_each(m_list.begin(),m_list.end(),[](K*it){ }); } private: void _remove(K k) { m_map.erase(k); } void _remove(const std::vector& v) { for(K k:v) { m_map.erase(k); } } void _add(K k,V v) { m_map.insert(std::make_pair(k,v)); } void _add(const std::unordered_map&m) { m_map.insert(m.begin(),m.end()); } }; template struct safe_shared_ptr { std::atomic m_mutex; std::shared_ptr m_ptr; explicit safe_shared_ptr(std::shared_ptr ptr) { m_mutex=0; m_ptr=ptr; } safe_shared_ptr(safe_shared_ptr&&ptr) { m_mutex.store(ptr.m_mutex.load()); m_ptr=std::move(ptr.get()); } bool set(std::shared_ptr ptr) { lock(); m_ptr=ptr; unlock(); return true; } std::shared_ptr get() { lock(); std::shared_ptr ret=m_ptr; unlock(); return ret; } private: void lock() { int expected=0; while(!m_mutex.compare_exchange_strong(expected,1)) expected=0; assert(m_mutex.load()==1); } void unlock() { m_mutex.store(0); } }; template struct single_base:write_copy_base { typedef write_copy_base base; static safe_shared_ptr m_instance; std::mutex m_mutex; static std::shared_ptr instance() { return m_instance.get(); } void add(K k,V c) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_add(k,c)); } void add(const std::unordered_map&c) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_add(c)); } void remove(K k,V c) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_remove(k,c)); } void remove(const std::unordered_map&c) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_remove(c)); } void remove(const std::vector&list) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_remove(list)); } void remove(K k) { std::lock_guard lock(m_mutex); m_instance.set(base::clone_remove(k)); } }; template safe_shared_ptr single_base::m_instance{std::make_shared()}; #endif