Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 1860e7a

Browse files
author
Ian Sturdy
authored
Add delta aggregation as an internal interface. (#117)
1 parent 51c296f commit 1860e7a

9 files changed

Lines changed: 103 additions & 5 deletions

File tree

opencensus/stats/internal/aggregation_window.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ std::string AggregationWindow::DebugString() const {
2323
switch (type_) {
2424
case Type::kCumulative:
2525
return "Cumulative";
26+
case Type::kDelta:
27+
return "Delta";
2628
case Type::kInterval:
2729
return absl::StrCat("Interval (", absl::ToDoubleSeconds(duration_),
2830
"s window)");

opencensus/stats/internal/aggregation_window.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ class AggregationWindow final {
3232
return AggregationWindow(Type::kCumulative, absl::InfiniteDuration());
3333
}
3434

35+
// Delta aggregation accumulates data until it is requested and then resets
36+
// it, so that each recorded value appears in exactly one delta.
37+
static AggregationWindow Delta() {
38+
return AggregationWindow(Type::kDelta, absl::InfiniteDuration());
39+
}
40+
3541
// Interval aggregation keeps a rolling total of usage over the previous
3642
// 'interval' of time.
3743
static AggregationWindow Interval(absl::Duration interval) {
@@ -40,6 +46,7 @@ class AggregationWindow final {
4046

4147
enum class Type {
4248
kCumulative,
49+
kDelta,
4350
kInterval,
4451
};
4552

opencensus/stats/internal/debug_string_test.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ TEST(DebugStringTest, Aggregation) {
3737

3838
TEST(DebugStringTest, AggregationWindow) {
3939
EXPECT_NE("", AggregationWindow::Cumulative().DebugString());
40+
EXPECT_NE("", AggregationWindow::Delta().DebugString());
4041
EXPECT_NE("", AggregationWindow::Interval(absl::Minutes(1)).DebugString());
4142
}
4243

opencensus/stats/internal/stats_manager.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#include "opencensus/stats/internal/stats_manager.h"
1616

1717
#include <iostream>
18+
#include <memory>
1819

1920
#include "absl/base/macros.h"
21+
#include "absl/memory/memory.h"
2022
#include "absl/time/time.h"
2123

2224
namespace opencensus {
@@ -73,12 +75,15 @@ void StatsManager::ViewInformation::Record(
7375
data_.Add(value, tag_values, now);
7476
}
7577

76-
ViewDataImpl StatsManager::ViewInformation::GetData() const {
78+
std::unique_ptr<ViewDataImpl> StatsManager::ViewInformation::GetData() {
7779
absl::ReaderMutexLock l(mu_);
7880
if (data_.type() == ViewDataImpl::Type::kStatsObject) {
79-
return ViewDataImpl(data_, absl::Now());
81+
return absl::make_unique<ViewDataImpl>(data_, absl::Now());
82+
} else if (descriptor_.aggregation_window_.type() ==
83+
AggregationWindow::Type::kDelta) {
84+
return data_.GetDeltaAndReset(absl::Now());
8085
} else {
81-
return data_;
86+
return absl::make_unique<ViewDataImpl>(data_);
8287
}
8388
}
8489

opencensus/stats/internal/stats_manager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class StatsManager final {
6161
absl::Time now);
6262

6363
// Retrieves a copy of the data.
64-
ViewDataImpl GetData() const LOCKS_EXCLUDED(*mu_);
64+
std::unique_ptr<ViewDataImpl> GetData() LOCKS_EXCLUDED(*mu_);
6565

6666
const ViewDescriptor& view_descriptor() const { return descriptor_; }
6767

opencensus/stats/internal/stats_manager_test.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,37 @@ TEST_F(StatsManagerTest, Distribution) {
136136
::testing::ElementsAre(1, 0));
137137
}
138138

139+
TEST_F(StatsManagerTest, Delta) {
140+
ViewDescriptor view_descriptor = ViewDescriptor()
141+
.set_measure(kFirstMeasureId)
142+
.set_name("delta")
143+
.set_aggregation(Aggregation::Count())
144+
.add_column(key1_)
145+
.add_column(key2_);
146+
SetAggregationWindow(AggregationWindow::Delta(), &view_descriptor);
147+
View view(view_descriptor);
148+
ASSERT_EQ(ViewData::Type::kInt64, view.GetData().type());
149+
EXPECT_TRUE(view.GetData().int_data().empty());
150+
// Stats under a different measure should be ignored.
151+
Record({{SecondMeasure(), 1}}, {});
152+
EXPECT_TRUE(view.GetData().int_data().empty());
153+
154+
Record({{FirstMeasure(), 2.0}}, {});
155+
Record({{FirstMeasure(), 3.0}}, {});
156+
Record({{FirstMeasure(), 4.0}},
157+
{{key1_, "value1"}, {key2_, "value2"}, {key3_, "value3"}});
158+
EXPECT_THAT(
159+
view.GetData().int_data(),
160+
::testing::UnorderedElementsAre(
161+
::testing::Pair(::testing::ElementsAre("", ""), 2),
162+
::testing::Pair(::testing::ElementsAre("value1", "value2"), 1)));
163+
164+
Record({{FirstMeasure(), 4.0}}, {{key1_, "new_value"}});
165+
EXPECT_THAT(view.GetData().int_data(),
166+
::testing::UnorderedElementsAre(
167+
::testing::Pair(::testing::ElementsAre("new_value", ""), 1)));
168+
}
169+
139170
// TODO: Test window expiration if we add a simulated clock.
140171
TEST_F(StatsManagerTest, IntervalCount) {
141172
ViewDescriptor view_descriptor = ViewDescriptor()

opencensus/stats/internal/view.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "opencensus/stats/view.h"
1616

1717
#include <iostream>
18+
#include <utility>
1819

1920
#include "absl/base/macros.h"
2021
#include "absl/memory/memory.h"
@@ -43,7 +44,7 @@ const ViewData View::GetData() {
4344
ABSL_ASSERT(0);
4445
return ViewData(absl::make_unique<ViewDataImpl>(absl::Now(), descriptor_));
4546
}
46-
return ViewData((absl::make_unique<ViewDataImpl>(handle_->GetData())));
47+
return ViewData(handle_->GetData());
4748
}
4849

4950
} // namespace stats

opencensus/stats/internal/view_data_impl.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
#include <cstdint>
1818
#include <iostream>
19+
#include <memory>
1920

21+
#include "absl/memory/memory.h"
2022
#include "opencensus/stats/distribution.h"
2123

2224
namespace opencensus {
@@ -26,6 +28,7 @@ ViewDataImpl::Type ViewDataImpl::TypeForDescriptor(
2628
const ViewDescriptor& descriptor) {
2729
switch (descriptor.aggregation_window_.type()) {
2830
case AggregationWindow::Type::kCumulative:
31+
case AggregationWindow::Type::kDelta:
2932
switch (descriptor.aggregation().type()) {
3033
case Aggregation::Type::kSum:
3134
return ViewDataImpl::Type::kDouble;
@@ -123,6 +126,11 @@ ViewDataImpl::~ViewDataImpl() {
123126
}
124127
}
125128

129+
std::unique_ptr<ViewDataImpl> ViewDataImpl::GetDeltaAndReset(absl::Time now) {
130+
// Need to use wrap_unique because this is a private constructor.
131+
return absl::WrapUnique(new ViewDataImpl(this, now));
132+
}
133+
126134
ViewDataImpl::ViewDataImpl(const ViewDataImpl& other)
127135
: aggregation_(other.aggregation_),
128136
aggregation_window_(other.aggregation_window_),
@@ -201,5 +209,38 @@ void ViewDataImpl::Add(double value, const std::vector<std::string>& tag_values,
201209
}
202210
}
203211

212+
ViewDataImpl::ViewDataImpl(ViewDataImpl* source, absl::Time now)
213+
: aggregation_(source->aggregation_),
214+
aggregation_window_(source->aggregation_window_),
215+
type_(source->type_),
216+
start_time_(source->start_time_),
217+
end_time_(now) {
218+
switch (type_) {
219+
case Type::kDouble: {
220+
new (&double_data_) DataMap<double>();
221+
double_data_.swap(source->double_data_);
222+
break;
223+
}
224+
case Type::kInt64: {
225+
new (&int_data_) DataMap<int64_t>();
226+
int_data_.swap(source->int_data_);
227+
break;
228+
}
229+
case Type::kDistribution: {
230+
new (&distribution_data_) DataMap<Distribution>();
231+
distribution_data_.swap(source->distribution_data_);
232+
break;
233+
}
234+
case Type::kStatsObject: {
235+
std::cerr << "GetDeltaAndReset should not be called on ViewDataImpl for "
236+
"interval stats.";
237+
ABSL_ASSERT(0);
238+
break;
239+
}
240+
}
241+
source->start_time_ = now;
242+
source->end_time_ = now;
243+
}
244+
204245
} // namespace stats
205246
} // namespace opencensus

opencensus/stats/internal/view_data_impl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef OPENCENSUS_STATS_INTERNAL_VIEW_DATA_IMPL_H_
1616
#define OPENCENSUS_STATS_INTERNAL_VIEW_DATA_IMPL_H_
1717

18+
#include <memory>
1819
#include <string>
1920
#include <unordered_map>
2021
#include <vector>
@@ -62,6 +63,10 @@ class ViewDataImpl {
6263
ViewDataImpl(const ViewDataImpl& other);
6364
~ViewDataImpl();
6465

66+
// Returns a copy of the present state of the object and resets data() and
67+
// start_time().
68+
std::unique_ptr<ViewDataImpl> GetDeltaAndReset(absl::Time now);
69+
6570
const Aggregation& aggregation() const { return aggregation_; }
6671
const AggregationWindow& aggregation_window() const {
6772
return aggregation_window_;
@@ -108,6 +113,11 @@ class ViewDataImpl {
108113
absl::Time now);
109114

110115
private:
116+
// Implements GetDeltaAndReset(), copying aggregation_ and swapping data_ and
117+
// start/end times. This is private so that it can be given a more descriptive
118+
// name in the public API.
119+
ViewDataImpl(ViewDataImpl* source, absl::Time now);
120+
111121
Type TypeForDescriptor(const ViewDescriptor& descriptor);
112122

113123
const Aggregation aggregation_;

0 commit comments

Comments
 (0)