//===-- ThreadSafeSTLMap.h --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ThreadSafeSTLMap_h_
#define liblldb_ThreadSafeSTLMap_h_

// C Includes
// C++ Includes
#include <map>

// Other libraries and framework includes
// Project includes
#include "lldb/Host/Mutex.h"

namespace lldb_private {

template <typename _Key, typename _Tp>
class ThreadSafeSTLMap
{
public:
    typedef std::map<_Key,_Tp> collection;
    typedef typename collection::iterator iterator;
    typedef typename collection::const_iterator const_iterator;
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    ThreadSafeSTLMap() :
        m_collection (),
        m_mutex (Mutex::eMutexTypeRecursive)
    {
    }

    ~ThreadSafeSTLMap()
    {
    }

    bool
    IsEmpty() const
    {
        Mutex::Locker locker(m_mutex);
        return m_collection.empty();
    }
    
    void
    Clear()
    {
        Mutex::Locker locker(m_mutex);
        return m_collection.clear();
    }

    size_t
    Erase (const _Key& key)
    {
        Mutex::Locker locker(m_mutex);
        return EraseNoLock (key);
    }

    size_t
    EraseNoLock (const _Key& key)
    {
        return m_collection.erase (key);
    }

    bool
    GetValueForKey (const _Key& key, _Tp &value) const
    {
        Mutex::Locker locker(m_mutex);
        return GetValueForKeyNoLock (key, value);
    }

    // Call this if you have already manually locked the mutex using the
    // GetMutex() accessor
    bool
    GetValueForKeyNoLock (const _Key& key, _Tp &value) const
    {
        const_iterator pos = m_collection.find(key);
        if (pos != m_collection.end())
        {
            value = pos->second;
            return true;
        }
        return false;
    }

    bool
    GetFirstKeyForValue (const _Tp &value, _Key& key) const
    {
        Mutex::Locker locker(m_mutex);
        return GetFirstKeyForValueNoLock (value, key);
    }

    bool
    GetFirstKeyForValueNoLock (const _Tp &value, _Key& key) const
    {
        const_iterator pos, end = m_collection.end();
        for (pos = m_collection.begin(); pos != end; ++pos)
        {
            if (pos->second == value)
            {
                key = pos->first;
                return true;
            }
        }
        return false;
    }

    bool
    LowerBound (const _Key& key,
                _Key& match_key,
                _Tp &match_value,
                bool decrement_if_not_equal) const
    {
        Mutex::Locker locker(m_mutex);
        return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal);
    }

    bool
    LowerBoundNoLock (const _Key& key,
                      _Key& match_key,
                      _Tp &match_value,
                      bool decrement_if_not_equal) const
    {
        const_iterator pos = m_collection.lower_bound (key);
        if (pos != m_collection.end())
        {
            match_key = pos->first;
            if (decrement_if_not_equal && key != match_key && pos != m_collection.begin())
            {
                --pos;
                match_key = pos->first;
            }
            match_value = pos->second;
            return true;
        }
        return false;
    }

    iterator
    lower_bound_unsafe (const _Key& key)
    {
        return m_collection.lower_bound (key);
    }

    void
    SetValueForKey (const _Key& key, const _Tp &value)
    {
        Mutex::Locker locker(m_mutex);
        SetValueForKeyNoLock (key, value);
    }

    // Call this if you have already manually locked the mutex using the
    // GetMutex() accessor
    void
    SetValueForKeyNoLock (const _Key& key, const _Tp &value)
    {
        m_collection[key] = value;
    }

    Mutex &
    GetMutex ()
    {
        return m_mutex;
    }

private:
    collection m_collection;
    mutable Mutex m_mutex;

    //------------------------------------------------------------------
    // For ThreadSafeSTLMap only
    //------------------------------------------------------------------
    DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLMap);
};


} // namespace lldb_private

#endif  // liblldb_ThreadSafeSTLMap_h_
