blob: 703ce481f637c0ae706380e1b8da3172e5a81b93 [file] [log] [blame]
//===-- 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_