124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadSafeSTLMap.h --------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef liblldb_ThreadSafeSTLMap_h_
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define liblldb_ThreadSafeSTLMap_h_
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <map>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Mutex.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace lldb_private {
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertemplate <typename _Key, typename _Tp>
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass ThreadSafeSTLMap
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    typedef std::map<_Key,_Tp> collection;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    typedef typename collection::iterator iterator;
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    typedef typename collection::const_iterator const_iterator;
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Constructors and Destructors
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ThreadSafeSTLMap() :
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_collection (),
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_mutex (Mutex::eMutexTypeRecursive)
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ~ThreadSafeSTLMap()
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
43eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton    bool
44eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton    IsEmpty() const
45eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton    {
46eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton        Mutex::Locker locker(m_mutex);
47eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton        return m_collection.empty();
48eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton    }
4949480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton
5049480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton    void
5149480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton    Clear()
5249480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton    {
5349480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton        Mutex::Locker locker(m_mutex);
5449480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton        return m_collection.clear();
5549480b158ee907f30afea651d2c81a67b5dbc971Greg Clayton    }
56eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Erase (const _Key& key)
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_mutex);
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return EraseNoLock (key);
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EraseNoLock (const _Key& key)
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return m_collection.erase (key);
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetValueForKey (const _Key& key, _Tp &value) const
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_mutex);
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return GetValueForKeyNoLock (key, value);
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Call this if you have already manually locked the mutex using the
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // GetMutex() accessor
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetValueForKeyNoLock (const _Key& key, _Tp &value) const
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const_iterator pos = m_collection.find(key);
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos != m_collection.end())
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            value = pos->second;
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetFirstKeyForValue (const _Tp &value, _Key& key) const
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_mutex);
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return GetFirstKeyForValueNoLock (value, key);
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetFirstKeyForValueNoLock (const _Tp &value, _Key& key) const
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const_iterator pos, end = m_collection.end();
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (pos = m_collection.begin(); pos != end; ++pos)
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (pos->second == value)
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                key = pos->first;
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    LowerBound (const _Key& key,
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                _Key& match_key,
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                _Tp &match_value,
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                bool decrement_if_not_equal) const
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_mutex);
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal);
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    LowerBoundNoLock (const _Key& key,
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                      _Key& match_key,
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                      _Tp &match_value,
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                      bool decrement_if_not_equal) const
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const_iterator pos = m_collection.lower_bound (key);
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos != m_collection.end())
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            match_key = pos->first;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (decrement_if_not_equal && key != match_key && pos != m_collection.begin())
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                --pos;
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                match_key = pos->first;
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            match_value = pos->second;
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    iterator
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lower_bound_unsafe (const _Key& key)
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return m_collection.lower_bound (key);
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SetValueForKey (const _Key& key, const _Tp &value)
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_mutex);
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SetValueForKeyNoLock (key, value);
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Call this if you have already manually locked the mutex using the
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // GetMutex() accessor
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SetValueForKeyNoLock (const _Key& key, const _Tp &value)
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_collection[key] = value;
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex &
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetMutex ()
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return m_mutex;
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    collection m_collection;
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    mutable Mutex m_mutex;
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For ThreadSafeSTLMap only
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLMap);
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace lldb_private
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif  // liblldb_ThreadSafeSTLMap_h_
185