MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / write

Method write

src/Interpreters/Cache/QueryConditionCache.cpp:50–112  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

48}
49
50void QueryConditionCache::write(
51 const UUID & table_id, const String & part_name, UInt64 condition_hash, const String & condition,
52 const MarkRanges & mark_ranges, size_t marks_count, bool has_final_mark)
53{
54 if (table_id == UUIDHelpers::Nil)
55 return; /// Issue #92863: Certain database engines provide no table UUIDs
56
57 Key key = makeKey(table_id, part_name, condition_hash);
58
59#if defined(DEBUG_OR_SANITIZER_BUILD)
60 auto load_func = [&](){ return std::make_shared<Entry>(marks_count, table_id, part_name, condition_hash, condition); };
61#else
62 auto load_func = [&](){ return std::make_shared<Entry>(marks_count); };
63#endif
64
65 auto [entry, inserted] = cache.getOrSet(key, load_func);
66
67 /// Try to avoid acquiring the RW lock below (*) by early-ing out. Matters for systems with lots of cores.
68 {
69 std::shared_lock shared_lock(entry->mutex); /// cheap
70
71 bool need_not_update_marks = true;
72 for (const auto & mark_range : mark_ranges)
73 {
74 /// If the bits are already in the desired state (false), we don't need to update them.
75 need_not_update_marks = std::all_of(entry->matching_marks.begin() + mark_range.begin,
76 entry->matching_marks.begin() + mark_range.end,
77 [](auto b) { return b == false; });
78 if (!need_not_update_marks)
79 break;
80 }
81
82 /// Do we either have no final mark or final mark is already in the desired state?
83 bool need_not_update_final_mark = !has_final_mark || entry->matching_marks[marks_count - 1] == false;
84
85 if (need_not_update_marks && need_not_update_final_mark)
86 return;
87 }
88
89 {
90 std::lock_guard lock(entry->mutex); /// (*)
91
92 chassert(marks_count == entry->matching_marks.size());
93
94 /// The input mark ranges are the areas which the scan can skip later on.
95 for (const auto & mark_range : mark_ranges)
96 std::fill(entry->matching_marks.begin() + mark_range.begin, entry->matching_marks.begin() + mark_range.end, false);
97
98 if (has_final_mark)
99 entry->matching_marks[marks_count - 1] = false;
100 }
101
102 LOG_TEST(
103 logger,
104 "{} entry for table_id: {}, part_name: {}, condition_hash: {}, condition: {}, marks_count: {}, has_final_mark: {}",
105 inserted ? "Inserted" : "Updated",
106 table_id,
107 part_name,

Callers

nothing calls this directly

Calls 3

getOrSetMethod · 0.45
beginMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected