blob: 72c98067787842d959ecd2ce499a81359bae9398 [file] [log] [blame]
/*
* 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