| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| // See the header for a description. |
| |
| #include "pagespeed/kernel/base/split_statistics.h" |
| |
| #include "base/logging.h" |
| #include "pagespeed/kernel/base/abstract_mutex.h" |
| #include "pagespeed/kernel/base/statistics.h" |
| #include "pagespeed/kernel/base/thread_system.h" |
| |
| namespace net_instaweb { |
| |
| SplitUpDownCounter::SplitUpDownCounter(UpDownCounter* rw, UpDownCounter* w) |
| : rw_(rw), w_(w) {} |
| |
| SplitUpDownCounter::~SplitUpDownCounter() {} |
| |
| void SplitUpDownCounter::Set(int64 value) { |
| w_->Set(value); |
| rw_->Set(value); |
| } |
| |
| int64 SplitUpDownCounter::SetReturningPreviousValue(int64 value) { |
| w_->Set(value); |
| return rw_->SetReturningPreviousValue(value); |
| } |
| |
| int64 SplitUpDownCounter::Get() const { return rw_->Get(); } |
| |
| StringPiece SplitUpDownCounter::GetName() const { return rw_->GetName(); } |
| |
| int64 SplitUpDownCounter::AddHelper(int64 delta) { |
| w_->Add(delta); |
| return rw_->Add(delta); |
| } |
| |
| SplitVariable::SplitVariable(Variable* rw, Variable* w) : rw_(rw), w_(w) {} |
| |
| SplitVariable::~SplitVariable() {} |
| |
| int64 SplitVariable::Get() const { return rw_->Get(); } |
| |
| void SplitVariable::Clear() { |
| w_->Clear(); |
| rw_->Clear(); |
| } |
| |
| StringPiece SplitVariable::GetName() const { return rw_->GetName(); } |
| |
| int64 SplitVariable::AddHelper(int64 delta) { |
| w_->Add(delta); |
| return rw_->Add(delta); |
| } |
| |
| SplitHistogram::SplitHistogram(ThreadSystem* threads, Histogram* rw, |
| Histogram* w) |
| : lock_(threads->NewMutex()), rw_(rw), w_(w) {} |
| |
| SplitHistogram::~SplitHistogram() {} |
| |
| void SplitHistogram::Add(double value) { |
| w_->Add(value); |
| rw_->Add(value); |
| } |
| |
| void SplitHistogram::Clear() { |
| // Clear only resets local on purpose, in case it's tied to a clear button |
| // in a UI. |
| rw_->Clear(); |
| } |
| |
| void SplitHistogram::Render(int index, Writer* writer, |
| MessageHandler* handler) { |
| rw_->Render(index, writer, handler); |
| } |
| |
| int SplitHistogram::NumBuckets() { return rw_->NumBuckets(); } |
| |
| void SplitHistogram::EnableNegativeBuckets() { |
| w_->EnableNegativeBuckets(); |
| rw_->EnableNegativeBuckets(); |
| } |
| |
| void SplitHistogram::SetMinValue(double value) { |
| w_->SetMinValue(value); |
| rw_->SetMinValue(value); |
| } |
| |
| void SplitHistogram::SetMaxValue(double value) { |
| w_->SetMaxValue(value); |
| rw_->SetMaxValue(value); |
| } |
| |
| void SplitHistogram::SetSuggestedNumBuckets(int i) { |
| w_->SetSuggestedNumBuckets(i); |
| rw_->SetSuggestedNumBuckets(i); |
| } |
| |
| double SplitHistogram::BucketStart(int index) { |
| return rw_->BucketStart(index); |
| } |
| |
| double SplitHistogram::BucketLimit(int index) { |
| return rw_->BucketLimit(index); |
| } |
| |
| double SplitHistogram::BucketCount(int index) { |
| return rw_->BucketCount(index); |
| } |
| |
| double SplitHistogram::AverageInternal() { return rw_->Average(); } |
| |
| double SplitHistogram::PercentileInternal(const double perc) { |
| return rw_->Percentile(perc); |
| } |
| |
| double SplitHistogram::StandardDeviationInternal() { |
| return rw_->StandardDeviation(); |
| } |
| |
| double SplitHistogram::CountInternal() { return rw_->Count(); } |
| |
| double SplitHistogram::MaximumInternal() { return rw_->Maximum(); } |
| |
| double SplitHistogram::MinimumInternal() { return rw_->Minimum(); } |
| |
| AbstractMutex* SplitHistogram::lock() { return lock_.get(); } |
| |
| SplitTimedVariable::SplitTimedVariable(TimedVariable* rw, TimedVariable* w) |
| : rw_(rw), w_(w) {} |
| |
| SplitTimedVariable::~SplitTimedVariable() {} |
| |
| void SplitTimedVariable::IncBy(int64 delta) { |
| w_->IncBy(delta); |
| rw_->IncBy(delta); |
| } |
| |
| int64 SplitTimedVariable::Get(int level) { return rw_->Get(level); } |
| |
| void SplitTimedVariable::Clear() { |
| // Clear only resets local on purpose, in case it's tied to a clear button |
| // in a UI. |
| rw_->Clear(); |
| } |
| |
| SplitStatistics::SplitStatistics(ThreadSystem* thread_system, Statistics* local, |
| Statistics* global) |
| : thread_system_(thread_system), local_(local), global_(global) {} |
| |
| SplitStatistics::~SplitStatistics() {} |
| |
| SplitUpDownCounter* SplitStatistics::NewUpDownCounter(StringPiece name) { |
| UpDownCounter* local_var = local_->FindUpDownCounter(name); |
| CHECK(local_var != nullptr); |
| |
| UpDownCounter* global_var = global_->FindUpDownCounter(name); |
| CHECK(global_var != nullptr); |
| |
| return new SplitUpDownCounter(local_var /* read/write */, |
| global_var /* write only */); |
| } |
| |
| SplitVariable* SplitStatistics::NewVariable(StringPiece name) { |
| Variable* local_var = local_->FindVariable(name); |
| CHECK(local_var != nullptr); |
| |
| Variable* global_var = global_->FindVariable(name); |
| CHECK(global_var != nullptr); |
| |
| return new SplitVariable(local_var /* read/write */, |
| global_var /* write only */); |
| } |
| |
| SplitUpDownCounter* SplitStatistics::NewGlobalUpDownCounter(StringPiece name) { |
| UpDownCounter* local_var = local_->FindUpDownCounter(name); |
| CHECK(local_var != nullptr); |
| |
| UpDownCounter* global_var = global_->FindUpDownCounter(name); |
| CHECK(global_var != nullptr); |
| |
| // For NewGlobalUpDownCounter we reverse global and local from their usual |
| // behavior in NewVariable, doing reads from the global/aggregate. |
| return new SplitUpDownCounter(global_var /* read/write */, |
| local_var /* write only */); |
| } |
| |
| SplitHistogram* SplitStatistics::NewHistogram(StringPiece name) { |
| Histogram* local_histo = local_->FindHistogram(name); |
| CHECK(local_histo != nullptr); |
| |
| Histogram* global_histo = global_->FindHistogram(name); |
| CHECK(global_histo != nullptr); |
| |
| return new SplitHistogram(thread_system_, local_histo /* read/write */, |
| global_histo /* write only */); |
| } |
| |
| SplitTimedVariable* SplitStatistics::NewTimedVariable(StringPiece name) { |
| TimedVariable* local_timed_var = local_->FindTimedVariable(name); |
| CHECK(local_timed_var != nullptr); |
| |
| TimedVariable* global_timed_var = global_->FindTimedVariable(name); |
| CHECK(global_timed_var != nullptr); |
| |
| return new SplitTimedVariable(local_timed_var /* read/write */, |
| global_timed_var /* write only */); |
| } |
| |
| } // namespace net_instaweb |