Add counters interface
authorNick Terrell <terrelln@fb.com>
Tue, 23 Jan 2018 04:58:50 +0000 (20:58 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Tue, 23 Jan 2018 05:23:48 +0000 (21:23 -0800)
Summary: Adds an open source counters interface.

Reviewed By: yfeldblum

Differential Revision: D6609118

fbshipit-source-id: cc326443339b88acdd11e4184eb0c82d786732c2

folly/Makefile.am
folly/compression/Counters.cpp [new file with mode: 0644]
folly/compression/Counters.h [new file with mode: 0644]
folly/compression/test/CountersTest.cpp [new file with mode: 0644]

index 66bb93e76b9657f08f324ea88a54b4cd31d4afc7..3eb105ece370984df77b3cd49d17e4321ae5030d 100644 (file)
@@ -48,6 +48,7 @@ nobase_follyinclude_HEADERS = \
        CpuId.h \
        CPortability.h \
        compression/Compression.h \
+       compression/Counters.h \
        compression/Utils.h \
        compression/Zlib.h \
        concurrency/CacheLocality.h \
@@ -513,6 +514,7 @@ libfollybase_la_SOURCES = \
 libfolly_la_SOURCES = \
        ClockGettimeWrappers.cpp \
        compression/Compression.cpp \
+       compression/Counters.cpp \
        compression/Zlib.cpp \
        concurrency/CacheLocality.cpp \
        detail/AtFork.cpp \
diff --git a/folly/compression/Counters.cpp b/folly/compression/Counters.cpp
new file mode 100644 (file)
index 0000000..747c8bb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018-present Facebook, Inc.
+ *
+ * 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 <folly/compression/Counters.h>
+#include <folly/folly-config.h>
+
+namespace folly {
+#if FOLLY_HAVE_WEAK_SYMBOLS
+#define FOLLY_WEAK_SYMBOL __attribute__((__weak__))
+#else
+#define FOLLY_WEAK_SYMBOL
+#endif
+
+folly::Function<void(double)> FOLLY_WEAK_SYMBOL makeCompressionCounterHandler(
+    folly::io::CodecType,
+    folly::StringPiece,
+    folly::Optional<int>,
+    CompressionCounterKey,
+    CompressionCounterType) {
+  return {};
+}
+} // namespace folly
diff --git a/folly/compression/Counters.h b/folly/compression/Counters.h
new file mode 100644 (file)
index 0000000..26c6740
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2018-present Facebook, Inc.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <folly/Function.h>
+#include <folly/Optional.h>
+#include <folly/Range.h>
+
+namespace folly {
+namespace io {
+enum class CodecType;
+} // namespace io
+
+enum class CompressionCounterKey {
+  BYTES_BEFORE_COMPRESSION = 0,
+  BYTES_AFTER_COMPRESSION = 1,
+  BYTES_BEFORE_DECOMPRESSION = 2,
+  BYTES_AFTER_DECOMPRESSION = 3,
+};
+
+enum class CompressionCounterType {
+  AVG = 0,
+  SUM = 1,
+};
+
+/**
+ * This functions is an extension point when FOLLY_HAVE_WEAK_SYMBOLS is true.
+ * There is a default no-op implementation provided which can be overrided by
+ * linking in a library which provides its own definition.
+ *
+ * @param codecType   The type of the codec for this counter.
+ * @param codecName   The name of the codec for this counter. If the codecName
+ *                    is empty it should be defaulted using the codecType.
+ * @param level       Optionally the level used to construct the codec.
+ * @param key         The key of the counter.
+ * @param counterType The type of the counter.
+ * @returns           A function to increment the counter for the given key and
+ *                    type. It may be an empty folly::Function.
+ */
+folly::Function<void(double)> makeCompressionCounterHandler(
+    folly::io::CodecType codecType,
+    folly::StringPiece codecName,
+    folly::Optional<int> level,
+    CompressionCounterKey key,
+    CompressionCounterType counterType);
+
+namespace detail {
+
+/// Wrapper around the makeCompressionCounterHandler() extension point.
+class CompressionCounter {
+ public:
+  CompressionCounter() {}
+  CompressionCounter(
+      folly::io::CodecType codecType,
+      folly::StringPiece codecName,
+      folly::Optional<int> level,
+      CompressionCounterKey key,
+      CompressionCounterType counterType) {
+    increment_ = makeCompressionCounterHandler(
+        codecType, codecName, std::move(level), key, counterType);
+  }
+
+  void operator+=(double sum) {
+    if (increment_) {
+      increment_(sum);
+    }
+  }
+
+  void operator++() {
+    *this += 1.0;
+  }
+
+  void operator++(int) {
+    *this += 1.0;
+  }
+
+  bool hasImplementation() const {
+    return static_cast<bool>(increment_);
+  }
+
+ private:
+  folly::Function<void(double)> increment_;
+};
+
+} // namespace detail
+} // namespace folly
diff --git a/folly/compression/test/CountersTest.cpp b/folly/compression/test/CountersTest.cpp
new file mode 100644 (file)
index 0000000..c51175f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018-present Facebook, Inc.
+ *
+ * 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 <folly/compression/Counters.h>
+#include <folly/compression/Compression.h>
+#include <folly/portability/GTest.h>
+
+using ::folly::CompressionCounterType;
+using ::folly::detail::CompressionCounter;
+
+namespace {
+constexpr auto kCodecType = folly::io::CodecType::USER_DEFINED;
+constexpr folly::StringPiece kCodecName = "test";
+constexpr auto kKey = folly::CompressionCounterKey::BYTES_AFTER_COMPRESSION;
+} // namespace
+
+TEST(FollyCountersTest, HasImplementation) {
+  CompressionCounter counter(
+      kCodecType, kCodecName, folly::none, kKey, CompressionCounterType::SUM);
+  EXPECT_FALSE(counter.hasImplementation());
+}
+
+TEST(FollyCountersTest, SumWorks) {
+  CompressionCounter counter(
+      kCodecType, kCodecName, folly::none, kKey, CompressionCounterType::SUM);
+  for (int i = 0; i < 100; ++i) {
+    ++counter;
+    counter++;
+  }
+}
+
+TEST(FollyCountersTest, AvgWorks) {
+  CompressionCounter counter(
+      kCodecType,
+      kCodecName,
+      folly::none,
+      kKey,
+      CompressionCounterType::AVG);
+  for (int i = 0; i < 100; ++i) {
+    counter += 5;
+  }
+}