Leaked source code of windows server 2003
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.

348 lines
7.2 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. class CMAPException
  15. {
  16. public:
  17. DWORD m_ErrorCode;
  18. CMAPException(DWORD errorCode = 0) : m_ErrorCode(errorCode) {}
  19. };
  20. template<class T>
  21. class MAPAllocator : public allocator<T> {
  22. public:
  23. MAPAllocator() : allocator<T>() {}
  24. pointer
  25. allocate(size_type n, const void *hint) {
  26. T* ptr;
  27. ptr = (T *)operator new( (size_t)n * sizeof(T));
  28. if( NULL == ptr ) {
  29. throw CMAPException(ERROR_NOT_ENOUGH_MEMORY);
  30. }
  31. return ptr;
  32. }
  33. char *
  34. _Charalloc(size_type sz) {
  35. return (char *)allocate( sz, NULL );
  36. }
  37. //
  38. // No need to overload construct(),
  39. //
  40. // void construct(pointer p, const T& val);
  41. //
  42. // The member function constructs an object of type T at p by evaluating
  43. // the placement new expression new ((void *)p) T(val).
  44. //
  45. };
  46. template<class KEY, class T, class Pred = less<KEY>, class A = MAPAllocator<T> >
  47. class MAP : public map<KEY, T, Pred, A> {
  48. private:
  49. //
  50. // Difference between this MAP<> and STL's map<> is that this
  51. // template protect data via critical section, refer to STL's map<>
  52. // for detail of member function.
  53. //
  54. // critical section to lock the tree.
  55. CCriticalSection m_CriticalSection;
  56. //
  57. //map<KEY, T, Pred, A>::iterator m_it;
  58. public:
  59. // LOCK_ITERATOR, derive from STL's map<>::iterator
  60. typedef typename map<KEY, T, Pred, A>::iterator Iter_base;
  61. struct __Iterator : Iter_base {
  62. CCriticalSection& lock;
  63. __Iterator(
  64. const __Iterator& it
  65. ) : lock(it.lock)
  66. /*++
  67. --*/
  68. {
  69. lock.Lock();
  70. *this = it;
  71. }
  72. __Iterator(
  73. CCriticalSection& m,
  74. iterator it
  75. ) :
  76. lock(m)
  77. {
  78. lock.Lock();
  79. *(map<KEY, T, Pred, A>::iterator *)this = it;
  80. }
  81. ~__Iterator()
  82. {
  83. lock.UnLock();
  84. }
  85. __Iterator&
  86. operator=(const __Iterator& it )
  87. {
  88. if( this != &it )
  89. {
  90. // No additional Lock() here since
  91. // our constructor already holding a lock
  92. *(map<KEY, T, Pred, A>::iterator *)this = (map<KEY, T, Pred, A>::iterator)it;
  93. }
  94. return *this;
  95. }
  96. };
  97. typedef __Iterator LOCK_ITERATOR;
  98. LOCK_ITERATOR
  99. begin()
  100. /*++
  101. overload map<>::begin()
  102. --*/
  103. {
  104. // Double lock is necessary, caller could do
  105. // <...>::LOCK_ITERATOR it = <>.find();
  106. // and before LOCK_ITERATOR destructor got call, call might do
  107. // it = <>.find() again, that will increase lock count by 1 and
  108. // no way to release it.
  109. CCriticalSectionLocker lock( m_CriticalSection );
  110. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::begin());
  111. }
  112. explicit
  113. MAP(
  114. const Pred& comp = Pred(),
  115. const A& al = A()
  116. ) : map<KEY, T, Pred, A>( comp, al )
  117. /*++
  118. --*/
  119. {
  120. //m_it = end();
  121. }
  122. MAP(const map& x) : map(x)
  123. {
  124. m_it = end();
  125. }
  126. MAP(
  127. const value_type *first,
  128. const value_type *last,
  129. const Pred& comp = Pred(),
  130. const A& al = A()
  131. ) : map( first, last, comp, al )
  132. {
  133. //m_it = end();
  134. }
  135. //virtual ~MAP()
  136. //{
  137. // map<KEY, T, Pred, A>::~map();
  138. //}
  139. //---------------------------------------------------------
  140. void
  141. Cleanup()
  142. {
  143. erase_all();
  144. }
  145. //---------------------------------------------------------
  146. void
  147. Lock()
  148. /*++
  149. Explicity lock the data tree
  150. --*/
  151. {
  152. m_CriticalSection.Lock();
  153. }
  154. //---------------------------------------------------------
  155. void
  156. Unlock()
  157. /*++
  158. lock lock the data tree
  159. --*/
  160. {
  161. m_CriticalSection.UnLock();
  162. }
  163. //---------------------------------------------------------
  164. bool
  165. TryLock()
  166. /*++
  167. Try locking the tree, same as Win32's TryEnterCriticalSection().
  168. --*/
  169. {
  170. return m_CriticalSection.TryLock();
  171. }
  172. //---------------------------------------------------------
  173. typename A::reference operator[](
  174. const KEY& key
  175. )
  176. /*++
  177. Overload map<>::operator[] to lock tree.
  178. --*/
  179. {
  180. CCriticalSectionLocker lock( m_CriticalSection );
  181. return map<KEY, T, Pred, A>::operator[](key);
  182. }
  183. //---------------------------------------------------------
  184. pair<iterator, bool>
  185. insert(iterator it, const value_type& x)
  186. /*++
  187. overload map<>;;insert()
  188. --*/
  189. {
  190. CCriticalSectionLocker lock( m_CriticalSection );
  191. return map<KEY, T, Pred, A>::insert(Key);
  192. }
  193. //---------------------------------------------------------
  194. void
  195. insert(
  196. const value_type* first,
  197. const value_type* last
  198. )
  199. /*++
  200. overload map<>::insert().
  201. --*/
  202. {
  203. CCriticalSectionLocker lock( m_CriticalSection );
  204. map<KEY, T, Pred, A>::insert(first, lase);
  205. }
  206. //---------------------------------------------------------
  207. LOCK_ITERATOR
  208. erase(
  209. iterator it
  210. )
  211. /*++
  212. overload map<>::erase()
  213. --*/
  214. {
  215. CCriticalSectionLocker lock( m_CriticalSection );
  216. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(it));
  217. }
  218. //---------------------------------------------------------
  219. void
  220. erase_all()
  221. /*++
  222. delete all data in the tree
  223. --*/
  224. {
  225. CCriticalSectionLocker lock( m_CriticalSection );
  226. erase( map<KEY, T, Pred, A>::begin(), end() );
  227. return;
  228. }
  229. //---------------------------------------------------------
  230. LOCK_ITERATOR
  231. erase(
  232. iterator first,
  233. iterator last
  234. )
  235. /*++
  236. Overload map<>::erase()
  237. --*/
  238. {
  239. CCriticalSectionLocker lock( m_CriticalSection );
  240. return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(first, last));
  241. }
  242. //---------------------------------------------------------
  243. size_type
  244. erase(
  245. const KEY& key
  246. )
  247. /*++
  248. overload map<>::erase()
  249. --*/
  250. {
  251. CCriticalSectionLocker lock( m_CriticalSection );
  252. return map<KEY, T, Pred, A>::erase(key);
  253. }
  254. LOCK_ITERATOR
  255. find(
  256. const KEY& key
  257. )
  258. /*++
  259. overload map<>::find()
  260. --*/
  261. {
  262. CCriticalSectionLocker lock( m_CriticalSection );
  263. return LOCK_ITERATOR( m_CriticalSection, map<KEY, T, Pred, A>::find(key) );
  264. }
  265. };
  266. #endif