public void TestLinearBucketValues() { var index = 0; // Note that using linear buckets should work "as expected" as long as the number of linear buckets // is lower than the resolution level determined by largestValueWithSingleUnitResolution // (2000 in this case). Above that count, some of the linear buckets can end up rounded up in size // (to the nearest local resolution unit level), which can result in a smaller number of buckets that // expected covering the range. // Iterate raw data using linear buckets of 100 msec each. foreach (var v in RawHistogram.LinearBucketValues(100000)) { var countAddedInThisBucket = v.CountAddedInThisIterationStep; if (index == 0) { Assert.AreEqual(10000, countAddedInThisBucket, "Raw Linear 100 msec bucket # 0 added a count of 10000"); } else if (index == 999) { Assert.AreEqual(1, countAddedInThisBucket, "Raw Linear 100 msec bucket # 999 added a count of 1"); } else { Assert.AreEqual(0, countAddedInThisBucket, "Raw Linear 100 msec bucket # " + index + " added a count of 0"); } index++; } Assert.AreEqual(1000, index); index = 0; long totalAddedCounts = 0; // Iterate data using linear buckets of 10 msec each. foreach (var v in LongHistogram.LinearBucketValues(10000)) { var countAddedInThisBucket = v.CountAddedInThisIterationStep; if (index == 0) { Assert.AreEqual(10001, countAddedInThisBucket, $"Linear 1 sec bucket # 0 [{v.ValueIteratedFrom}..{v.ValueIteratedTo}] added a count of 10001"); } // Because value resolution is low enough (3 digits) that multiple linear buckets will end up // residing in a single value-equivalent range, some linear buckets will have counts of 2 or // more, and some will have 0 (when the first bucket in the equivalent range was the one that // got the total count bump). // However, we can still verify the sum of counts added in all the buckets... totalAddedCounts += v.CountAddedInThisIterationStep; index++; } Assert.AreEqual(10000, index, "There should be 10000 linear buckets of size 10000 usec between 0 and 100 sec."); Assert.AreEqual(20000, totalAddedCounts, "Total added counts should be 20000"); index = 0; totalAddedCounts = 0; // Iterate data using linear buckets of 1 msec each. foreach (var v in LongHistogram.LinearBucketValues(1000)) { var countAddedInThisBucket = v.CountAddedInThisIterationStep; if (index == 0) { Assert.AreEqual(10000, countAddedInThisBucket, $"Linear 1 sec bucket # 0 [{v.ValueIteratedFrom}..{v.ValueIteratedTo}] added a count of 10000"); } // Because value resolution is low enough (3 digits) that multiple linear buckets will end up // residing in a single value-equivalent range, some linear buckets will have counts of 2 or // more, and some will have 0 (when the first bucket in the equivalent range was the one that // got the total count bump). // However, we can still verify the sum of counts added in all the buckets... totalAddedCounts += v.CountAddedInThisIterationStep; index++; } // You may ask "why 100007 and not 100000?" for the value below? The answer is that at this fine // a linear stepping resolution, the final populated sub-bucket (at 100 seconds with 3 decimal // point resolution) is larger than our liner stepping, and holds more than one linear 1 msec // step in it. // Since we only know we're done with linear iteration when the next iteration step will step // out of the last populated bucket, there is not way to tell if the iteration should stop at // 100000 or 100007 steps. The proper thing to do is to run to the end of the sub-bucket quanta... Assert.AreEqual(100007, index, "There should be 100007 linear buckets of size 1000 usec between 0 and 100 sec."); Assert.AreEqual(20000, totalAddedCounts, "Total added counts should be 20000"); }