@@ -135,35 +135,35 @@ bool TagExtractorImpl::extractTag(const std::string& stat_name, std::vector<Tag>
135135 return false ;
136136}
137137
138- RawStatData* HeapRawStatDataAllocator::alloc (const std::string& name) {
139- uint64_t num_bytes_to_allocate = RawStatData::structSize (name.size ());
140- RawStatData* data = static_cast <RawStatData*>(::calloc (num_bytes_to_allocate, 1 ));
141- if (data == nullptr ) {
142- throw std::bad_alloc ();
143- }
144- data->checkAndInit (name, num_bytes_to_allocate);
138+ HeapStatData::HeapStatData (absl::string_view key) : name_(key.data(), key.size()) {}
145139
140+ HeapStatData* HeapStatDataAllocator::alloc (absl::string_view name) {
141+ // Any expected truncation of name is done at the callsite. No truncation is
142+ // required to use this allocator.
143+ auto data = std::make_unique<HeapStatData>(name);
146144 Thread::ReleasableLockGuard lock (mutex_);
147- auto ret = stats_.insert (data);
148- RawStatData * existing_data = *ret.first ;
145+ auto ret = stats_.insert (data. get () );
146+ HeapStatData * existing_data = *ret.first ;
149147 lock.release ();
150148
151- if (!ret.second ) {
152- ::free (data);
153- ++existing_data->ref_count_ ;
154- return existing_data;
155- } else {
156- return data;
149+ if (ret.second ) {
150+ return data.release ();
157151 }
152+ ++existing_data->ref_count_ ;
153+ return existing_data;
158154}
159155
160156/* *
161- * Counter implementation that wraps a RawStatData.
157+ * Counter implementation that wraps a StatData. StatData must have data members:
158+ * std::atomic<int64_t> value_;
159+ * std::atomic<int64_t> pending_increment_;
160+ * std::atomic<int16_t> flags_;
161+ * std::atomic<int16_t> ref_count_;
162162 */
163- class CounterImpl : public Counter , public MetricImpl {
163+ template < class StatData > class CounterImpl : public Counter , public MetricImpl {
164164public:
165- CounterImpl (RawStatData & data, RawStatDataAllocator & alloc, std::string&& tag_extracted_name ,
166- std::vector<Tag>&& tags)
165+ CounterImpl (StatData & data, StatDataAllocatorImpl<StatData> & alloc,
166+ std::string&& tag_extracted_name, std:: vector<Tag>&& tags)
167167 : MetricImpl(data.name_, std::move(tag_extracted_name), std::move(tags)), data_(data),
168168 alloc_ (alloc) {}
169169 ~CounterImpl () { alloc_.free (data_); }
@@ -182,17 +182,17 @@ class CounterImpl : public Counter, public MetricImpl {
182182 uint64_t value () const override { return data_.value_ ; }
183183
184184private:
185- RawStatData & data_;
186- RawStatDataAllocator & alloc_;
185+ StatData & data_;
186+ StatDataAllocatorImpl<StatData> & alloc_;
187187};
188188
189189/* *
190- * Gauge implementation that wraps a RawStatData .
190+ * Gauge implementation that wraps a StatData .
191191 */
192- class GaugeImpl : public Gauge , public MetricImpl {
192+ template < class StatData > class GaugeImpl : public Gauge , public MetricImpl {
193193public:
194- GaugeImpl (RawStatData & data, RawStatDataAllocator & alloc, std::string&& tag_extracted_name ,
195- std::vector<Tag>&& tags)
194+ GaugeImpl (StatData & data, StatDataAllocatorImpl<StatData> & alloc,
195+ std::string&& tag_extracted_name, std:: vector<Tag>&& tags)
196196 : MetricImpl(data.name_, std::move(tag_extracted_name), std::move(tags)), data_(data),
197197 alloc_ (alloc) {}
198198 ~GaugeImpl () { alloc_.free (data_); }
@@ -217,8 +217,8 @@ class GaugeImpl : public Gauge, public MetricImpl {
217217 bool used () const override { return data_.flags_ & Flags::Used; }
218218
219219private:
220- RawStatData & data_;
221- RawStatDataAllocator & alloc_;
220+ StatData & data_;
221+ StatDataAllocatorImpl<StatData> & alloc_;
222222};
223223
224224TagProducerImpl::TagProducerImpl (const envoy::config::metrics::v2::StatsConfig& config) {
@@ -319,47 +319,28 @@ TagProducerImpl::addDefaultExtractors(const envoy::config::metrics::v2::StatsCon
319319 return names;
320320}
321321
322- void HeapRawStatDataAllocator::free (RawStatData& data) {
322+ // TODO(jmarantz): move this below HeapStatDataAllocator::alloc.
323+ void HeapStatDataAllocator::free (HeapStatData& data) {
323324 ASSERT (data.ref_count_ > 0 );
324325 if (--data.ref_count_ > 0 ) {
325326 return ;
326327 }
327328
328- size_t key_removed;
329329 {
330330 Thread::LockGuard lock (mutex_);
331- key_removed = stats_.erase (&data);
331+ size_t key_removed = stats_.erase (&data);
332+ ASSERT (key_removed == 1 );
332333 }
333334
334- ASSERT (key_removed == 1 );
335- ::free (&data);
335+ delete &data;
336336}
337337
338- void RawStatData::initialize (absl::string_view key, uint64_t xfer_size ) {
338+ void RawStatData::initialize (absl::string_view key, const StatsOptions& stats_options ) {
339339 ASSERT (!initialized ());
340+ ASSERT (key.size () <= stats_options.maxNameLength ());
340341 ref_count_ = 1 ;
341- memcpy (name_, key.data (), xfer_size);
342- name_[xfer_size] = ' \0 ' ;
343- }
344-
345- void RawStatData::checkAndInit (absl::string_view key, uint64_t num_bytes_allocated) {
346- uint64_t xfer_size = key.size ();
347- ASSERT (structSize (xfer_size) <= num_bytes_allocated);
348-
349- initialize (key, xfer_size);
350- }
351-
352- void RawStatData::truncateAndInit (absl::string_view key, const StatsOptions& stats_options) {
353- if (key.size () > stats_options.maxNameLength ()) {
354- ENVOY_LOG_MISC (
355- warn,
356- " Statistic '{}' is too long with {} characters, it will be truncated to {} characters" , key,
357- key.size (), stats_options.maxNameLength ());
358- }
359-
360- // key is not necessarily nul-terminated, but we want to make sure name_ is.
361- uint64_t xfer_size = std::min (stats_options.maxNameLength (), key.size ());
362- initialize (key, xfer_size);
342+ memcpy (name_, key.data (), key.size ());
343+ name_[key.size ()] = ' \0 ' ;
363344}
364345
365346HistogramStatisticsImpl::HistogramStatisticsImpl (const histogram_t * histogram_ptr)
@@ -420,26 +401,32 @@ void SourceImpl::clearCache() {
420401 histograms_.reset ();
421402}
422403
423- CounterSharedPtr RawStatDataAllocator::makeCounter (const std::string& name,
424- std::string&& tag_extracted_name,
425- std::vector<Tag>&& tags) {
426- RawStatData* data = alloc (name);
404+ template <class StatData >
405+ CounterSharedPtr StatDataAllocatorImpl<StatData>::makeCounter(absl::string_view name,
406+ std::string&& tag_extracted_name,
407+ std::vector<Tag>&& tags) {
408+ StatData* data = alloc (name);
427409 if (data == nullptr ) {
428410 return nullptr ;
429411 }
430- return std::make_shared<CounterImpl>(*data, *this , std::move (tag_extracted_name),
431- std::move (tags));
412+ return std::make_shared<CounterImpl<StatData> >(*data, *this , std::move (tag_extracted_name),
413+ std::move (tags));
432414}
433415
434- GaugeSharedPtr RawStatDataAllocator::makeGauge (const std::string& name,
435- std::string&& tag_extracted_name,
436- std::vector<Tag>&& tags) {
437- RawStatData* data = alloc (name);
416+ template <class StatData >
417+ GaugeSharedPtr StatDataAllocatorImpl<StatData>::makeGauge(absl::string_view name,
418+ std::string&& tag_extracted_name,
419+ std::vector<Tag>&& tags) {
420+ StatData* data = alloc (name);
438421 if (data == nullptr ) {
439422 return nullptr ;
440423 }
441- return std::make_shared<GaugeImpl>(*data, *this , std::move (tag_extracted_name), std::move (tags));
424+ return std::make_shared<GaugeImpl<StatData>>(*data, *this , std::move (tag_extracted_name),
425+ std::move (tags));
442426}
443427
428+ template class StatDataAllocatorImpl <HeapStatData>;
429+ template class StatDataAllocatorImpl <RawStatData>;
430+
444431} // namespace Stats
445432} // namespace Envoy
0 commit comments