Skip to content

Commit 5d2efda

Browse files
jbachorikclaude
andcommitted
Extract counter decrement logic into decrementCounters()
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent a846b1e commit 5d2efda

2 files changed

Lines changed: 27 additions & 25 deletions

File tree

ddprof-lib/src/main/cpp/callTraceHashTable.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -102,42 +102,43 @@ CallTraceHashTable::~CallTraceHashTable() {
102102
}
103103

104104

105-
ChunkList CallTraceHashTable::clearTableOnly() {
106-
// Wait for all refcount guards to clear before detaching chunks
107-
RefCountGuard::waitForAllRefCountsToClear();
108-
105+
void CallTraceHashTable::decrementCounters() {
109106
#ifdef COUNTERS
110107
// Compute and decrement the global counters for everything in this table.
111-
// After waitForAllRefCountsToClear() there are no concurrent writers, so
112-
// plain iteration (same pattern as collect()) is safe.
108+
// Must only be called after waitForAllRefCountsToClear() so there are no
109+
// concurrent writers and plain iteration is safe.
113110
// Use a set to deduplicate: put() may store the same CallTrace* pointer in
114111
// both a newer and an older table (when findCallTrace finds it in prev()),
115112
// but the counter was only incremented once, so we must only count it once.
116-
{
117-
const size_t header_size = sizeof(CallTrace) - sizeof(ASGCT_CallFrame);
118-
long long freed_bytes = 0;
119-
long long freed_traces = 0;
120-
std::unordered_set<CallTrace*> seen;
121-
for (LongHashTable *t = _table; t != nullptr; t = t->prev()) {
122-
u64 *keys = t->keys();
123-
CallTraceSample *values = t->values();
124-
u32 capacity = t->capacity();
125-
for (u32 slot = 0; slot < capacity; slot++) {
126-
if (keys[slot] != 0) {
127-
CallTrace *trace = values[slot].acquireTrace();
128-
if (trace != nullptr && trace != CallTraceSample::PREPARING) {
129-
if (seen.insert(trace).second) {
130-
freed_bytes += header_size + trace->num_frames * sizeof(ASGCT_CallFrame);
131-
freed_traces++;
132-
}
113+
const size_t header_size = sizeof(CallTrace) - sizeof(ASGCT_CallFrame);
114+
long long freed_bytes = 0;
115+
long long freed_traces = 0;
116+
std::unordered_set<CallTrace*> seen;
117+
for (LongHashTable *t = _table; t != nullptr; t = t->prev()) {
118+
u64 *keys = t->keys();
119+
CallTraceSample *values = t->values();
120+
u32 capacity = t->capacity();
121+
for (u32 slot = 0; slot < capacity; slot++) {
122+
if (keys[slot] != 0) {
123+
CallTrace *trace = values[slot].acquireTrace();
124+
if (trace != nullptr && trace != CallTraceSample::PREPARING) {
125+
if (seen.insert(trace).second) {
126+
freed_bytes += header_size + trace->num_frames * sizeof(ASGCT_CallFrame);
127+
freed_traces++;
133128
}
134129
}
135130
}
136131
}
137-
Counters::increment(CALLTRACE_STORAGE_BYTES, -freed_bytes);
138-
Counters::increment(CALLTRACE_STORAGE_TRACES, -freed_traces);
139132
}
133+
Counters::increment(CALLTRACE_STORAGE_BYTES, -freed_bytes);
134+
Counters::increment(CALLTRACE_STORAGE_TRACES, -freed_traces);
140135
#endif // COUNTERS
136+
}
137+
138+
ChunkList CallTraceHashTable::clearTableOnly() {
139+
// Wait for all refcount guards to clear before detaching chunks
140+
RefCountGuard::waitForAllRefCountsToClear();
141+
decrementCounters();
141142

142143
// Clear previous chain pointers to prevent traversal during deallocation
143144
for (LongHashTable *table = _table; table != nullptr; table = table->prev()) {

ddprof-lib/src/main/cpp/callTraceHashTable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class CallTraceHashTable {
7272
CallTrace *storeCallTrace(int num_frames, ASGCT_CallFrame *frames,
7373
bool truncated, u64 trace_id);
7474
CallTrace *findCallTrace(LongHashTable *table, u64 hash);
75+
void decrementCounters();
7576

7677

7778
public:

0 commit comments

Comments
 (0)