Made assets::data_stores thread safe.
This commit is contained in:
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user