From 43c97295fe42ad21941fa94637c2e783733d6d63 Mon Sep 17 00:00:00 2001 From: Lee Hwa Date: Mon, 6 Aug 2012 13:42:49 -0700 Subject: [PATCH] Task #906853: Implement ThreadLocalServiceData and reduce lock contentions during channel counter update Summary: Cache the counter updates on thread local data structures and aggregate/publish the data from a separate thread periodically. The ThreadLocalServiceData is implemented on top of the TLStats data structures. I am plannig to deploy a private build to production tomorrow to test this change in production, but figured it might be better to send the diff out first and get code review feedbacks at the same time. Test Plan: Run and pass unit tests. Run end-to-end testings on sandbox. (TBD) Deploy a private build to a production server and make sure the thrift call latency is reduced. Reviewed By: xin@fb.com FB internal diff: D540239 --- folly/Histogram.h | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/folly/Histogram.h b/folly/Histogram.h index 6b7cbcdd..f25fcbb0 100644 --- a/folly/Histogram.h +++ b/folly/Histogram.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace folly { @@ -233,6 +234,22 @@ class Histogram { count = 0; } + Bucket& merge(const Bucket &bucket) { + if (this != &bucket) { + sum += bucket.sum; + count += bucket.count; + } + return *this; + } + + Bucket& operator=(const Bucket& bucket) { + if (this != &bucket) { + sum = bucket.sum; + count = bucket.count; + } + return *this; + } + ValueType sum; uint64_t count; }; @@ -269,6 +286,37 @@ class Histogram { } } + /* Merge two histogram data together */ + void merge(Histogram &hist) { + // the two histogram bucket definitions must match to support + // a merge. + if (getBucketSize() != hist.getBucketSize() || + getMin() != hist.getMin() || + getMax() != hist.getMax() || + getNumBuckets() != hist.getNumBuckets() ) { + throw std::invalid_argument("Cannot merge from input histogram."); + } + + for (int i = 0; i < buckets_.getNumBuckets(); i++) { + buckets_.getByIndex(i).merge(hist.buckets_.getByIndex(i)); + } + } + + /* Copy bucket values from another histogram */ + void copy(Histogram &hist) { + // the two histogram bucket definition must match + if (getBucketSize() != hist.getBucketSize() || + getMin() != hist.getMin() || + getMax() != hist.getMax() || + getNumBuckets() != hist.getNumBuckets() ) { + throw std::invalid_argument("Cannot copy from input histogram."); + } + + for (int i = 0; i < buckets_.getNumBuckets(); i++) { + buckets_.getByIndex(i) = hist.buckets_.getByIndex(i); + } + } + /* Returns the bucket size of each bucket in the histogram. */ ValueType getBucketSize() const { return buckets_.getBucketSize(); -- 2.34.1