sample_vector_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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
  3. // found in the LICENSE file.
  4. #include "base/metrics/sample_vector.h"
  5. #include <limits.h>
  6. #include <stddef.h>
  7. #include <atomic>
  8. #include <memory>
  9. #include <vector>
  10. #include "base/metrics/bucket_ranges.h"
  11. #include "base/metrics/histogram.h"
  12. #include "base/metrics/persistent_memory_allocator.h"
  13. #include "base/test/gtest_util.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. namespace base {
  16. // This framework class has "friend" access to the SampleVector for accessing
  17. // non-public methods and fields.
  18. class SampleVectorTest : public testing::Test {
  19. public:
  20. const HistogramBase::AtomicCount* GetSamplesCounts(
  21. const SampleVectorBase& samples) {
  22. return samples.counts();
  23. }
  24. };
  25. TEST_F(SampleVectorTest, Accumulate) {
  26. // Custom buckets: [1, 5) [5, 10)
  27. BucketRanges ranges(3);
  28. ranges.set_range(0, 1);
  29. ranges.set_range(1, 5);
  30. ranges.set_range(2, 10);
  31. SampleVector samples(1, &ranges);
  32. samples.Accumulate(1, 200);
  33. samples.Accumulate(2, -300);
  34. EXPECT_EQ(-100, samples.GetCountAtIndex(0));
  35. samples.Accumulate(5, 200);
  36. EXPECT_EQ(200, samples.GetCountAtIndex(1));
  37. EXPECT_EQ(600, samples.sum());
  38. EXPECT_EQ(100, samples.redundant_count());
  39. EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
  40. samples.Accumulate(5, -100);
  41. EXPECT_EQ(100, samples.GetCountAtIndex(1));
  42. EXPECT_EQ(100, samples.sum());
  43. EXPECT_EQ(0, samples.redundant_count());
  44. EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
  45. }
  46. TEST_F(SampleVectorTest, Accumulate_LargeValuesDontOverflow) {
  47. // Custom buckets: [1, 250000000) [250000000, 500000000)
  48. BucketRanges ranges(3);
  49. ranges.set_range(0, 1);
  50. ranges.set_range(1, 250000000);
  51. ranges.set_range(2, 500000000);
  52. SampleVector samples(1, &ranges);
  53. samples.Accumulate(240000000, 200);
  54. samples.Accumulate(249999999, -300);
  55. EXPECT_EQ(-100, samples.GetCountAtIndex(0));
  56. samples.Accumulate(250000000, 200);
  57. EXPECT_EQ(200, samples.GetCountAtIndex(1));
  58. EXPECT_EQ(23000000300LL, samples.sum());
  59. EXPECT_EQ(100, samples.redundant_count());
  60. EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
  61. samples.Accumulate(250000000, -100);
  62. EXPECT_EQ(100, samples.GetCountAtIndex(1));
  63. EXPECT_EQ(-1999999700LL, samples.sum());
  64. EXPECT_EQ(0, samples.redundant_count());
  65. EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
  66. }
  67. TEST_F(SampleVectorTest, AddSubtract) {
  68. // Custom buckets: [0, 1) [1, 2) [2, 3) [3, INT_MAX)
  69. BucketRanges ranges(5);
  70. ranges.set_range(0, 0);
  71. ranges.set_range(1, 1);
  72. ranges.set_range(2, 2);
  73. ranges.set_range(3, 3);
  74. ranges.set_range(4, INT_MAX);
  75. SampleVector samples1(1, &ranges);
  76. samples1.Accumulate(0, 100);
  77. samples1.Accumulate(2, 100);
  78. samples1.Accumulate(4, 100);
  79. EXPECT_EQ(600, samples1.sum());
  80. EXPECT_EQ(300, samples1.TotalCount());
  81. EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
  82. SampleVector samples2(2, &ranges);
  83. samples2.Accumulate(1, 200);
  84. samples2.Accumulate(2, 200);
  85. samples2.Accumulate(4, 200);
  86. EXPECT_EQ(1400, samples2.sum());
  87. EXPECT_EQ(600, samples2.TotalCount());
  88. EXPECT_EQ(samples2.redundant_count(), samples2.TotalCount());
  89. samples1.Add(samples2);
  90. EXPECT_EQ(100, samples1.GetCountAtIndex(0));
  91. EXPECT_EQ(200, samples1.GetCountAtIndex(1));
  92. EXPECT_EQ(300, samples1.GetCountAtIndex(2));
  93. EXPECT_EQ(300, samples1.GetCountAtIndex(3));
  94. EXPECT_EQ(2000, samples1.sum());
  95. EXPECT_EQ(900, samples1.TotalCount());
  96. EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
  97. samples1.Subtract(samples2);
  98. EXPECT_EQ(100, samples1.GetCountAtIndex(0));
  99. EXPECT_EQ(0, samples1.GetCountAtIndex(1));
  100. EXPECT_EQ(100, samples1.GetCountAtIndex(2));
  101. EXPECT_EQ(100, samples1.GetCountAtIndex(3));
  102. EXPECT_EQ(600, samples1.sum());
  103. EXPECT_EQ(300, samples1.TotalCount());
  104. EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
  105. }
  106. TEST_F(SampleVectorTest, BucketIndexDeath) {
  107. // 8 buckets with exponential layout:
  108. // [0, 1) [1, 2) [2, 4) [4, 8) [8, 16) [16, 32) [32, 64) [64, INT_MAX)
  109. BucketRanges ranges(9);
  110. Histogram::InitializeBucketRanges(1, 64, &ranges);
  111. SampleVector samples(1, &ranges);
  112. // Normal case
  113. samples.Accumulate(0, 1);
  114. samples.Accumulate(3, 2);
  115. samples.Accumulate(64, 3);
  116. EXPECT_EQ(1, samples.GetCount(0));
  117. EXPECT_EQ(2, samples.GetCount(2));
  118. EXPECT_EQ(3, samples.GetCount(65));
  119. // Extreme case.
  120. EXPECT_DEATH_IF_SUPPORTED(samples.Accumulate(INT_MIN, 100), "");
  121. EXPECT_DEATH_IF_SUPPORTED(samples.Accumulate(-1, 100), "");
  122. EXPECT_DEATH_IF_SUPPORTED(samples.Accumulate(INT_MAX, 100), "");
  123. // Custom buckets: [1, 5) [5, 10)
  124. // Note, this is not a valid BucketRanges for Histogram because it does not
  125. // have overflow buckets.
  126. BucketRanges ranges2(3);
  127. ranges2.set_range(0, 1);
  128. ranges2.set_range(1, 5);
  129. ranges2.set_range(2, 10);
  130. SampleVector samples2(2, &ranges2);
  131. // Normal case.
  132. samples2.Accumulate(1, 1);
  133. samples2.Accumulate(4, 1);
  134. samples2.Accumulate(5, 2);
  135. samples2.Accumulate(9, 2);
  136. EXPECT_EQ(2, samples2.GetCount(1));
  137. EXPECT_EQ(4, samples2.GetCount(5));
  138. // Extreme case.
  139. EXPECT_DEATH_IF_SUPPORTED(samples2.Accumulate(0, 100), "");
  140. EXPECT_DEATH_IF_SUPPORTED(samples2.Accumulate(10, 100), "");
  141. }
  142. TEST_F(SampleVectorTest, AddSubtractBucketNotMatchDeath) {
  143. // Custom buckets 1: [1, 3) [3, 5)
  144. BucketRanges ranges1(3);
  145. ranges1.set_range(0, 1);
  146. ranges1.set_range(1, 3);
  147. ranges1.set_range(2, 5);
  148. SampleVector samples1(1, &ranges1);
  149. // Custom buckets 2: [0, 1) [1, 3) [3, 6) [6, 7)
  150. BucketRanges ranges2(5);
  151. ranges2.set_range(0, 0);
  152. ranges2.set_range(1, 1);
  153. ranges2.set_range(2, 3);
  154. ranges2.set_range(3, 6);
  155. ranges2.set_range(4, 7);
  156. SampleVector samples2(2, &ranges2);
  157. samples2.Accumulate(1, 100);
  158. samples1.Add(samples2);
  159. EXPECT_EQ(100, samples1.GetCountAtIndex(0));
  160. // Extra bucket in the beginning. These should CHECK in GetBucketIndex.
  161. samples2.Accumulate(0, 100);
  162. EXPECT_DEATH_IF_SUPPORTED(samples1.Add(samples2), "");
  163. EXPECT_DEATH_IF_SUPPORTED(samples1.Subtract(samples2), "");
  164. // Extra bucket in the end. These should cause AddSubtractImpl to fail, and
  165. // Add to DCHECK as a result.
  166. samples2.Accumulate(0, -100);
  167. samples2.Accumulate(6, 100);
  168. EXPECT_DCHECK_DEATH(samples1.Add(samples2));
  169. EXPECT_DCHECK_DEATH(samples1.Subtract(samples2));
  170. // Bucket not match: [3, 5) VS [3, 6). These should cause AddSubtractImpl to
  171. // DCHECK.
  172. samples2.Accumulate(6, -100);
  173. samples2.Accumulate(3, 100);
  174. EXPECT_DCHECK_DEATH(samples1.Add(samples2));
  175. EXPECT_DCHECK_DEATH(samples1.Subtract(samples2));
  176. }
  177. TEST_F(SampleVectorTest, Iterate) {
  178. BucketRanges ranges(5);
  179. ranges.set_range(0, 0);
  180. ranges.set_range(1, 1);
  181. ranges.set_range(2, 2);
  182. ranges.set_range(3, 3);
  183. ranges.set_range(4, 4);
  184. std::vector<HistogramBase::Count> counts(3);
  185. counts[0] = 1;
  186. counts[1] = 0; // Iterator will bypass this empty bucket.
  187. counts[2] = 2;
  188. // BucketRanges can have larger size than counts.
  189. SampleVectorIterator it(&counts, &ranges);
  190. size_t index;
  191. HistogramBase::Sample min;
  192. int64_t max;
  193. HistogramBase::Count count;
  194. it.Get(&min, &max, &count);
  195. EXPECT_EQ(0, min);
  196. EXPECT_EQ(1, max);
  197. EXPECT_EQ(1, count);
  198. EXPECT_TRUE(it.GetBucketIndex(&index));
  199. EXPECT_EQ(0u, index);
  200. it.Next();
  201. it.Get(&min, &max, &count);
  202. EXPECT_EQ(2, min);
  203. EXPECT_EQ(3, max);
  204. EXPECT_EQ(2, count);
  205. EXPECT_TRUE(it.GetBucketIndex(&index));
  206. EXPECT_EQ(2u, index);
  207. it.Next();
  208. EXPECT_TRUE(it.Done());
  209. // Create iterator from SampleVector.
  210. SampleVector samples(1, &ranges);
  211. samples.Accumulate(0, 0);
  212. samples.Accumulate(1, 1);
  213. samples.Accumulate(2, 2);
  214. samples.Accumulate(3, 3);
  215. std::unique_ptr<SampleCountIterator> it2 = samples.Iterator();
  216. int i;
  217. for (i = 1; !it2->Done(); i++, it2->Next()) {
  218. it2->Get(&min, &max, &count);
  219. EXPECT_EQ(i, min);
  220. EXPECT_EQ(i + 1, max);
  221. EXPECT_EQ(i, count);
  222. EXPECT_TRUE(it2->GetBucketIndex(&index));
  223. EXPECT_EQ(static_cast<size_t>(i), index);
  224. }
  225. EXPECT_EQ(4, i);
  226. }
  227. TEST_F(SampleVectorTest, IterateDoneDeath) {
  228. BucketRanges ranges(5);
  229. ranges.set_range(0, 0);
  230. ranges.set_range(1, 1);
  231. ranges.set_range(2, 2);
  232. ranges.set_range(3, 3);
  233. ranges.set_range(4, INT_MAX);
  234. SampleVector samples(1, &ranges);
  235. std::unique_ptr<SampleCountIterator> it = samples.Iterator();
  236. EXPECT_TRUE(it->Done());
  237. HistogramBase::Sample min;
  238. int64_t max;
  239. HistogramBase::Count count;
  240. EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count));
  241. EXPECT_DCHECK_DEATH(it->Next());
  242. samples.Accumulate(2, 100);
  243. it = samples.Iterator();
  244. EXPECT_FALSE(it->Done());
  245. }
  246. TEST_F(SampleVectorTest, SingleSample) {
  247. // Custom buckets: [1, 5) [5, 10)
  248. BucketRanges ranges(3);
  249. ranges.set_range(0, 1);
  250. ranges.set_range(1, 5);
  251. ranges.set_range(2, 10);
  252. SampleVector samples(&ranges);
  253. // Ensure that a single value accumulates correctly.
  254. EXPECT_FALSE(GetSamplesCounts(samples));
  255. samples.Accumulate(3, 200);
  256. EXPECT_EQ(200, samples.GetCount(3));
  257. EXPECT_FALSE(GetSamplesCounts(samples));
  258. samples.Accumulate(3, 400);
  259. EXPECT_EQ(600, samples.GetCount(3));
  260. EXPECT_FALSE(GetSamplesCounts(samples));
  261. EXPECT_EQ(3 * 600, samples.sum());
  262. EXPECT_EQ(600, samples.TotalCount());
  263. EXPECT_EQ(600, samples.redundant_count());
  264. // Ensure that the iterator returns only one value.
  265. HistogramBase::Sample min;
  266. int64_t max;
  267. HistogramBase::Count count;
  268. std::unique_ptr<SampleCountIterator> it = samples.Iterator();
  269. ASSERT_FALSE(it->Done());
  270. it->Get(&min, &max, &count);
  271. EXPECT_EQ(1, min);
  272. EXPECT_EQ(5, max);
  273. EXPECT_EQ(600, count);
  274. it->Next();
  275. EXPECT_TRUE(it->Done());
  276. // Ensure that it can be merged to another single-sample vector.
  277. SampleVector samples_copy(&ranges);
  278. samples_copy.Add(samples);
  279. EXPECT_FALSE(GetSamplesCounts(samples_copy));
  280. EXPECT_EQ(3 * 600, samples_copy.sum());
  281. EXPECT_EQ(600, samples_copy.TotalCount());
  282. EXPECT_EQ(600, samples_copy.redundant_count());
  283. // A different value should cause creation of the counts array.
  284. samples.Accumulate(8, 100);
  285. EXPECT_TRUE(GetSamplesCounts(samples));
  286. EXPECT_EQ(600, samples.GetCount(3));
  287. EXPECT_EQ(100, samples.GetCount(8));
  288. EXPECT_EQ(3 * 600 + 8 * 100, samples.sum());
  289. EXPECT_EQ(600 + 100, samples.TotalCount());
  290. EXPECT_EQ(600 + 100, samples.redundant_count());
  291. // The iterator should now return both values.
  292. it = samples.Iterator();
  293. ASSERT_FALSE(it->Done());
  294. it->Get(&min, &max, &count);
  295. EXPECT_EQ(1, min);
  296. EXPECT_EQ(5, max);
  297. EXPECT_EQ(600, count);
  298. it->Next();
  299. ASSERT_FALSE(it->Done());
  300. it->Get(&min, &max, &count);
  301. EXPECT_EQ(5, min);
  302. EXPECT_EQ(10, max);
  303. EXPECT_EQ(100, count);
  304. it->Next();
  305. EXPECT_TRUE(it->Done());
  306. // Ensure that it can merged to a single-sample vector.
  307. samples_copy.Add(samples);
  308. EXPECT_TRUE(GetSamplesCounts(samples_copy));
  309. EXPECT_EQ(3 * 1200 + 8 * 100, samples_copy.sum());
  310. EXPECT_EQ(1200 + 100, samples_copy.TotalCount());
  311. EXPECT_EQ(1200 + 100, samples_copy.redundant_count());
  312. }
  313. TEST_F(SampleVectorTest, PersistentSampleVector) {
  314. LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");
  315. std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
  316. samples_ref.store(0, std::memory_order_relaxed);
  317. HistogramSamples::Metadata samples_meta;
  318. memset(&samples_meta, 0, sizeof(samples_meta));
  319. // Custom buckets: [1, 5) [5, 10)
  320. BucketRanges ranges(3);
  321. ranges.set_range(0, 1);
  322. ranges.set_range(1, 5);
  323. ranges.set_range(2, 10);
  324. // Persistent allocation.
  325. const size_t counts_bytes =
  326. sizeof(HistogramBase::AtomicCount) * ranges.bucket_count();
  327. const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 1,
  328. counts_bytes, false);
  329. PersistentSampleVector samples1(0, &ranges, &samples_meta, allocation);
  330. EXPECT_FALSE(GetSamplesCounts(samples1));
  331. samples1.Accumulate(3, 200);
  332. EXPECT_EQ(200, samples1.GetCount(3));
  333. EXPECT_FALSE(GetSamplesCounts(samples1));
  334. EXPECT_EQ(0, samples1.GetCount(8));
  335. EXPECT_FALSE(GetSamplesCounts(samples1));
  336. PersistentSampleVector samples2(0, &ranges, &samples_meta, allocation);
  337. EXPECT_EQ(200, samples2.GetCount(3));
  338. EXPECT_FALSE(GetSamplesCounts(samples2));
  339. HistogramBase::Sample min;
  340. int64_t max;
  341. HistogramBase::Count count;
  342. std::unique_ptr<SampleCountIterator> it = samples2.Iterator();
  343. ASSERT_FALSE(it->Done());
  344. it->Get(&min, &max, &count);
  345. EXPECT_EQ(1, min);
  346. EXPECT_EQ(5, max);
  347. EXPECT_EQ(200, count);
  348. it->Next();
  349. EXPECT_TRUE(it->Done());
  350. samples1.Accumulate(8, 100);
  351. EXPECT_TRUE(GetSamplesCounts(samples1));
  352. EXPECT_FALSE(GetSamplesCounts(samples2));
  353. EXPECT_EQ(200, samples2.GetCount(3));
  354. EXPECT_EQ(100, samples2.GetCount(8));
  355. EXPECT_TRUE(GetSamplesCounts(samples2));
  356. EXPECT_EQ(3 * 200 + 8 * 100, samples2.sum());
  357. EXPECT_EQ(300, samples2.TotalCount());
  358. EXPECT_EQ(300, samples2.redundant_count());
  359. it = samples2.Iterator();
  360. ASSERT_FALSE(it->Done());
  361. it->Get(&min, &max, &count);
  362. EXPECT_EQ(1, min);
  363. EXPECT_EQ(5, max);
  364. EXPECT_EQ(200, count);
  365. it->Next();
  366. ASSERT_FALSE(it->Done());
  367. it->Get(&min, &max, &count);
  368. EXPECT_EQ(5, min);
  369. EXPECT_EQ(10, max);
  370. EXPECT_EQ(100, count);
  371. it->Next();
  372. EXPECT_TRUE(it->Done());
  373. PersistentSampleVector samples3(0, &ranges, &samples_meta, allocation);
  374. EXPECT_TRUE(GetSamplesCounts(samples2));
  375. EXPECT_EQ(200, samples3.GetCount(3));
  376. EXPECT_EQ(100, samples3.GetCount(8));
  377. EXPECT_EQ(3 * 200 + 8 * 100, samples3.sum());
  378. EXPECT_EQ(300, samples3.TotalCount());
  379. EXPECT_EQ(300, samples3.redundant_count());
  380. it = samples3.Iterator();
  381. ASSERT_FALSE(it->Done());
  382. it->Get(&min, &max, &count);
  383. EXPECT_EQ(1, min);
  384. EXPECT_EQ(5, max);
  385. EXPECT_EQ(200, count);
  386. it->Next();
  387. ASSERT_FALSE(it->Done());
  388. it->Get(&min, &max, &count);
  389. EXPECT_EQ(5, min);
  390. EXPECT_EQ(10, max);
  391. EXPECT_EQ(100, count);
  392. it->Next();
  393. EXPECT_TRUE(it->Done());
  394. }
  395. TEST_F(SampleVectorTest, PersistentSampleVectorTestWithOutsideAlloc) {
  396. LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");
  397. std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
  398. samples_ref.store(0, std::memory_order_relaxed);
  399. HistogramSamples::Metadata samples_meta;
  400. memset(&samples_meta, 0, sizeof(samples_meta));
  401. // Custom buckets: [1, 5) [5, 10)
  402. BucketRanges ranges(3);
  403. ranges.set_range(0, 1);
  404. ranges.set_range(1, 5);
  405. ranges.set_range(2, 10);
  406. // Persistent allocation.
  407. const size_t counts_bytes =
  408. sizeof(HistogramBase::AtomicCount) * ranges.bucket_count();
  409. const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 1,
  410. counts_bytes, false);
  411. PersistentSampleVector samples1(0, &ranges, &samples_meta, allocation);
  412. EXPECT_FALSE(GetSamplesCounts(samples1));
  413. samples1.Accumulate(3, 200);
  414. EXPECT_EQ(200, samples1.GetCount(3));
  415. EXPECT_FALSE(GetSamplesCounts(samples1));
  416. // Because the delayed allocation can be shared with other objects (the
  417. // |offset| parameter allows concatinating multiple data blocks into the
  418. // same allocation), it's possible that the allocation gets realized from
  419. // the outside even though the data block being accessed is all zero.
  420. allocation.Get();
  421. EXPECT_EQ(200, samples1.GetCount(3));
  422. EXPECT_FALSE(GetSamplesCounts(samples1));
  423. HistogramBase::Sample min;
  424. int64_t max;
  425. HistogramBase::Count count;
  426. std::unique_ptr<SampleCountIterator> it = samples1.Iterator();
  427. ASSERT_FALSE(it->Done());
  428. it->Get(&min, &max, &count);
  429. EXPECT_EQ(1, min);
  430. EXPECT_EQ(5, max);
  431. EXPECT_EQ(200, count);
  432. it->Next();
  433. EXPECT_TRUE(it->Done());
  434. // A duplicate samples object should still see the single-sample entry even
  435. // when storage is available.
  436. PersistentSampleVector samples2(0, &ranges, &samples_meta, allocation);
  437. EXPECT_EQ(200, samples2.GetCount(3));
  438. // New accumulations, in both directions, of the existing value should work.
  439. samples1.Accumulate(3, 50);
  440. EXPECT_EQ(250, samples1.GetCount(3));
  441. EXPECT_EQ(250, samples2.GetCount(3));
  442. samples2.Accumulate(3, 50);
  443. EXPECT_EQ(300, samples1.GetCount(3));
  444. EXPECT_EQ(300, samples2.GetCount(3));
  445. it = samples1.Iterator();
  446. ASSERT_FALSE(it->Done());
  447. it->Get(&min, &max, &count);
  448. EXPECT_EQ(1, min);
  449. EXPECT_EQ(5, max);
  450. EXPECT_EQ(300, count);
  451. it->Next();
  452. EXPECT_TRUE(it->Done());
  453. samples1.Accumulate(8, 100);
  454. EXPECT_TRUE(GetSamplesCounts(samples1));
  455. EXPECT_EQ(300, samples1.GetCount(3));
  456. EXPECT_EQ(300, samples2.GetCount(3));
  457. EXPECT_EQ(100, samples1.GetCount(8));
  458. EXPECT_EQ(100, samples2.GetCount(8));
  459. samples2.Accumulate(8, 100);
  460. EXPECT_EQ(300, samples1.GetCount(3));
  461. EXPECT_EQ(300, samples2.GetCount(3));
  462. EXPECT_EQ(200, samples1.GetCount(8));
  463. EXPECT_EQ(200, samples2.GetCount(8));
  464. }
  465. // Tests GetPeakBucketSize() returns accurate max bucket size.
  466. TEST_F(SampleVectorTest, GetPeakBucketSize) {
  467. // Custom buckets: [1, 5) [5, 10) [10, 20)
  468. BucketRanges ranges(4);
  469. ranges.set_range(0, 1);
  470. ranges.set_range(1, 5);
  471. ranges.set_range(2, 10);
  472. ranges.set_range(3, 20);
  473. SampleVector samples(1, &ranges);
  474. samples.Accumulate(3, 1);
  475. samples.Accumulate(6, 2);
  476. samples.Accumulate(12, 3);
  477. EXPECT_EQ(3, samples.GetPeakBucketSize());
  478. }
  479. } // namespace base