/*++ Copyright (c) 1999-2000 Microsoft Corporation Module Name: map.h Abstract: Implementation of MAP<> template based on STL's map<> Author: HueiWang 2/17/2000 --*/ #ifndef __MAP_H__ #define __MAP_H__ #include "tsstl.h" #include "locks.h" template, class A = allocator > class MAP : public map { private: // // Difference between this MAP<> and STL's map<> is that this // template protect data via critical section, refer to STL's map<> // for detail of member function. // // critical section to lock the tree. CCriticalSection m_CriticalSection; // //map::iterator m_it; public: // LOCK_ITERATOR, derive from STL's map<>::iterator typedef struct __Iterator : map::iterator { CCriticalSection& lock; __Iterator( const __Iterator& it ) : lock(it.lock) /*++ --*/ { lock.Lock(); *this = it; } __Iterator( CCriticalSection& m, iterator it ) : lock(m) { lock.Lock(); *(map::iterator *)this = it; } ~__Iterator() { lock.UnLock(); } __Iterator& operator=(const __Iterator& it ) { if( this != &it ) { // No additional Lock() here since // our constructor already holding a lock *(map::iterator *)this = (map::iterator)it; } return *this; } } LOCK_ITERATOR; LOCK_ITERATOR begin() /*++ overload map<>::begin() --*/ { // Double lock is necessary, caller could do // <...>::LOCK_ITERATOR it = <>.find(); // and before LOCK_ITERATOR destructor got call, call might do // it = <>.find() again, that will increase lock count by 1 and // no way to release it. CCriticalSectionLocker lock( m_CriticalSection ); return LOCK_ITERATOR(m_CriticalSection, map::begin()); } explicit MAP( const Pred& comp = Pred(), const A& al = A() ) : map( comp, al ) /*++ --*/ { //m_it = end(); } MAP(const map& x) : map(x) { m_it = end(); } MAP( const value_type *first, const value_type *last, const Pred& comp = Pred(), const A& al = A() ) : map( first, last, comp, al ) { //m_it = end(); } //virtual ~MAP() //{ // map::~map(); //} //--------------------------------------------------------- void Cleanup() { erase_all(); } //--------------------------------------------------------- void Lock() /*++ Explicity lock the data tree --*/ { m_CriticalSection.Lock(); } //--------------------------------------------------------- void Unlock() /*++ lock lock the data tree --*/ { m_CriticalSection.UnLock(); } //--------------------------------------------------------- bool TryLock() /*++ Try locking the tree, same as Win32's TryEnterCriticalSection(). --*/ { return m_CriticalSection.TryLock(); } //--------------------------------------------------------- A::reference operator[]( const KEY& key ) /*++ Overload map<>::operator[] to lock tree. --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return map::operator[](key); } //--------------------------------------------------------- pair insert(iterator it, const value_type& x) /*++ overload map<>;;insert() --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return map::insert(Key); } //--------------------------------------------------------- void insert( const value_type* first, const value_type* last ) /*++ overload map<>::insert(). --*/ { CCriticalSectionLocker lock( m_CriticalSection ); map::insert(first, lase); } //--------------------------------------------------------- LOCK_ITERATOR erase( iterator it ) /*++ overload map<>::erase() --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return LOCK_ITERATOR(m_CriticalSection, map::erase(it)); } //--------------------------------------------------------- void erase_all() /*++ delete all data in the tree --*/ { CCriticalSectionLocker lock( m_CriticalSection ); erase( map::begin(), end() ); return; } //--------------------------------------------------------- LOCK_ITERATOR erase( iterator first, iterator last ) /*++ Overload map<>::erase() --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return LOCK_ITERATOR(m_CriticalSection, map::erase(first, last)); } //--------------------------------------------------------- size_type erase( const KEY& key ) /*++ overload map<>::erase() --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return map::erase(key); } LOCK_ITERATOR find( const KEY& key ) /*++ overload map<>::find() --*/ { CCriticalSectionLocker lock( m_CriticalSection ); return LOCK_ITERATOR( m_CriticalSection, map::find(key) ); } }; #endif