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.
dvmhost/src/common/concurrent/unordered_map.h

387 lines
11 KiB

// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Common Library
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
/**
* @file unordered_map.h
* @ingroup concurrency
*/
#if !defined(__CONCURRENCY_UNORDERED_MAP_H__)
#define __CONCURRENCY_UNORDERED_MAP_H__
#include "common/concurrent/concurrent_lock.h"
#include "common/Thread.h"
#include <unordered_map>
#include <mutex>
namespace concurrent
{
// ---------------------------------------------------------------------------
// Class Declaration
// ---------------------------------------------------------------------------
/**
* @brief Thread-safe std::unordered_map.
* @ingroup concurrency
*/
template <typename Key, typename T>
class unordered_map : public concurrent_lock
{
using __std = std::unordered_map<Key, T>;
public:
using iterator = typename __std::iterator;
using const_iterator = typename __std::const_iterator;
/**
* @brief Initializes a new instance of the unordered_map class.
*/
unordered_map() : concurrent_lock(),
m_map()
{
/* stub */
}
/**
* @brief Initializes a new instance of the unordered_map class.
* @param size Initial size of the unordered_map.
*/
unordered_map(size_t size) : concurrent_lock(),
m_map(size)
{
/* stub */
}
/**
* @brief Finalizes a instance of the unordered_map class.
*/
virtual ~unordered_map()
{
m_map.clear();
}
/**
* @brief Unordered map assignment operator.
* @param other A map of identical element and allocator types.
*/
unordered_map& operator=(const unordered_map& other)
{
__lock();
m_map = other.m_map;
__unlock();
return *this;
}
/**
* @brief Unordered map assignment operator.
* @param other A map of identical element and allocator types.
*/
unordered_map& operator=(const std::unordered_map<Key, T>& other)
{
__lock();
m_map = other;
__unlock();
return *this;
}
/**
* @brief Unordered map assignment operator.
* @param other A map of identical element and allocator types.
*/
unordered_map& operator=(unordered_map& other)
{
__lock();
m_map = other.m_map;
__unlock();
return *this;
}
/**
* @brief Unordered map assignment operator.
* @param other A map of identical element and allocator types.
*/
unordered_map& operator=(std::unordered_map<Key, T>& other)
{
__lock();
m_map = other;
__unlock();
return *this;
}
/**
* @brief Assigns a given value to a unordered_map.
* @param size Number of elements to be assigned.
* @param value Value to be assigned.
*/
void assign(size_t size, const T& value)
{
__lock();
m_map.assign(size, value);
__unlock();
}
/**
* @brief Returns a read/write iterator that points to the first
* element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns iterator
*/
iterator begin()
{
__spinlock();
return m_map.begin();
}
/**
* @brief Returns a read-only (constant) iterator that points to the
* first element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns const_iterator
*/
const_iterator begin() const
{
__spinlock();
return m_map.begin();
}
/**
* @brief Returns a read/write iterator that points one past the last
* element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns iterator
*/
iterator end()
{
__spinlock();
return m_map.end();
}
/**
* @brief Returns a read-only (constant) iterator that points one past
* the last element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns const_iterator
*/
const_iterator end() const
{
__spinlock();
return m_map.end();
}
/**
* @brief Returns a read-only (constant) iterator that points to the
* first element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns const_iterator
*/
const_iterator cbegin() const
{
__spinlock();
return m_map.cbegin();
}
/**
* @brief Returns a read-only (constant) iterator that points one past
* the last element in the unordered_map. Iteration is done in ordinary
* element order.
* @returns const_iterator
*/
const_iterator cend() const
{
__spinlock();
return m_map.cend();
}
/**
* @brief Gets the element at the specified key.
* @param key Key of the element to get.
* @returns T& Element at the specified key.
*/
T& operator[](const Key& key)
{
__spinlock();
return m_map[key];
}
/**
* @brief Gets the element at the specified key.
* @param key Key of the element to get.
* @returns const T& Element at the specified key.
*/
const T& operator[](const Key& key) const
{
__spinlock();
return m_map[key];
}
/**
* @brief Gets the element at the specified key.
* @param key Key of the element to get.
* @returns T& Element at the specified key.
*/
T& at(const Key& key)
{
__spinlock();
return m_map.at(key);
}
/**
* @brief Gets the element at the specified key.
* @param key Key of the element to get.
* @returns const T& Element at the specified key.
*/
const T& at(const Key& key) const
{
__spinlock();
return m_map.at(key);
}
/**
* @brief Gets the total number of elements in the unordered_map.
* @returns size_t Total number of elements in the unordered_map.
*/
size_t size() const
{
__spinlock();
return m_map.size();
}
/**
* @brief Checks if the unordered_map is empty.
* @returns bool True if the unordered_map is empty, false otherwise.
*/
bool empty() const
{
__spinlock();
return m_map.empty();
}
/**
* @brief Checks if the unordered_map contains the specified key.
* @param key Key to check.
* @returns bool True if the unordered_map contains the specified key, false otherwise.
*/
bool contains(const Key& key) const
{
__spinlock();
return m_map.contains(key);
}
/**
* @brief Inserts a new element into the unordered_map.
* @param key Key of the element to insert.
* @param value Value of the element to insert.
*/
void insert(const Key& key, const T& value)
{
__lock();
m_map.insert({key, value});
__unlock();
}
/**
* @brief Removes the element at the specified key.
* @param key Key of the element to remove.
*/
void erase(const Key& key)
{
__lock();
m_map.erase(key);
__unlock();
}
/**
* @brief Removes the element at the specified iterator.
* @param position Iterator of the element to remove.
*/
void erase(const_iterator position)
{
__lock();
m_map.erase(position);
__unlock();
}
/**
* @brief Removes the elements in the specified range.
* @param first Iterator of the first element to remove.
* @param last Iterator of the last element to remove.
*/
void erase(const_iterator first, const_iterator last)
{
__lock();
m_map.erase(first, last);
__unlock();
}
/**
* @brief Clears the unordered_map.
*/
void clear()
{
__lock();
m_map.clear();
__unlock();
}
/**
* @brief Tries to locate an element in an unordered_map.
* @param key Key to be located.
* @return iterator Iterator pointing to sought-after element, or end() if not
* found.
*/
iterator find(const Key& key)
{
__spinlock();
return m_map.find(key);
}
/**
* @brief Tries to locate an element in an unordered_map.
* @param key Key to be located.
* @return const_iterator Iterator pointing to sought-after element, or end() if not
* found.
*/
const_iterator find(const Key& key) const
{
__spinlock();
return m_map.find(key);
}
/**
* @brief Finds the number of elements.
* @param key Key to count.
* @return size_t Number of elements with specified key.
*/
size_t count(const Key& key) const
{
__spinlock();
return m_map.count(key);
}
/**
* @brief Gets the underlying unordered_map.
* @returns std::unordered_map<Key, T>& Underlying unordered_map.
*/
std::unordered_map<Key, T>& get()
{
__spinlock();
return m_map;
}
/**
* @brief Gets the underlying unordered_map.
* @returns const std::unordered_map<Key, T>& Underlying unordered_map.
*/
const std::unordered_map<Key, T>& get() const
{
__spinlock();
return m_map;
}
/**
* @brief Prepare the underlying unordered_map for a specified number of
* elements.
* @param n Number of elements required.
*/
void reserve(size_t n)
{
m_map.reserve(n);
}
private:
std::unordered_map<Key, T> m_map;
};
} // namespace concurrent
#endif // __CONCURRENCY_UNORDERED_MAP_H__

Powered by TurnKey Linux.