Skip to content

Commit ec2014e

Browse files
otmeta-codesync[bot]
authored andcommitted
Minimize critical section in BasicQuantileStatMap::registerQuantileStat()
Reviewed By: yfeldblum Differential Revision: D93104557 fbshipit-source-id: 12ffa27a7de46321d648c9b14ad72563af3d94f8
1 parent 17bdca5 commit ec2014e

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

fb303/detail/QuantileStatMap-inl.h

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,29 +227,42 @@ BasicQuantileStatMap<ClockT>::registerQuantileStat(
227227
return p->stat;
228228
}
229229
}
230-
auto countersWLock = counters_.wlock();
231-
if (auto* p = folly::get_ptr(countersWLock->bases, name)) {
232-
return p->stat;
233-
}
230+
231+
// Construct all the map entries before acquiring the wlock. This could be
232+
// done under an upgrade lock, but we instead prioritize avoiding contention
233+
// on unrelated writes than avoiding wasted work. This is consistent with
234+
// ServiceData::getQuantileStat() which also favors optimistic concurrency
235+
// when calling this method.
236+
auto slidingWindowLengths = stat->getSlidingWindowLengths();
237+
std::vector<std::pair<std::string, CounterMapEntry>> counterMapEntries;
238+
counterMapEntries.reserve(
239+
statDefs.size() * (1 + slidingWindowLengths.size()));
234240
for (const auto& statDef : statDefs) {
235241
CounterMapEntry entry;
236242
entry.stat = stat;
237243
entry.statDef = statDef;
238-
detail::cachedAddString(
239-
*countersWLock, makeKey(name, statDef, folly::none), entry);
240-
241-
auto slidingWindowLengths = stat->getSlidingWindowLengths();
244+
counterMapEntries.emplace_back(makeKey(name, statDef, folly::none), entry);
242245

243246
for (auto slidingWindowLength : slidingWindowLengths) {
244247
entry.slidingWindowLength = slidingWindowLength;
245-
detail::cachedAddString(
246-
*countersWLock, makeKey(name, statDef, slidingWindowLength), entry);
248+
counterMapEntries.emplace_back(
249+
makeKey(name, statDef, slidingWindowLength), entry);
247250
}
248251
}
252+
253+
auto nameStr = name.str();
249254
StatMapEntry statMapEntry;
250255
statMapEntry.stat = stat;
251256
statMapEntry.statDefs = std::move(statDefs);
252-
countersWLock->bases.emplace(std::move(name), std::move(statMapEntry));
257+
258+
auto countersWLock = counters_.wlock();
259+
if (auto* p = folly::get_ptr(countersWLock->bases, name)) {
260+
return p->stat;
261+
}
262+
for (auto&& [key, entry] : counterMapEntries) {
263+
detail::cachedAddString(*countersWLock, std::move(key), std::move(entry));
264+
}
265+
countersWLock->bases.emplace(std::move(nameStr), std::move(statMapEntry));
253266
return stat;
254267
}
255268

0 commit comments

Comments
 (0)