avoid race on read/write to the cache of defaults

This commit is contained in:
nikitamikhaylov 2020-09-30 21:25:02 +03:00
parent 9b46b53fa3
commit 10adac00f4
3 changed files with 35 additions and 18 deletions

View File

@ -387,11 +387,12 @@ void CacheDictionary::has(const PaddedPODArray<Key> & ids, PaddedPODArray<UInt8>
for (const auto row : ext::range(0, rows))
{
const auto id = ids[row];
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
continue;
{
std::shared_lock shared_lock(default_cache_rw_lock);
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
continue;
}
const auto find_result = findCellIdx(id, now);
auto insert_to_answer_routine = [&] ()
@ -480,8 +481,11 @@ void CacheDictionary::has(const PaddedPODArray<Key> & ids, PaddedPODArray<UInt8>
for (const auto row : cache_expired_or_not_found_ids[key])
out[row] = true;
else
{
std::unique_lock unique_lock(default_cache_rw_lock);
/// Cache this key as default.
default_keys.insert(key);
}
}
}

View File

@ -330,6 +330,9 @@ private:
/// readers. Surprisingly this lock is also used for last_exception pointer.
mutable std::shared_mutex rw_lock;
/// This lock is used only for read/write into cache of default keys.
mutable std::shared_mutex default_cache_rw_lock;
/// Actual size will be increased to match power of 2
const size_t size;

View File

@ -62,9 +62,13 @@ void CacheDictionary::getItemsNumberImpl(
{
const auto id = ids[row];
/// First check if this key in the cache of default keys.
if (default_keys.find(id) != default_keys.end())
continue;
{
std::shared_lock shared_lock(default_cache_rw_lock);
/// First check if this key in the cache of default keys.
if (default_keys.find(id) != default_keys.end())
continue;
}
/** cell should be updated if either:
* 1. ids do not match,
@ -171,6 +175,7 @@ void CacheDictionary::getItemsNumberImpl(
} else
{
/// Add key to the cache of default keys.
std::unique_lock unique_lock(default_cache_rw_lock);
default_keys.emplace(key);
}
}
@ -199,11 +204,14 @@ void CacheDictionary::getItemsString(
{
const auto id = ids[row];
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
{
const auto string_ref = get_default(row);
out->insertData(string_ref.data, string_ref.size);
std::shared_lock shared_lock(default_cache_rw_lock);
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
{
const auto string_ref = get_default(row);
out->insertData(string_ref.data, string_ref.size);
}
}
const auto find_result = findCellIdx(id, now);
@ -250,14 +258,15 @@ void CacheDictionary::getItemsString(
for (const auto row : ext::range(0, ids.size()))
{
const auto id = ids[row];
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
{
const auto string_ref = get_default(row);
out->insertData(string_ref.data, string_ref.size);
std::shared_lock shared_lock(default_cache_rw_lock);
/// Check if the key is stored in the cache of defaults.
if (default_keys.find(id) != default_keys.end())
{
const auto string_ref = get_default(row);
out->insertData(string_ref.data, string_ref.size);
}
}
const auto find_result = findCellIdx(id, now);
auto insert_value_routine = [&]()
@ -374,6 +383,7 @@ void CacheDictionary::getItemsString(
value = std::get<String>(found_it->second.values[attribute_index]);
else
{
std::unique_lock unique_lock(default_cache_rw_lock);
default_keys.insert(id);
value = get_default(row);
}