Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. map.h
  5. Abstract:
  6. Implementation of MAP<> template based on STL's map<>
  7. Author:
  8. HueiWang 2/17/2000
  9. --*/
  10. #ifndef __MAP_H__
  11. #define __MAP_H__
  12. #include "tsstl.h"
  13. #include "locks.h"
  14. template<class KEY, class T, class Pred = less<KEY>, class A = allocator<T> >
  15. class MAP : public map<KEY, T, Pred, A> {
  16. private:
  17. //
  18. // Difference between this MAP<> and STL's map<> is that this
  19. // template protect data via critical section, refer to STL's map<>
  20. // for detail of member function.
  21. //
  22. // critical section to lock the tree.
  23. CCriticalSection m_CriticalSection;
  24. //
  25. //map<KEY, T, Pred, A>::iterator m_it;
  26. public:
  27. // LOCK_ITERATOR, derive from STL's map<>::iterator
  28. typedef struct __Iterator : map<KEY, T, Pred, A>::iterator {
  29. CCriticalSection& lock;
  30. __Iterator(
  31. const __Iterator& it
  32. ) : lock(it.lock)
  33. /*++
  34. --*/
  35. {
  36. lock.Lock();
  37. *this = it;
  38. }
  39. __Iterator(
  40. CCriticalSection& m,
  41. iterator it
  42. ) :
  43. lock(m)
  44. {
  45. lock.Lock();
  46. *(map<KEY, T, Pred, A>::iterator *)this = it;
  47. }
  48. ~__Iterator()
  49. {
  50. lock.UnLock();
  51. }
  52. __Iterator&
  53. operator=(const __Iterator& it )
  54. {
  55. if( this != &it )
  56. {
  57. // No additional Lock() here since
  58. // our constructor already holding a lock
  59. *(map<KEY, T, Pred, A>::iterator *)this = (map<KEY, T, Pred, A>::iterator)it;
  60. }
  61. return *this;
  62. }
  63. } LOCK_ITERATOR;
  64. LOCK_ITERATOR
  65. begin()
  66. /*++
  67. overload map<>::begin()
  68. --*/
  69. {
  70. // Double lock is necessary, caller could do
  71. // <...>::LOCK_ITERATOR it = <>.find();
  72. // and before LOCK_ITERATOR destructor got call, call might do
  73. // it = <>.find() again, that will increase lock count by 1 and
  74. // no way to release it.
  75. CCriticalSectionLocker lock( m_CriticalSection );
  76. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::begin());
  77. }
  78. explicit
  79. MAP(
  80. const Pred& comp = Pred(),
  81. const A& al = A()
  82. ) : map<KEY, T, Pred, A>( comp, al )
  83. /*++
  84. --*/
  85. {
  86. //m_it = end();
  87. }
  88. MAP(const map& x) : map(x)
  89. {
  90. m_it = end();
  91. }
  92. MAP(
  93. const value_type *first,
  94. const value_type *last,
  95. const Pred& comp = Pred(),
  96. const A& al = A()
  97. ) : map( first, last, comp, al )
  98. {
  99. //m_it = end();
  100. }
  101. //virtual ~MAP()
  102. //{
  103. // map<KEY, T, Pred, A>::~map();
  104. //}
  105. //---------------------------------------------------------
  106. void
  107. Cleanup()
  108. {
  109. erase_all();
  110. }
  111. //---------------------------------------------------------
  112. void
  113. Lock()
  114. /*++
  115. Explicity lock the data tree
  116. --*/
  117. {
  118. m_CriticalSection.Lock();
  119. }
  120. //---------------------------------------------------------
  121. void
  122. Unlock()
  123. /*++
  124. lock lock the data tree
  125. --*/
  126. {
  127. m_CriticalSection.UnLock();
  128. }
  129. //---------------------------------------------------------
  130. bool
  131. TryLock()
  132. /*++
  133. Try locking the tree, same as Win32's TryEnterCriticalSection().
  134. --*/
  135. {
  136. return m_CriticalSection.TryLock();
  137. }
  138. //---------------------------------------------------------
  139. A::reference operator[](
  140. const KEY& key
  141. )
  142. /*++
  143. Overload map<>::operator[] to lock tree.
  144. --*/
  145. {
  146. CCriticalSectionLocker lock( m_CriticalSection );
  147. return map<KEY, T, Pred, A>::operator[](key);
  148. }
  149. //---------------------------------------------------------
  150. pair<iterator, bool>
  151. insert(iterator it, const value_type& x)
  152. /*++
  153. overload map<>;;insert()
  154. --*/
  155. {
  156. CCriticalSectionLocker lock( m_CriticalSection );
  157. return map<KEY, T, Pred, A>::insert(Key);
  158. }
  159. //---------------------------------------------------------
  160. void
  161. insert(
  162. const value_type* first,
  163. const value_type* last
  164. )
  165. /*++
  166. overload map<>::insert().
  167. --*/
  168. {
  169. CCriticalSectionLocker lock( m_CriticalSection );
  170. map<KEY, T, Pred, A>::insert(first, lase);
  171. }
  172. //---------------------------------------------------------
  173. LOCK_ITERATOR
  174. erase(
  175. iterator it
  176. )
  177. /*++
  178. overload map<>::erase()
  179. --*/
  180. {
  181. CCriticalSectionLocker lock( m_CriticalSection );
  182. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(it));
  183. }
  184. //---------------------------------------------------------
  185. void
  186. erase_all()
  187. /*++
  188. delete all data in the tree
  189. --*/
  190. {
  191. CCriticalSectionLocker lock( m_CriticalSection );
  192. erase( map<KEY, T, Pred, A>::begin(), end() );
  193. return;
  194. }
  195. //---------------------------------------------------------
  196. LOCK_ITERATOR
  197. erase(
  198. iterator first,
  199. iterator last
  200. )
  201. /*++
  202. Overload map<>::erase()
  203. --*/
  204. {
  205. CCriticalSectionLocker lock( m_CriticalSection );
  206. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(first, last));
  207. }
  208. //---------------------------------------------------------
  209. size_type
  210. erase(
  211. const KEY& key
  212. )
  213. /*++
  214. overload map<>::erase()
  215. --*/
  216. {
  217. CCriticalSectionLocker lock( m_CriticalSection );
  218. return map<KEY, T, Pred, A>::erase(key);
  219. }
  220. LOCK_ITERATOR
  221. find(
  222. const KEY& key
  223. )
  224. /*++
  225. overload map<>::find()
  226. --*/
  227. {
  228. CCriticalSectionLocker lock( m_CriticalSection );
  229. return LOCK_ITERATOR( m_CriticalSection, map<KEY, T, Pred, A>::find(key) );
  230. }
  231. };
  232. #endif