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

@@ -17,7 +17,7 @@ assets::shader_source_store_iterator<Char>::shader_source_store_iterator(
string_iterator_type strings,
length_iterator_type lengths,
metadata_iterator_type metadata,
std::size_t index,
const size_type index,
const offset_type& offset
) :
m_ids{ ids },
@@ -172,65 +172,90 @@ assets::shader_source_store_iterator<Char>::dereference() const
);
}
assets::shader_source_store::id_type assets::shader_source_store::add(
const shader_source_id id,
const shader_source_data& shader_source
) {
bool assets::shader_source_store::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = find(id);
m_strings.reserve(m_strings.size() + shader_source.source.size() + 1);
m_strings.insert(m_strings.end(), shader_source.source.begin(), shader_source.source.end());
m_strings.push_back('\0');
m_lengths.push_back(shader_source.source.size());
m_metadata.push_back(shader_source.meta);
return id;
return insert(result.first, id, data);
}
std::pair<assets::shader_source_store::iterator_type, bool> assets::shader_source_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
template<typename... Ts>
bool assets::shader_source_store::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
auto dst_source_length = count_type{};
const auto src_source_length = data.source.size();
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_lengths.insert(m_lengths.begin() + index, src_source_length);
m_metadata.insert(m_metadata.begin() + index, data.meta);
}
else
{
dst_source_length = m_lengths[index];
m_lengths[index] = src_source_length;
m_metadata[index] = data.meta;
}
const auto dst_string_it = m_strings.begin() + it.m_offset;
ztu::replace_range(
m_strings,
dst_string_it,
dst_string_it + dst_source_length,
data.source.begin(),
data.source.end()
);
const auto index = id_it - m_ids.begin() - match;
if (new_entry)
{
m_strings.insert(m_strings.begin() + it.m_offset + src_source_length, '\0');
}
auto it = begin();
it += index;
return { it, match };
return new_entry;
}
std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
inline std::pair<assets::shader_source_store::iterator, bool> assets::shader_source_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
auto lock = std::shared_lock{ m_mutex };
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto index = id_it - m_ids.begin() - match;
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator_type& it)
inline std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.erase(m_ids.begin() + it.m_index);
const auto begin = m_strings.begin() + it.m_offset;
const auto end = begin + it.m_lengths[it.m_index];
m_strings.erase(begin, end);
const auto strings_begin = m_strings.begin() + it.m_offset;
const auto strings_end = begin + it.m_lengths[it.m_index] + sizeof('\0');
m_strings.erase(strings_begin, strings_end);
m_lengths.erase(m_lengths.begin() + it.m_index);
m_metadata.erase(m_metadata.begin() + it.m_index);
@@ -238,15 +263,25 @@ void assets::shader_source_store::remove(const iterator_type& it)
void assets::shader_source_store::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
m_strings.clear();
m_lengths.clear();
m_metadata.clear();
}
assets::shader_source_store::iterator_type assets::shader_source_store::begin()
std::shared_lock<std::shared_mutex> assets::shader_source_store::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
std::unique_lock<std::shared_mutex> assets::shader_source_store::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
assets::shader_source_store::iterator assets::shader_source_store::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),
@@ -256,9 +291,9 @@ assets::shader_source_store::iterator_type assets::shader_source_store::begin()
};
}
assets::shader_source_store::iterator_type assets::shader_source_store::end()
assets::shader_source_store::iterator assets::shader_source_store::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),