From ad8e104a2fee25b0adaefe05286df0b84854ac90 Mon Sep 17 00:00:00 2001
From: Philip Pronin <philipp@fb.com>
Date: Sat, 1 Sep 2012 01:03:07 -0700
Subject: [PATCH] Histogram function to write tab-separated values.

Summary: Export histograms in a tab-separated format.

Test Plan: Used it.

Reviewed By: lucian@fb.com
---
 folly/Histogram-inl.h | 19 ++++++++++++++++---
 folly/Histogram.h     |  7 +++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/folly/Histogram-inl.h b/folly/Histogram-inl.h
index 97d2bffd..33ec2894 100644
--- a/folly/Histogram-inl.h
+++ b/folly/Histogram-inl.h
@@ -242,15 +242,28 @@ std::string Histogram<T>::debugString() const {
       ", bucketSize: ", buckets_.getBucketSize(),
       ", min: ", buckets_.getMin(), ", max: ", buckets_.getMax(), "\n");
 
-  for (unsigned int n = 0; n < buckets_.getNumBuckets(); ++n) {
-    folly::toAppend("  ", buckets_.getBucketMin(n), ": ",
-                    buckets_.getByIndex(n).count, "\n",
+  for (unsigned int i = 0; i < buckets_.getNumBuckets(); ++i) {
+    folly::toAppend("  ", buckets_.getBucketMin(i), ": ",
+                    buckets_.getByIndex(i).count, "\n",
                     &ret);
   }
 
   return ret;
 }
 
+template <typename T>
+void Histogram<T>::toTSV(std::ostream& out, bool skipEmptyBuckets) const {
+  for (unsigned int i = 0; i < buckets_.getNumBuckets(); ++i) {
+    // Do not output empty buckets in order to reduce data file size.
+    if (skipEmptyBuckets && getBucketByIndex(i).count == 0) {
+      continue;
+    }
+    const auto& bucket = getBucketByIndex(i);
+    out << getBucketMin(i) << '\t' << getBucketMax(i) << '\t'
+        << bucket.count << '\t' << bucket.sum << '\n';
+  }
+}
+
 } // folly
 
 #endif // FOLLY_HISTOGRAM_INL_H_
diff --git a/folly/Histogram.h b/folly/Histogram.h
index 30273994..fb721450 100644
--- a/folly/Histogram.h
+++ b/folly/Histogram.h
@@ -19,6 +19,7 @@
 
 #include <cstddef>
 #include <limits>
+#include <ostream>
 #include <string>
 #include <vector>
 #include <stdexcept>
@@ -367,6 +368,12 @@ class Histogram {
    */
   std::string debugString() const;
 
+  /*
+   * Write the histogram contents in tab-separated values (TSV) format.
+   * Format is "min max count sum".
+   */
+  void toTSV(std::ostream& out, bool skipEmptyBuckets = true) const;
+
  private:
   struct CountFromBucket {
     uint64_t operator()(const Bucket& bucket) const {
-- 
2.34.1