1
0

write-copy.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #ifndef _WRITE_COPY_HPP_
  2. #define _WRITE_COPY_HPP_
  3. //add之前如果有数据,需要把运行中更改的数据进行保存。
  4. #include <assert.h>
  5. #include <unordered_map>
  6. #include <algorithm>
  7. #include <memory>
  8. #include <mutex>
  9. #include <atomic>
  10. #include <vector>
  11. #include "visit.h"
  12. template<typename T,typename K,typename V>
  13. struct write_copy_base:acceptor<V>
  14. {
  15. void accept(visitor<V> &v)
  16. {
  17. for(std::pair<K,V> me:m_map)
  18. {
  19. v.visit(me.second);
  20. }
  21. }
  22. std::unordered_map<K,V> m_map;
  23. int m_version=0;
  24. write_copy_base()
  25. {}
  26. int version()const
  27. {
  28. return m_version;
  29. }
  30. int set_version(int v)
  31. {
  32. return m_version=++v;
  33. }
  34. V get(K k)const
  35. {
  36. return m_map[k];
  37. }
  38. V get(K k)
  39. {
  40. auto serch = m_map.find(k);
  41. if(serch != m_map.end())
  42. return serch->second;
  43. else
  44. return nullptr;
  45. }
  46. std::shared_ptr<T> clone()const
  47. {
  48. std::shared_ptr<T> ret=std::make_shared<T>();
  49. ret->m_map.insert(m_map.begin(),m_map.end());
  50. ret->set_version(m_version);
  51. return ret;
  52. }
  53. std::shared_ptr<T> clone_add(const std::unordered_map<K,V>&m)const
  54. {
  55. std::shared_ptr<T> ret=std::move(clone());
  56. ret->_add(m);
  57. return ret;
  58. }
  59. std::shared_ptr<T> clone_add(K k,V v)const
  60. {
  61. std::shared_ptr<T> ret=std::move(clone());
  62. ret->_add(k,v);
  63. return ret;
  64. }
  65. std::shared_ptr<T> clone_remove(K k)const
  66. {
  67. std::shared_ptr<T> ret=std::move(clone());
  68. ret->_remove(k);
  69. return ret;
  70. }
  71. std::shared_ptr<T> clone_remove(const std::vector<K>&list)const
  72. {
  73. std::shared_ptr<T> ret=std::move(clone());
  74. ret->_remove(list);
  75. return ret;
  76. }
  77. virtual ~write_copy_base()
  78. {
  79. // std::for_each(m_list.begin(),m_list.end(),[](K*it){ });
  80. }
  81. private:
  82. void _remove(K k)
  83. {
  84. m_map.erase(k);
  85. }
  86. void _remove(const std::vector<K>& v)
  87. {
  88. for(K k:v)
  89. {
  90. m_map.erase(k);
  91. }
  92. }
  93. void _add(K k,V v)
  94. {
  95. m_map.insert(std::make_pair(k,v));
  96. }
  97. void _add(const std::unordered_map<K,V>&m)
  98. {
  99. m_map.insert(m.begin(),m.end());
  100. }
  101. };
  102. template<typename T>
  103. struct safe_shared_ptr
  104. {
  105. std::atomic<int> m_mutex;
  106. std::shared_ptr<T> m_ptr;
  107. explicit safe_shared_ptr(std::shared_ptr<T> ptr)
  108. {
  109. m_mutex=0;
  110. m_ptr=ptr;
  111. }
  112. safe_shared_ptr(safe_shared_ptr<T>&&ptr)
  113. {
  114. m_mutex.store(ptr.m_mutex.load());
  115. m_ptr=std::move(ptr.get());
  116. }
  117. bool set(std::shared_ptr<T> ptr)
  118. {
  119. lock();
  120. m_ptr=ptr;
  121. unlock();
  122. return true;
  123. }
  124. std::shared_ptr<T> get()
  125. {
  126. lock();
  127. std::shared_ptr<T> ret=m_ptr;
  128. unlock();
  129. return ret;
  130. }
  131. private:
  132. void lock()
  133. {
  134. int expected=0;
  135. while(!m_mutex.compare_exchange_strong(expected,1))
  136. expected=0;
  137. assert(m_mutex.load()==1);
  138. }
  139. void unlock()
  140. {
  141. m_mutex.store(0);
  142. }
  143. };
  144. template<typename T,typename K,typename V>
  145. struct single_base:write_copy_base<T,K,V>
  146. {
  147. typedef write_copy_base<T,K,V> base;
  148. static safe_shared_ptr<T> m_instance;
  149. std::mutex m_mutex;
  150. static std::shared_ptr<T> instance()
  151. {
  152. return m_instance.get();
  153. }
  154. void add(K k,V c)
  155. {
  156. std::lock_guard<std::mutex> lock(m_mutex);
  157. m_instance.set(base::clone_add(k,c));
  158. }
  159. void add(const std::unordered_map<K,V>&c)
  160. {
  161. std::lock_guard<std::mutex> lock(m_mutex);
  162. m_instance.set(base::clone_add(c));
  163. }
  164. void remove(K k,V c)
  165. {
  166. std::lock_guard<std::mutex> lock(m_mutex);
  167. m_instance.set(base::clone_remove(k,c));
  168. }
  169. void remove(const std::unordered_map<K,V>&c)
  170. {
  171. std::lock_guard<std::mutex> lock(m_mutex);
  172. m_instance.set(base::clone_remove(c));
  173. }
  174. void remove(const std::vector<K>&list)
  175. {
  176. std::lock_guard<std::mutex> lock(m_mutex);
  177. m_instance.set(base::clone_remove(list));
  178. }
  179. void remove(K k)
  180. {
  181. std::lock_guard<std::mutex> lock(m_mutex);
  182. m_instance.set(base::clone_remove(k));
  183. }
  184. };
  185. template<typename T,typename K,typename V> safe_shared_ptr<T> single_base<T,K,V>::m_instance{std::make_shared<T>()};
  186. #endif