folly::FunctionScheduler: replace std::function w/ folly::Function
authorSven Over <over@fb.com>
Mon, 4 Apr 2016 09:32:10 +0000 (02:32 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Mon, 4 Apr 2016 09:35:18 +0000 (02:35 -0700)
Summary:By using folly::Function instead of std::function to internally store
functions in FunctionScheduler, this diff allows users to pass
non-copyable lambdas to FunctionScheduler::addFunction.

All exisiting unit tests still pass. Also, passing std::function to
addFunction still works, as the std::function will be implicitly
converted (i.e. wrapped) in a folly::Function. However, this implies
a performance penalty.

Reviewed By: fugalh

Differential Revision: D3092944

fb-gh-sync-id: 1e8081e70d4717025f2eadbb6b6da173460d4373
fbshipit-source-id: 1e8081e70d4717025f2eadbb6b6da173460d4373

folly/experimental/FunctionScheduler.cpp
folly/experimental/FunctionScheduler.h

index d648ce2645181fc1816e25d588f5eaf4f52f9777..de90c4821516567f2bf3ea19d1470770262ee47b 100644 (file)
@@ -92,46 +92,44 @@ FunctionScheduler::~FunctionScheduler() {
   shutdown();
 }
 
-void FunctionScheduler::addFunction(const std::function<void()>& cb,
+void FunctionScheduler::addFunction(Function<void()>&& cb,
                                     milliseconds interval,
                                     StringPiece nameID,
                                     milliseconds startDelay) {
   addFunctionGenericDistribution(
-      cb,
-      IntervalDistributionFunc(ConstIntervalFunctor(interval)),
+      std::move(cb),
+      ConstIntervalFunctor(interval),
       nameID.str(),
       to<std::string>(interval.count(), "ms"),
       startDelay);
 }
 
-void FunctionScheduler::addFunction(const std::function<void()>& cb,
+void FunctionScheduler::addFunction(Function<void()>&& cb,
                                     milliseconds interval,
                                     const LatencyDistribution& latencyDistr,
                                     StringPiece nameID,
                                     milliseconds startDelay) {
   if (latencyDistr.isPoisson) {
     addFunctionGenericDistribution(
-        cb,
-        IntervalDistributionFunc(
-            PoissonDistributionFunctor(latencyDistr.poissonMean)),
+        std::move(cb),
+        PoissonDistributionFunctor(latencyDistr.poissonMean),
         nameID.str(),
         to<std::string>(latencyDistr.poissonMean, "ms (Poisson mean)"),
         startDelay);
   } else {
-    addFunction(cb, interval, nameID, startDelay);
+    addFunction(std::move(cb), interval, nameID, startDelay);
   }
 }
 
 void FunctionScheduler::addFunctionUniformDistribution(
-    const std::function<void()>& cb,
+    Function<void()>&& cb,
     milliseconds minInterval,
     milliseconds maxInterval,
     StringPiece nameID,
     milliseconds startDelay) {
   addFunctionGenericDistribution(
-      cb,
-      IntervalDistributionFunc(
-          UniformDistributionFunctor(minInterval, maxInterval)),
+      std::move(cb),
+      UniformDistributionFunctor(minInterval, maxInterval),
       nameID.str(),
       to<std::string>(
           "[", minInterval.count(), " , ", maxInterval.count(), "] ms"),
@@ -139,8 +137,8 @@ void FunctionScheduler::addFunctionUniformDistribution(
 }
 
 void FunctionScheduler::addFunctionGenericDistribution(
-    const std::function<void()>& cb,
-    const IntervalDistributionFunc& intervalFunc,
+    Function<void()>&& cb,
+    IntervalDistributionFunc&& intervalFunc,
     const std::string& nameID,
     const std::string& intervalDescr,
     milliseconds startDelay) {
@@ -173,7 +171,13 @@ void FunctionScheduler::addFunctionGenericDistribution(
   }
 
   addFunctionToHeap(
-      l, RepeatFunc(cb, intervalFunc, nameID, intervalDescr, startDelay));
+      l,
+      RepeatFunc(
+          std::move(cb),
+          std::move(intervalFunc),
+          nameID,
+          intervalDescr,
+          startDelay));
 }
 
 bool FunctionScheduler::cancelFunction(StringPiece nameID) {
index e3c0d132e3e83a18b8c16fd94f6ae5547d4aa693..e5514596c0a6c1afdba58d28447e4812140e9576 100644 (file)
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <folly/Function.h>
 #include <folly/Range.h>
 #include <chrono>
 #include <condition_variable>
@@ -92,7 +93,7 @@ class FunctionScheduler {
    * Throws an exception on error.  In particular, each function must have a
    * unique name--two functions cannot be added with the same name.
    */
-  void addFunction(const std::function<void()>& cb,
+  void addFunction(Function<void()>&& cb,
                    std::chrono::milliseconds interval,
                    StringPiece nameID = StringPiece(),
                    std::chrono::milliseconds startDelay =
@@ -103,7 +104,7 @@ class FunctionScheduler {
    * LatencyDistribution
    */
   void addFunction(
-      const std::function<void()>& cb,
+      Function<void()>&& cb,
       std::chrono::milliseconds interval,
       const LatencyDistribution& latencyDistr,
       StringPiece nameID = StringPiece(),
@@ -114,7 +115,7 @@ class FunctionScheduler {
     * interval being distributed uniformly within the given interval
     * [minInterval, maxInterval].
     */
-  void addFunctionUniformDistribution(const std::function<void()>& cb,
+  void addFunctionUniformDistribution(Function<void()>&& cb,
                                       std::chrono::milliseconds minInterval,
                                       std::chrono::milliseconds maxInterval,
                                       StringPiece nameID,
@@ -124,7 +125,7 @@ class FunctionScheduler {
    * A type alias for function that is called to determine the time
    * interval for the next scheduled run.
    */
-  using IntervalDistributionFunc = std::function<std::chrono::milliseconds()>;
+  using IntervalDistributionFunc = Function<std::chrono::milliseconds()>;
 
   /**
    * Add a new function to the FunctionScheduler. The scheduling interval
@@ -136,8 +137,8 @@ class FunctionScheduler {
    * @see FunctionScheduler::addFunctionJitterInterval).
    */
   void addFunctionGenericDistribution(
-      const std::function<void()>& cb,
-      const IntervalDistributionFunc& intervalFunc,
+      Function<void()>&& cb,
+      IntervalDistributionFunc&& intervalFunc,
       const std::string& nameID,
       const std::string& intervalDescr,
       std::chrono::milliseconds startDelay);
@@ -186,20 +187,20 @@ class FunctionScheduler {
 
  private:
   struct RepeatFunc {
-    std::function<void()> cb;
+    Function<void()> cb;
     IntervalDistributionFunc intervalFunc;
     std::chrono::steady_clock::time_point nextRunTime;
     std::string name;
     std::chrono::milliseconds startDelay;
     std::string intervalDescr;
 
-    RepeatFunc(const std::function<void()>& cback,
-               const IntervalDistributionFunc& intervalFn,
+    RepeatFunc(Function<void()>&& cback,
+               IntervalDistributionFunc&& intervalFn,
                const std::string& nameID,
                const std::string& intervalDistDescription,
                std::chrono::milliseconds delay)
-        : cb(cback),
-          intervalFunc(intervalFn),
+        : cb(std::move(cback)),
+          intervalFunc(std::move(intervalFn)),
           nextRunTime(),
           name(nameID),
           startDelay(delay),
@@ -217,7 +218,7 @@ class FunctionScheduler {
     }
     void cancel() {
       // Simply reset cb to an empty function.
-      cb = std::function<void()>();
+      cb = {};
     }
     bool isValid() const { return bool(cb); }
   };