| /* |
| * Copyright 2012 Google 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. |
| */ |
| |
| // Author: jmarantz@google.com (Joshua Marantz) |
| |
| #include "pagespeed/kernel/cache/cache_stats.h" |
| |
| #include "pagespeed/kernel/base/shared_string.h" |
| #include "pagespeed/kernel/base/statistics.h" |
| #include "pagespeed/kernel/base/string.h" |
| #include "pagespeed/kernel/base/string_util.h" |
| #include "pagespeed/kernel/base/timer.h" |
| #include "pagespeed/kernel/cache/cache_interface.h" |
| #include "pagespeed/kernel/cache/delegating_cache_callback.h" |
| |
| namespace { |
| |
| const char kGetCountHistogram[] = "_get_count"; |
| const char kHitLatencyHistogram[] = "_hit_latency_us"; |
| const char kInsertLatencyHistogram[] = "_insert_latency_us"; |
| const char kInsertSizeHistogram[] = "_insert_size_bytes"; |
| const char kLookupSizeHistogram[] = "_lookup_size_bytes"; |
| |
| const char kDeletes[] = "_deletes"; |
| const char kHits[] = "_hits"; |
| const char kInserts[] = "_inserts"; |
| const char kMisses[] = "_misses"; |
| |
| // TODO(jmarantz): tie this to CacheBatcher::kDefaultMaxQueueSize, |
| // but for now I want to get discrete counts in each bucket. |
| const int kGetCountHistogramMaxValue = 500; |
| const int kSizeHistogramMaxValue = 5*1000*1000; |
| const int kLatencyHistogramMaxValueUs = 1*1000*1000; |
| |
| } // namespace |
| |
| namespace net_instaweb { |
| |
| CacheStats::CacheStats(StringPiece prefix, |
| CacheInterface* cache, |
| Timer* timer, |
| Statistics* statistics) |
| : cache_(cache), |
| timer_(timer), |
| get_count_histogram_(statistics->GetHistogram( |
| StrCat(prefix, kGetCountHistogram))), |
| hit_latency_us_histogram_(statistics->GetHistogram( |
| StrCat(prefix, kHitLatencyHistogram))), |
| insert_latency_us_histogram_(statistics->GetHistogram( |
| StrCat(prefix, kInsertLatencyHistogram))), |
| insert_size_bytes_histogram_(statistics->GetHistogram( |
| StrCat(prefix, kInsertSizeHistogram))), |
| lookup_size_bytes_histogram_(statistics->GetHistogram( |
| StrCat(prefix, kLookupSizeHistogram))), |
| deletes_(statistics->GetVariable(StrCat(prefix, kDeletes))), |
| hits_(statistics->GetVariable(StrCat(prefix, kHits))), |
| inserts_(statistics->GetVariable(StrCat(prefix, kInserts))), |
| misses_(statistics->GetVariable(StrCat(prefix, kMisses))), |
| prefix_(prefix.data(), prefix.size()) { |
| get_count_histogram_->SetMaxValue(kGetCountHistogramMaxValue); |
| insert_size_bytes_histogram_->SetMaxValue(kSizeHistogramMaxValue); |
| lookup_size_bytes_histogram_->SetMaxValue(kSizeHistogramMaxValue); |
| hit_latency_us_histogram_->SetMaxValue(kLatencyHistogramMaxValueUs); |
| insert_latency_us_histogram_->SetMaxValue(kLatencyHistogramMaxValueUs); |
| } |
| |
| CacheStats::~CacheStats() { |
| } |
| |
| GoogleString CacheStats::FormatName(StringPiece prefix, StringPiece cache) { |
| return StrCat("Stats(prefix=", prefix, ",cache=", cache, ")"); |
| } |
| |
| void CacheStats::InitStats(StringPiece prefix, Statistics* statistics) { |
| Histogram* get_count_histogram = |
| statistics->AddHistogram(StrCat(prefix, kGetCountHistogram)); |
| get_count_histogram->SetMaxValue(kGetCountHistogramMaxValue); |
| statistics->AddHistogram(StrCat(prefix, kHitLatencyHistogram)); |
| statistics->AddHistogram(StrCat(prefix, kInsertLatencyHistogram)); |
| Histogram* insert_size_bytes_histogram = |
| statistics->AddHistogram(StrCat(prefix, kInsertSizeHistogram)); |
| insert_size_bytes_histogram->SetMaxValue(kSizeHistogramMaxValue); |
| Histogram* lookup_size_bytes_histogram = |
| statistics->AddHistogram(StrCat(prefix, kLookupSizeHistogram)); |
| lookup_size_bytes_histogram->SetMaxValue(kSizeHistogramMaxValue); |
| statistics->AddVariable(StrCat(prefix, kDeletes)); |
| statistics->AddVariable(StrCat(prefix, kHits)); |
| statistics->AddVariable(StrCat(prefix, kInserts)); |
| statistics->AddVariable(StrCat(prefix, kMisses)); |
| } |
| |
| class CacheStats::StatsCallback : public DelegatingCacheCallback { |
| public: |
| StatsCallback(CacheStats* stats, |
| Timer* timer, |
| CacheInterface::Callback* callback) |
| : DelegatingCacheCallback(callback), |
| stats_(stats), |
| timer_(timer) { |
| start_time_us_ = timer->NowUs(); |
| } |
| |
| virtual ~StatsCallback() { |
| } |
| |
| virtual void Done(CacheInterface::KeyState state) { |
| if (state == CacheInterface::kAvailable) { |
| int64 end_time_us = timer_->NowUs(); |
| stats_->hits_->Add(1); |
| stats_->lookup_size_bytes_histogram_->Add(value()->size()); |
| stats_->hit_latency_us_histogram_->Add(end_time_us - start_time_us_); |
| } else { |
| stats_->misses_->Add(1); |
| } |
| DelegatingCacheCallback::Done(state); |
| } |
| |
| private: |
| CacheStats* stats_; |
| Timer* timer_; |
| int64 start_time_us_; |
| |
| DISALLOW_COPY_AND_ASSIGN(StatsCallback); |
| }; |
| |
| void CacheStats::Get(const GoogleString& key, Callback* callback) { |
| if (shutdown_.value()) { |
| ValidateAndReportResult(key, CacheInterface::kNotFound, callback); |
| } else { |
| StatsCallback* cb = new StatsCallback(this, timer_, callback); |
| cache_->Get(key, cb); |
| get_count_histogram_->Add(1); |
| } |
| } |
| |
| void CacheStats::MultiGet(MultiGetRequest* request) { |
| if (shutdown_.value()) { |
| ReportMultiGetNotFound(request); |
| } else { |
| get_count_histogram_->Add(request->size()); |
| for (int i = 0, n = request->size(); i < n; ++i) { |
| KeyCallback* key_callback = &(*request)[i]; |
| key_callback->callback = new StatsCallback(this, timer_, |
| key_callback->callback); |
| } |
| cache_->MultiGet(request); |
| } |
| } |
| |
| void CacheStats::Put(const GoogleString& key, SharedString* value) { |
| if (!shutdown_.value()) { |
| int64 start_time_us = timer_->NowUs(); |
| inserts_->Add(1); |
| insert_size_bytes_histogram_->Add(value->size()); |
| cache_->Put(key, value); |
| insert_latency_us_histogram_->Add(timer_->NowUs() - start_time_us); |
| } |
| } |
| |
| void CacheStats::Delete(const GoogleString& key) { |
| if (!shutdown_.value()) { |
| deletes_->Add(1); |
| cache_->Delete(key); |
| } |
| } |
| |
| } // namespace net_instaweb |