Made assets::data_stores thread safe.

This commit is contained in:
zy4n
2025-03-31 20:13:26 +02:00
parent 144126ee7a
commit 0acfe36118
39 changed files with 1772 additions and 1069 deletions

View File

@@ -4,6 +4,8 @@
#include <filesystem>
#include <ranges>
#include <vector>
#include <mutex>
#include <shared_mutex>
template<typename ID>
class file_id_lookup
@@ -29,64 +31,107 @@ public:
using node_type = typename container_type::node_type;
using insert_return_type = typename container_type::insert_return_type;
std::pair<iterator, bool> try_emplace(const key_type& path)
{
std::unique_lock lock(m_mutex);
auto it = m_container.find(path);
const auto is_new = it == m_container.end();
if (is_new) {
it = m_container.emplace_hint(it, path, ID::next());
}
return { it, is_new };
}
[[nodiscard]] bool empty() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.empty();
}
[[nodiscard]] size_type size() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.size();
}
[[nodiscard]] size_type max_size() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.max_size();
}
void by_extension(const std::string_view extension, std::vector<const_pointer>& dst) const
{
std::shared_lock lock(m_mutex);
std::ranges::copy(
m_container |
std::views::filter([
&](const value_type& entry) {
return entry.first.extension() == extension;
}
) |
std::views::transform([
&](const value_type& entry) {
return &entry;
}
),
std::back_inserter(dst)
);
}
[[nodiscard]] bool contains(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.contains(key);
}
[[nodiscard]] size_type count(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.count(key);
}
[[nodiscard]] iterator find(const key_type& key)
{
std::shared_lock lock(m_mutex);
return m_container.find(key);
}
[[nodiscard]] const_iterator find(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.find(key);
}
iterator erase(iterator pos)
{
std::unique_lock lock(m_mutex);
return m_container.erase(pos);
}
iterator erase(const_iterator pos)
{
std::unique_lock lock(m_mutex);
return m_container.erase(pos);
}
iterator erase(const_iterator first, const_iterator last)
{
std::unique_lock lock(m_mutex);
return m_container.erase(first, last);
}
size_type erase(const key_type& key)
{
std::unique_lock lock(m_mutex);
return m_container.erase(key);
}
void clear() noexcept
{
std::unique_lock lock(m_mutex);
m_container.clear();
}
[[nodiscard]] iterator begin() noexcept { return m_container.begin(); }
[[nodiscard]] const_iterator begin() const noexcept { return m_container.begin(); }
[[nodiscard]] const_iterator cbegin() const noexcept { return m_container.cbegin(); }
[[nodiscard]] iterator end() noexcept { return m_container.end(); }
[[nodiscard]] const_iterator end() const noexcept { return m_container.end(); }
[[nodiscard]] const_iterator cend() const noexcept { return m_container.cend(); }
[[nodiscard]] bool empty() const noexcept { return m_container.empty(); }
[[nodiscard]] size_type size() const noexcept { return m_container.size(); }
[[nodiscard]] size_type max_size() const noexcept { return m_container.max_size(); }
void by_extension(
const std::string_view extension,
std::vector<const_pointer>& dst
) const {
std::ranges::copy(
m_container |
std::views::filter(
[&](const value_type& entry)
{
return entry.first.extension() == extension;
}
) |
std::views::transform(
[&](const value_type& entry)
{
return &entry;
}
),
std::back_inserter(dst)
);
}
std::pair<iterator, bool> try_emplace(const key_type& path)
{
auto it = m_container.find(path);
const auto is_new = it == m_container.end();
if (not is_new)
{
it = m_container.emplace_hint(it, path, ID::next());
}
return { it, is_new };
}
[[nodiscard]] bool contains(const key_type& key) const { return m_container.contains(key); }
[[nodiscard]] size_type count(const key_type& key) const { return m_container.count(key); }
[[nodiscard]] iterator find(const key_type& key) { return m_container.find(key); }
[[nodiscard]] const_iterator find(const key_type& key) const { return m_container.find(key); }
iterator erase(iterator pos) { return m_container.erase(pos); }
iterator erase(const_iterator pos) { return m_container.erase(pos); }
iterator erase(const_iterator first, const_iterator last) { return m_container.erase(first, last); }
size_type erase(const key_type& key) { return m_container.erase(key); }
void clear() noexcept { m_container.clear(); }
private:
@@ -101,4 +146,5 @@ private:
}
container_type m_container;
std::shared_mutex m_mutex;
};

View File

@@ -0,0 +1,33 @@
#pragma once
#include <algorithm>
#include <vector>
namespace ztu
{
template<class T, class Allocator, class InputIt>
void replace_range(
std::vector<T, Allocator>& dst,
typename std::vector<T, Allocator>::iterator dst_begin,
typename std::vector<T, Allocator>::iterator dst_end,
InputIt src_begin,
InputIt src_end
) {
const auto dst_size = std::distance(dst_begin, dst_end);
const auto src_size = std::distance(src_begin, src_end);
if (dst_size < src_size)
{
dst.insert(dst_end, src_begin + dst_size, src_end);
}
else if (dst_size > src_size)
{
dst.erase(dst_begin + src_size, dst_end);
}
std::copy_n(src_begin, std::min(src_size, dst_size), dst_begin);
}
}