|
4 | 4 |
|
5 | 5 | #include <algorithm>
|
6 | 6 | #include <chrono>
|
| 7 | +#include <string_view> |
7 | 8 | #include <thread>
|
8 | 9 |
|
| 10 | +Datadog::internal::StringArena::StringArena() |
| 11 | +{ |
| 12 | + chunks.emplace_back(); |
| 13 | + chunks.back().reserve(Datadog::internal::StringArena::DEFAULT_SIZE); |
| 14 | +} |
| 15 | + |
| 16 | +void |
| 17 | +Datadog::internal::StringArena::reset() |
| 18 | +{ |
| 19 | + // Free chunks. Keep the first one around so it's easy to reuse this without |
| 20 | + // needing new allocations every time. We can completely drop it to get rid |
| 21 | + // of everything |
| 22 | + // TODO - we could consider keeping more around if it's not too costly. |
| 23 | + // The goal is to not retain more than we need _on average_. If we have |
| 24 | + // mostly small samples and then a rare huge one, we can end up with |
| 25 | + // all samples in our pool using as much memory as the largets ones we've seen |
| 26 | + chunks.front().clear(); |
| 27 | + chunks.erase(++chunks.begin(), chunks.end()); |
| 28 | +} |
| 29 | + |
| 30 | +std::string_view |
| 31 | +Datadog::internal::StringArena::insert(std::string_view s) |
| 32 | +{ |
| 33 | + auto chunk = &chunks.back(); |
| 34 | + if ((chunk->capacity() - chunk->size()) < s.size()) { |
| 35 | + chunk = &chunks.emplace_back(); |
| 36 | + chunk->reserve(std::max(s.size(), Datadog::internal::StringArena::DEFAULT_SIZE)); |
| 37 | + } |
| 38 | + int base = chunk->size(); |
| 39 | + chunk->insert(chunk->end(), s.begin(), s.end()); |
| 40 | + return std::string_view(chunk->data() + base, s.size()); |
| 41 | +} |
| 42 | + |
9 | 43 | Datadog::Sample::Sample(SampleType _type_mask, unsigned int _max_nframes)
|
10 | 44 | : max_nframes{ _max_nframes }
|
11 | 45 | , type_mask{ _type_mask }
|
|
28 | 62 | Datadog::Sample::push_frame_impl(std::string_view name, std::string_view filename, uint64_t address, int64_t line)
|
29 | 63 | {
|
30 | 64 | static const ddog_prof_Mapping null_mapping = { 0, 0, 0, to_slice(""), to_slice("") };
|
31 |
| - name = profile_state.insert_or_get(name); |
32 |
| - filename = profile_state.insert_or_get(filename); |
| 65 | + name = string_storage.insert(name); |
| 66 | + filename = string_storage.insert(filename); |
33 | 67 |
|
34 | 68 | CodeProvenance::get_instance().add_filename(filename);
|
35 | 69 |
|
@@ -73,7 +107,7 @@ Datadog::Sample::push_label(const ExportLabelKey key, std::string_view val)
|
73 | 107 | }
|
74 | 108 |
|
75 | 109 | // Otherwise, persist the val string and add the label
|
76 |
| - val = profile_state.insert_or_get(val); |
| 110 | + val = string_storage.insert(val); |
77 | 111 | auto& label = labels.emplace_back();
|
78 | 112 | label.key = to_slice(key_sv);
|
79 | 113 | label.str = to_slice(val);
|
@@ -106,6 +140,7 @@ Datadog::Sample::clear_buffers()
|
106 | 140 | labels.clear();
|
107 | 141 | locations.clear();
|
108 | 142 | dropped_frames = 0;
|
| 143 | + string_storage.reset(); |
109 | 144 | }
|
110 | 145 |
|
111 | 146 | bool
|
|
0 commit comments