Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: base/metrics/sample_vector_unittest.cc

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: addressed review comments by asvitkine Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/metrics/sample_vector.cc ('K') | « base/metrics/sample_vector.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/metrics/sample_vector.h" 5 #include "base/metrics/sample_vector.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <atomic>
10 #include <memory> 11 #include <memory>
11 #include <vector> 12 #include <vector>
12 13
13 #include "base/metrics/bucket_ranges.h" 14 #include "base/metrics/bucket_ranges.h"
14 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/metrics/persistent_memory_allocator.h"
15 #include "base/test/gtest_util.h" 17 #include "base/test/gtest_util.h"
16 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
17 19
18 namespace base { 20 namespace base {
19 namespace {
20 21
21 TEST(SampleVectorTest, AccumulateTest) { 22 // This framework class has "friend" access to the SampleVector for accessing
23 // non-public methods and fields.
24 class SampleVectorTest : public testing::Test {
25 public:
26 const HistogramBase::AtomicCount* GetSamplesCounts(
27 const SampleVectorBase& samples) {
28 return samples.counts();
29 }
30 };
31
32 TEST_F(SampleVectorTest, AccumulateTest) {
22 // Custom buckets: [1, 5) [5, 10) 33 // Custom buckets: [1, 5) [5, 10)
23 BucketRanges ranges(3); 34 BucketRanges ranges(3);
24 ranges.set_range(0, 1); 35 ranges.set_range(0, 1);
25 ranges.set_range(1, 5); 36 ranges.set_range(1, 5);
26 ranges.set_range(2, 10); 37 ranges.set_range(2, 10);
27 SampleVector samples(1, &ranges); 38 SampleVector samples(1, &ranges);
28 39
29 samples.Accumulate(1, 200); 40 samples.Accumulate(1, 200);
30 samples.Accumulate(2, -300); 41 samples.Accumulate(2, -300);
31 EXPECT_EQ(-100, samples.GetCountAtIndex(0)); 42 EXPECT_EQ(-100, samples.GetCountAtIndex(0));
32 43
33 samples.Accumulate(5, 200); 44 samples.Accumulate(5, 200);
34 EXPECT_EQ(200, samples.GetCountAtIndex(1)); 45 EXPECT_EQ(200, samples.GetCountAtIndex(1));
35 46
36 EXPECT_EQ(600, samples.sum()); 47 EXPECT_EQ(600, samples.sum());
37 EXPECT_EQ(100, samples.redundant_count()); 48 EXPECT_EQ(100, samples.redundant_count());
38 EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); 49 EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
39 50
40 samples.Accumulate(5, -100); 51 samples.Accumulate(5, -100);
41 EXPECT_EQ(100, samples.GetCountAtIndex(1)); 52 EXPECT_EQ(100, samples.GetCountAtIndex(1));
42 53
43 EXPECT_EQ(100, samples.sum()); 54 EXPECT_EQ(100, samples.sum());
44 EXPECT_EQ(0, samples.redundant_count()); 55 EXPECT_EQ(0, samples.redundant_count());
45 EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); 56 EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
46 } 57 }
47 58
48 TEST(SampleVectorTest, Accumulate_LargeValuesDontOverflow) { 59 TEST_F(SampleVectorTest, Accumulate_LargeValuesDontOverflow) {
49 // Custom buckets: [1, 250000000) [250000000, 500000000) 60 // Custom buckets: [1, 250000000) [250000000, 500000000)
50 BucketRanges ranges(3); 61 BucketRanges ranges(3);
51 ranges.set_range(0, 1); 62 ranges.set_range(0, 1);
52 ranges.set_range(1, 250000000); 63 ranges.set_range(1, 250000000);
53 ranges.set_range(2, 500000000); 64 ranges.set_range(2, 500000000);
54 SampleVector samples(1, &ranges); 65 SampleVector samples(1, &ranges);
55 66
56 samples.Accumulate(240000000, 200); 67 samples.Accumulate(240000000, 200);
57 samples.Accumulate(249999999, -300); 68 samples.Accumulate(249999999, -300);
58 EXPECT_EQ(-100, samples.GetCountAtIndex(0)); 69 EXPECT_EQ(-100, samples.GetCountAtIndex(0));
59 70
60 samples.Accumulate(250000000, 200); 71 samples.Accumulate(250000000, 200);
61 EXPECT_EQ(200, samples.GetCountAtIndex(1)); 72 EXPECT_EQ(200, samples.GetCountAtIndex(1));
62 73
63 EXPECT_EQ(23000000300LL, samples.sum()); 74 EXPECT_EQ(23000000300LL, samples.sum());
64 EXPECT_EQ(100, samples.redundant_count()); 75 EXPECT_EQ(100, samples.redundant_count());
65 EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); 76 EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
66 77
67 samples.Accumulate(250000000, -100); 78 samples.Accumulate(250000000, -100);
68 EXPECT_EQ(100, samples.GetCountAtIndex(1)); 79 EXPECT_EQ(100, samples.GetCountAtIndex(1));
69 80
70 EXPECT_EQ(-1999999700LL, samples.sum()); 81 EXPECT_EQ(-1999999700LL, samples.sum());
71 EXPECT_EQ(0, samples.redundant_count()); 82 EXPECT_EQ(0, samples.redundant_count());
72 EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); 83 EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
73 } 84 }
74 85
75 TEST(SampleVectorTest, AddSubtractTest) { 86 TEST_F(SampleVectorTest, AddSubtractTest) {
76 // Custom buckets: [0, 1) [1, 2) [2, 3) [3, INT_MAX) 87 // Custom buckets: [0, 1) [1, 2) [2, 3) [3, INT_MAX)
77 BucketRanges ranges(5); 88 BucketRanges ranges(5);
78 ranges.set_range(0, 0); 89 ranges.set_range(0, 0);
79 ranges.set_range(1, 1); 90 ranges.set_range(1, 1);
80 ranges.set_range(2, 2); 91 ranges.set_range(2, 2);
81 ranges.set_range(3, 3); 92 ranges.set_range(3, 3);
82 ranges.set_range(4, INT_MAX); 93 ranges.set_range(4, INT_MAX);
83 94
84 SampleVector samples1(1, &ranges); 95 SampleVector samples1(1, &ranges);
85 samples1.Accumulate(0, 100); 96 samples1.Accumulate(0, 100);
(...skipping 23 matching lines...) Expand all
109 samples1.Subtract(samples2); 120 samples1.Subtract(samples2);
110 EXPECT_EQ(100, samples1.GetCountAtIndex(0)); 121 EXPECT_EQ(100, samples1.GetCountAtIndex(0));
111 EXPECT_EQ(0, samples1.GetCountAtIndex(1)); 122 EXPECT_EQ(0, samples1.GetCountAtIndex(1));
112 EXPECT_EQ(100, samples1.GetCountAtIndex(2)); 123 EXPECT_EQ(100, samples1.GetCountAtIndex(2));
113 EXPECT_EQ(100, samples1.GetCountAtIndex(3)); 124 EXPECT_EQ(100, samples1.GetCountAtIndex(3));
114 EXPECT_EQ(600, samples1.sum()); 125 EXPECT_EQ(600, samples1.sum());
115 EXPECT_EQ(300, samples1.TotalCount()); 126 EXPECT_EQ(300, samples1.TotalCount());
116 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount()); 127 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
117 } 128 }
118 129
119 TEST(SampleVectorDeathTest, BucketIndexTest) { 130 TEST_F(SampleVectorTest, BucketIndexDeathTest) {
120 // 8 buckets with exponential layout: 131 // 8 buckets with exponential layout:
121 // [0, 1) [1, 2) [2, 4) [4, 8) [8, 16) [16, 32) [32, 64) [64, INT_MAX) 132 // [0, 1) [1, 2) [2, 4) [4, 8) [8, 16) [16, 32) [32, 64) [64, INT_MAX)
122 BucketRanges ranges(9); 133 BucketRanges ranges(9);
123 Histogram::InitializeBucketRanges(1, 64, &ranges); 134 Histogram::InitializeBucketRanges(1, 64, &ranges);
124 SampleVector samples(1, &ranges); 135 SampleVector samples(1, &ranges);
125 136
126 // Normal case 137 // Normal case
127 samples.Accumulate(0, 1); 138 samples.Accumulate(0, 1);
128 samples.Accumulate(3, 2); 139 samples.Accumulate(3, 2);
129 samples.Accumulate(64, 3); 140 samples.Accumulate(64, 3);
(...skipping 21 matching lines...) Expand all
151 samples2.Accumulate(5, 2); 162 samples2.Accumulate(5, 2);
152 samples2.Accumulate(9, 2); 163 samples2.Accumulate(9, 2);
153 EXPECT_EQ(2, samples2.GetCount(1)); 164 EXPECT_EQ(2, samples2.GetCount(1));
154 EXPECT_EQ(4, samples2.GetCount(5)); 165 EXPECT_EQ(4, samples2.GetCount(5));
155 166
156 // Extreme case. 167 // Extreme case.
157 EXPECT_DCHECK_DEATH(samples2.Accumulate(0, 100)); 168 EXPECT_DCHECK_DEATH(samples2.Accumulate(0, 100));
158 EXPECT_DCHECK_DEATH(samples2.Accumulate(10, 100)); 169 EXPECT_DCHECK_DEATH(samples2.Accumulate(10, 100));
159 } 170 }
160 171
161 TEST(SampleVectorDeathTest, AddSubtractBucketNotMatchTest) { 172 TEST_F(SampleVectorTest, AddSubtractBucketNotMatchDeathTest) {
162 // Custom buckets 1: [1, 3) [3, 5) 173 // Custom buckets 1: [1, 3) [3, 5)
163 BucketRanges ranges1(3); 174 BucketRanges ranges1(3);
164 ranges1.set_range(0, 1); 175 ranges1.set_range(0, 1);
165 ranges1.set_range(1, 3); 176 ranges1.set_range(1, 3);
166 ranges1.set_range(2, 5); 177 ranges1.set_range(2, 5);
167 SampleVector samples1(1, &ranges1); 178 SampleVector samples1(1, &ranges1);
168 179
169 // Custom buckets 2: [0, 1) [1, 3) [3, 6) [6, 7) 180 // Custom buckets 2: [0, 1) [1, 3) [3, 6) [6, 7)
170 BucketRanges ranges2(5); 181 BucketRanges ranges2(5);
171 ranges2.set_range(0, 0); 182 ranges2.set_range(0, 0);
(...skipping 18 matching lines...) Expand all
190 EXPECT_DCHECK_DEATH(samples1.Add(samples2)); 201 EXPECT_DCHECK_DEATH(samples1.Add(samples2));
191 EXPECT_DCHECK_DEATH(samples1.Subtract(samples2)); 202 EXPECT_DCHECK_DEATH(samples1.Subtract(samples2));
192 203
193 // Bucket not match: [3, 5) VS [3, 6) 204 // Bucket not match: [3, 5) VS [3, 6)
194 samples2.Accumulate(6, -100); 205 samples2.Accumulate(6, -100);
195 samples2.Accumulate(3, 100); 206 samples2.Accumulate(3, 100);
196 EXPECT_DCHECK_DEATH(samples1.Add(samples2)); 207 EXPECT_DCHECK_DEATH(samples1.Add(samples2));
197 EXPECT_DCHECK_DEATH(samples1.Subtract(samples2)); 208 EXPECT_DCHECK_DEATH(samples1.Subtract(samples2));
198 } 209 }
199 210
200 TEST(SampleVectorIteratorTest, IterateTest) { 211 TEST_F(SampleVectorTest, IterateTest) {
201 BucketRanges ranges(5); 212 BucketRanges ranges(5);
202 ranges.set_range(0, 0); 213 ranges.set_range(0, 0);
203 ranges.set_range(1, 1); 214 ranges.set_range(1, 1);
204 ranges.set_range(2, 2); 215 ranges.set_range(2, 2);
205 ranges.set_range(3, 3); 216 ranges.set_range(3, 3);
206 ranges.set_range(4, 4); 217 ranges.set_range(4, 4);
207 218
208 std::vector<HistogramBase::Count> counts(3); 219 std::vector<HistogramBase::Count> counts(3);
209 counts[0] = 1; 220 counts[0] = 1;
210 counts[1] = 0; // Iterator will bypass this empty bucket. 221 counts[1] = 0; // Iterator will bypass this empty bucket.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 EXPECT_EQ(i + 1, max); 261 EXPECT_EQ(i + 1, max);
251 EXPECT_EQ(i, count); 262 EXPECT_EQ(i, count);
252 263
253 size_t index; 264 size_t index;
254 EXPECT_TRUE(it2->GetBucketIndex(&index)); 265 EXPECT_TRUE(it2->GetBucketIndex(&index));
255 EXPECT_EQ(static_cast<size_t>(i), index); 266 EXPECT_EQ(static_cast<size_t>(i), index);
256 } 267 }
257 EXPECT_EQ(4, i); 268 EXPECT_EQ(4, i);
258 } 269 }
259 270
260 TEST(SampleVectorIteratorDeathTest, IterateDoneTest) { 271 TEST_F(SampleVectorTest, IterateDoneDeathTest) {
261 BucketRanges ranges(5); 272 BucketRanges ranges(5);
262 ranges.set_range(0, 0); 273 ranges.set_range(0, 0);
263 ranges.set_range(1, 1); 274 ranges.set_range(1, 1);
264 ranges.set_range(2, 2); 275 ranges.set_range(2, 2);
265 ranges.set_range(3, 3); 276 ranges.set_range(3, 3);
266 ranges.set_range(4, INT_MAX); 277 ranges.set_range(4, INT_MAX);
267 SampleVector samples(1, &ranges); 278 SampleVector samples(1, &ranges);
268 279
269 std::unique_ptr<SampleCountIterator> it = samples.Iterator(); 280 std::unique_ptr<SampleCountIterator> it = samples.Iterator();
270 281
271 EXPECT_TRUE(it->Done()); 282 EXPECT_TRUE(it->Done());
272 283
273 HistogramBase::Sample min; 284 HistogramBase::Sample min;
274 HistogramBase::Sample max; 285 HistogramBase::Sample max;
275 HistogramBase::Count count; 286 HistogramBase::Count count;
276 EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count)); 287 EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count));
277 288
278 EXPECT_DCHECK_DEATH(it->Next()); 289 EXPECT_DCHECK_DEATH(it->Next());
279 290
280 samples.Accumulate(2, 100); 291 samples.Accumulate(2, 100);
281 it = samples.Iterator(); 292 it = samples.Iterator();
282 EXPECT_FALSE(it->Done()); 293 EXPECT_FALSE(it->Done());
283 } 294 }
284 295
285 } // namespace 296 TEST_F(SampleVectorTest, SingleSampleTest) {
Alexei Svitkine (slow) 2017/04/20 22:11:34 Nit: I'd omit the word "Test" from all of these. I
bcwhite 2017/04/21 13:25:32 Done.
297 // Custom buckets: [1, 5) [5, 10)
298 BucketRanges ranges(3);
299 ranges.set_range(0, 1);
300 ranges.set_range(1, 5);
301 ranges.set_range(2, 10);
302 SampleVector samples(&ranges);
303
304 // Ensure that a single value accumulates correctly.
305 EXPECT_FALSE(GetSamplesCounts(samples));
306 samples.Accumulate(3, 200);
307 EXPECT_EQ(200, samples.GetCount(3));
308 EXPECT_FALSE(GetSamplesCounts(samples));
309 samples.Accumulate(3, 400);
310 EXPECT_EQ(600, samples.GetCount(3));
311 EXPECT_FALSE(GetSamplesCounts(samples));
312 EXPECT_EQ(3 * 600, samples.sum());
313 EXPECT_EQ(600, samples.TotalCount());
314 EXPECT_EQ(600, samples.redundant_count());
315
316 // Ensure that the iterator returns only one value.
317 HistogramBase::Sample min;
318 HistogramBase::Sample max;
319 HistogramBase::Count count;
320 std::unique_ptr<SampleCountIterator> it = samples.Iterator();
321 ASSERT_FALSE(it->Done());
322 it->Get(&min, &max, &count);
323 EXPECT_EQ(1, min);
324 EXPECT_EQ(5, max);
325 EXPECT_EQ(600, count);
326 it->Next();
327 EXPECT_TRUE(it->Done());
328
329 // Ensure that it can be merged to another single-sample vector.
330 SampleVector samples_copy(&ranges);
331 samples_copy.Add(samples);
332 EXPECT_FALSE(GetSamplesCounts(samples_copy));
333 EXPECT_EQ(3 * 600, samples_copy.sum());
334 EXPECT_EQ(600, samples_copy.TotalCount());
335 EXPECT_EQ(600, samples_copy.redundant_count());
336
337 // A different value should cause creation of the counts array.
338 samples.Accumulate(8, 100);
339 EXPECT_TRUE(GetSamplesCounts(samples));
340 EXPECT_EQ(600, samples.GetCount(3));
341 EXPECT_EQ(100, samples.GetCount(8));
342 EXPECT_EQ(3 * 600 + 8 * 100, samples.sum());
343 EXPECT_EQ(600 + 100, samples.TotalCount());
344 EXPECT_EQ(600 + 100, samples.redundant_count());
345
346 // The iterator should now return both values.
347 it = samples.Iterator();
348 ASSERT_FALSE(it->Done());
349 it->Get(&min, &max, &count);
350 EXPECT_EQ(1, min);
351 EXPECT_EQ(5, max);
352 EXPECT_EQ(600, count);
353 it->Next();
354 ASSERT_FALSE(it->Done());
355 it->Get(&min, &max, &count);
356 EXPECT_EQ(5, min);
357 EXPECT_EQ(10, max);
358 EXPECT_EQ(100, count);
359 it->Next();
360 EXPECT_TRUE(it->Done());
361
362 // Ensure that it can merged to a single-sample vector.
363 samples_copy.Add(samples);
364 EXPECT_TRUE(GetSamplesCounts(samples_copy));
365 EXPECT_EQ(3 * 1200 + 8 * 100, samples_copy.sum());
366 EXPECT_EQ(1200 + 100, samples_copy.TotalCount());
367 EXPECT_EQ(1200 + 100, samples_copy.redundant_count());
368 }
369
370 TEST_F(SampleVectorTest, PersistentSampleVectorTest) {
371 LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");
372 std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
373 samples_ref.store(0, std::memory_order_relaxed);
374 HistogramSamples::Metadata samples_meta;
375 memset(&samples_meta, 0, sizeof(samples_meta));
376
377 // Custom buckets: [1, 5) [5, 10)
378 BucketRanges ranges(3);
379 ranges.set_range(0, 1);
380 ranges.set_range(1, 5);
381 ranges.set_range(2, 10);
382
383 // Persistent allocation.
384 const size_t counts_bytes =
385 sizeof(HistogramBase::AtomicCount) * ranges.bucket_count();
386 const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 1,
387 counts_bytes);
388
389 PersistentSampleVector samples1(0, &ranges, &samples_meta, allocation);
390 EXPECT_FALSE(GetSamplesCounts(samples1));
391 samples1.Accumulate(3, 200);
392 EXPECT_EQ(200, samples1.GetCount(3));
393 EXPECT_FALSE(GetSamplesCounts(samples1));
394 EXPECT_EQ(0, samples1.GetCount(8));
395 EXPECT_FALSE(GetSamplesCounts(samples1));
396
397 PersistentSampleVector samples2(0, &ranges, &samples_meta, allocation);
398 EXPECT_EQ(200, samples2.GetCount(3));
399 EXPECT_FALSE(GetSamplesCounts(samples2));
400
401 HistogramBase::Sample min;
402 HistogramBase::Sample max;
403 HistogramBase::Count count;
404 std::unique_ptr<SampleCountIterator> it = samples2.Iterator();
405 ASSERT_FALSE(it->Done());
406 it->Get(&min, &max, &count);
407 EXPECT_EQ(1, min);
408 EXPECT_EQ(5, max);
409 EXPECT_EQ(200, count);
410 it->Next();
411 EXPECT_TRUE(it->Done());
412
413 samples1.Accumulate(8, 100);
414 EXPECT_TRUE(GetSamplesCounts(samples1));
415
416 EXPECT_FALSE(GetSamplesCounts(samples2));
417 EXPECT_EQ(200, samples2.GetCount(3));
418 EXPECT_EQ(100, samples2.GetCount(8));
419 EXPECT_TRUE(GetSamplesCounts(samples2));
420 EXPECT_EQ(3 * 200 + 8 * 100, samples2.sum());
421 EXPECT_EQ(300, samples2.TotalCount());
422 EXPECT_EQ(300, samples2.redundant_count());
423
424 it = samples2.Iterator();
425 ASSERT_FALSE(it->Done());
426 it->Get(&min, &max, &count);
427 EXPECT_EQ(1, min);
428 EXPECT_EQ(5, max);
429 EXPECT_EQ(200, count);
430 it->Next();
431 ASSERT_FALSE(it->Done());
432 it->Get(&min, &max, &count);
433 EXPECT_EQ(5, min);
434 EXPECT_EQ(10, max);
435 EXPECT_EQ(100, count);
436 it->Next();
437 EXPECT_TRUE(it->Done());
438
439 PersistentSampleVector samples3(0, &ranges, &samples_meta, allocation);
440 EXPECT_TRUE(GetSamplesCounts(samples2));
441 EXPECT_EQ(200, samples3.GetCount(3));
442 EXPECT_EQ(100, samples3.GetCount(8));
443 EXPECT_EQ(3 * 200 + 8 * 100, samples3.sum());
444 EXPECT_EQ(300, samples3.TotalCount());
445 EXPECT_EQ(300, samples3.redundant_count());
446
447 it = samples3.Iterator();
448 ASSERT_FALSE(it->Done());
449 it->Get(&min, &max, &count);
450 EXPECT_EQ(1, min);
451 EXPECT_EQ(5, max);
452 EXPECT_EQ(200, count);
453 it->Next();
454 ASSERT_FALSE(it->Done());
455 it->Get(&min, &max, &count);
456 EXPECT_EQ(5, min);
457 EXPECT_EQ(10, max);
458 EXPECT_EQ(100, count);
459 it->Next();
460 EXPECT_TRUE(it->Done());
461 }
462
463 TEST_F(SampleVectorTest, PersistentSampleVectorTestWithOutsideAlloc) {
464 LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");
465 std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
466 samples_ref.store(0, std::memory_order_relaxed);
467 HistogramSamples::Metadata samples_meta;
468 memset(&samples_meta, 0, sizeof(samples_meta));
469
470 // Custom buckets: [1, 5) [5, 10)
471 BucketRanges ranges(3);
472 ranges.set_range(0, 1);
473 ranges.set_range(1, 5);
474 ranges.set_range(2, 10);
475
476 // Persistent allocation.
477 const size_t counts_bytes =
478 sizeof(HistogramBase::AtomicCount) * ranges.bucket_count();
479 const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 1,
480 counts_bytes);
481
482 PersistentSampleVector samples1(0, &ranges, &samples_meta, allocation);
483 EXPECT_FALSE(GetSamplesCounts(samples1));
484 samples1.Accumulate(3, 200);
485 EXPECT_EQ(200, samples1.GetCount(3));
486 EXPECT_FALSE(GetSamplesCounts(samples1));
487
488 // Because the delayed allocation can be shared with other objects (the
489 // |offset| parameter allows concatinating multiple data blocks into the
490 // same allocation), it's possible that the allocation gets realized from
491 // the outside even though the data block being accessed is all zero.
492 allocation.Get();
493 EXPECT_EQ(200, samples1.GetCount(3));
494 EXPECT_FALSE(GetSamplesCounts(samples1));
495
496 HistogramBase::Sample min;
497 HistogramBase::Sample max;
498 HistogramBase::Count count;
499 std::unique_ptr<SampleCountIterator> it = samples1.Iterator();
500 ASSERT_FALSE(it->Done());
501 it->Get(&min, &max, &count);
502 EXPECT_EQ(1, min);
503 EXPECT_EQ(5, max);
504 EXPECT_EQ(200, count);
505 it->Next();
506 EXPECT_TRUE(it->Done());
507
508 // A duplicate samples object should still see the single-sample entry even
509 // when storage is available.
510 PersistentSampleVector samples2(0, &ranges, &samples_meta, allocation);
511 EXPECT_EQ(200, samples2.GetCount(3));
512
513 // New accumulations, in both directions, of the existing value should work.
514 samples1.Accumulate(3, 50);
515 EXPECT_EQ(250, samples1.GetCount(3));
516 EXPECT_EQ(250, samples2.GetCount(3));
517 samples2.Accumulate(3, 50);
518 EXPECT_EQ(300, samples1.GetCount(3));
519 EXPECT_EQ(300, samples2.GetCount(3));
520
521 it = samples1.Iterator();
522 ASSERT_FALSE(it->Done());
523 it->Get(&min, &max, &count);
524 EXPECT_EQ(1, min);
525 EXPECT_EQ(5, max);
526 EXPECT_EQ(300, count);
527 it->Next();
528 EXPECT_TRUE(it->Done());
529
530 samples1.Accumulate(8, 100);
531 EXPECT_TRUE(GetSamplesCounts(samples1));
532 EXPECT_EQ(300, samples1.GetCount(3));
533 EXPECT_EQ(300, samples2.GetCount(3));
534 EXPECT_EQ(100, samples1.GetCount(8));
535 EXPECT_EQ(100, samples2.GetCount(8));
536 samples2.Accumulate(8, 100);
537 EXPECT_EQ(300, samples1.GetCount(3));
538 EXPECT_EQ(300, samples2.GetCount(3));
539 EXPECT_EQ(200, samples1.GetCount(8));
540 EXPECT_EQ(200, samples2.GetCount(8));
541 }
542
286 } // namespace base 543 } // namespace base
OLDNEW
« base/metrics/sample_vector.cc ('K') | « base/metrics/sample_vector.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698