Move LogHistogram out of heapprofd_producer.

The file is getting very long.

Change-Id: I114d9aa17c443dd0c9908a3924bfa600d8669a3e
diff --git a/Android.bp b/Android.bp
index 68061d4..ea75b19 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6816,6 +6816,7 @@
     "src/profiling/memory/bookkeeping_dump.cc",
     "src/profiling/memory/heapprofd_producer.cc",
     "src/profiling/memory/java_hprof_producer.cc",
+    "src/profiling/memory/log_histogram.cc",
     "src/profiling/memory/system_property.cc",
     "src/profiling/memory/unwinding.cc",
   ],
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index c9d9715..c6c93b2 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -264,6 +264,8 @@
     "heapprofd_producer.h",
     "java_hprof_producer.cc",
     "java_hprof_producer.h",
+    "log_histogram.cc",
+    "log_histogram.h",
     "system_property.cc",
     "system_property.h",
     "unwinding.cc",
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index 22091f2..0b79ddf 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -90,15 +90,6 @@
   return false;
 }
 
-// Return largest n such that pow(2, n) < value.
-size_t Log2LessThan(uint64_t value) {
-  size_t i = 0;
-  while (value) {
-    i++;
-    value >>= 1;
-  }
-  return i;
-}
 
 bool IsFile(int fd, const char* fn) {
   struct stat fdstat;
@@ -171,30 +162,6 @@
   return true;
 }
 
-const uint64_t LogHistogram::kMaxBucket = 0;
-
-std::vector<std::pair<uint64_t, uint64_t>> LogHistogram::GetData() {
-  std::vector<std::pair<uint64_t, uint64_t>> data;
-  data.reserve(kBuckets);
-  for (size_t i = 0; i < kBuckets; ++i) {
-    if (i == kBuckets - 1)
-      data.emplace_back(kMaxBucket, values_[i]);
-    else
-      data.emplace_back(1 << i, values_[i]);
-  }
-  return data;
-}
-
-size_t LogHistogram::GetBucket(uint64_t value) {
-  if (value == 0)
-    return 0;
-
-  size_t hibit = Log2LessThan(value);
-  if (hibit >= kBuckets)
-    return kBuckets - 1;
-  return hibit;
-}
-
 // We create kUnwinderThreads unwinding threads. Bookkeeping is done on the main
 // thread.
 HeapprofdProducer::HeapprofdProducer(HeapprofdMode mode,
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index d913614..8d24315 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -40,6 +40,7 @@
 #include "src/profiling/common/profiler_guardrails.h"
 #include "src/profiling/memory/bookkeeping.h"
 #include "src/profiling/memory/bookkeeping_dump.h"
+#include "src/profiling/memory/log_histogram.h"
 #include "src/profiling/memory/system_property.h"
 #include "src/profiling/memory/unwinding.h"
 #include "src/profiling/memory/unwound_messages.h"
@@ -56,20 +57,6 @@
   std::string cmdline;
 };
 
-class LogHistogram {
- public:
-  static const uint64_t kMaxBucket;
-  static constexpr size_t kBuckets = 20;
-
-  void Add(uint64_t value) { values_[GetBucket(value)]++; }
-  std::vector<std::pair<uint64_t, uint64_t>> GetData();
-
- private:
-  size_t GetBucket(uint64_t value);
-
-  std::array<uint64_t, kBuckets> values_ = {};
-};
-
 // TODO(rsavitski): central daemon can do less work if it knows that the global
 // operating mode is fork-based, as it then will not be interacting with the
 // clients. This can be implemented as an additional mode here.
diff --git a/src/profiling/memory/log_histogram.cc b/src/profiling/memory/log_histogram.cc
new file mode 100644
index 0000000..84cc18c
--- /dev/null
+++ b/src/profiling/memory/log_histogram.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/memory/log_histogram.h"
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#include <utility>
+#include <vector>
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+// Return largest n such that pow(2, n) < value.
+size_t Log2LessThan(uint64_t value) {
+  size_t i = 0;
+  while (value) {
+    i++;
+    value >>= 1;
+  }
+  return i;
+}
+
+}  // namespace
+
+const uint64_t LogHistogram::kMaxBucket = 0;
+
+std::vector<std::pair<uint64_t, uint64_t>> LogHistogram::GetData() {
+  std::vector<std::pair<uint64_t, uint64_t>> data;
+  data.reserve(kBuckets);
+  for (size_t i = 0; i < kBuckets; ++i) {
+    if (i == kBuckets - 1)
+      data.emplace_back(kMaxBucket, values_[i]);
+    else
+      data.emplace_back(1 << i, values_[i]);
+  }
+  return data;
+}
+
+size_t LogHistogram::GetBucket(uint64_t value) {
+  if (value == 0)
+    return 0;
+
+  size_t hibit = Log2LessThan(value);
+  if (hibit >= kBuckets)
+    return kBuckets - 1;
+  return hibit;
+}
+
+}  // namespace profiling
+}  // namespace perfetto
diff --git a/src/profiling/memory/log_histogram.h b/src/profiling/memory/log_histogram.h
new file mode 100644
index 0000000..c542933
--- /dev/null
+++ b/src/profiling/memory/log_histogram.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_MEMORY_LOG_HISTOGRAM_H_
+#define SRC_PROFILING_MEMORY_LOG_HISTOGRAM_H_
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#include <array>
+#include <utility>
+#include <vector>
+
+namespace perfetto {
+namespace profiling {
+
+class LogHistogram {
+ public:
+  static const uint64_t kMaxBucket;
+  static constexpr size_t kBuckets = 20;
+
+  void Add(uint64_t value) { values_[GetBucket(value)]++; }
+  std::vector<std::pair<uint64_t, uint64_t>> GetData();
+
+ private:
+  size_t GetBucket(uint64_t value);
+
+  std::array<uint64_t, kBuckets> values_ = {};
+};
+
+}  // namespace profiling
+}  // namespace perfetto
+
+#endif  // SRC_PROFILING_MEMORY_LOG_HISTOGRAM_H_