blob: 2f5678bbdb281927eca3dd55655506673a20703b [file] [log] [blame]
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Implementation of Win32 metrics aggregator.
#include "aggregator-win32.h"
#include "const-win32.h"
#include "util-win32.h"
namespace stats_report {
MetricsAggregatorWin32::MetricsAggregatorWin32(const MetricCollection &coll,
const wchar_t *key_name)
: MetricsAggregator(coll),
is_machine_(false) {
DCHECK(NULL != key_name);
key_name_.Format(kStatsKeyFormatString, key_name);
}
MetricsAggregatorWin32::MetricsAggregatorWin32(const MetricCollection &coll,
const wchar_t *key_name,
bool is_machine)
: MetricsAggregator(coll),
is_machine_(is_machine) {
DCHECK(NULL != key_name);
key_name_.Format(kStatsKeyFormatString, key_name);
}
MetricsAggregatorWin32::~MetricsAggregatorWin32() {
}
bool MetricsAggregatorWin32::StartAggregation() {
DCHECK(NULL == key_.m_hKey);
HKEY parent_key = is_machine_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
LONG err = key_.Create(parent_key, key_name_);
if (err != ERROR_SUCCESS)
return false;
return true;
}
void MetricsAggregatorWin32::EndAggregation() {
count_key_.Close();
timing_key_.Close();
integer_key_.Close();
bool_key_.Close();
key_.Close();
}
bool MetricsAggregatorWin32::EnsureKey(const wchar_t *name, CRegKey *key) {
if (NULL != key->m_hKey)
return true;
LONG err = key->Create(key_, name);
if (ERROR_SUCCESS != err) {
DCHECK(NULL == key->m_hKey);
// TODO: log?
return false;
}
return true;
}
void MetricsAggregatorWin32::Aggregate(CountMetric *metric) {
DCHECK(NULL != metric);
// do as little as possible if no value
uint64 value = metric->Reset();
if (0 == value)
return;
if (!EnsureKey(kCountsKeyName, &count_key_))
return;
CString name(metric->name());
uint64 reg_value = 0;
if (!GetData(&count_key_, name, &reg_value)) {
// TODO: clean up??
}
reg_value += value;
DWORD err = count_key_.SetBinaryValue(name, &reg_value, sizeof(reg_value));
}
void MetricsAggregatorWin32::Aggregate(TimingMetric *metric) {
DCHECK(NULL != metric);
// do as little as possible if no value
TimingMetric::TimingData value = metric->Reset();
if (0 == value.count)
return;
if (!EnsureKey(kTimingsKeyName, &timing_key_))
return;
CString name(metric->name());
TimingMetric::TimingData reg_value;
if (!GetData(&timing_key_, name, &reg_value)) {
memcpy(&reg_value, &value, sizeof(value));
} else {
reg_value.count += value.count;
reg_value.sum += value.sum;
reg_value.minimum = std::min(reg_value.minimum, value.minimum);
reg_value.maximum = std::max(reg_value.maximum, value.maximum);
}
DWORD err = timing_key_.SetBinaryValue(name, &reg_value, sizeof(reg_value));
}
void MetricsAggregatorWin32::Aggregate(IntegerMetric *metric) {
DCHECK(NULL != metric);
// do as little as possible if no value
uint64 value = metric->value();
if (0 == value)
return;
if (!EnsureKey(kIntegersKeyName, &integer_key_))
return;
DWORD err = integer_key_.SetBinaryValue(CString(metric->name()),
&value, sizeof(value));
}
void MetricsAggregatorWin32::Aggregate(BoolMetric *metric) {
DCHECK(NULL != metric);
// do as little as possible if no value
int32 value = metric->Reset();
if (BoolMetric::kBoolUnset == value)
return;
if (!EnsureKey(kBooleansKeyName, &bool_key_))
return;
DWORD err = bool_key_.SetBinaryValue(CString(metric->name()),
&value, sizeof(value));
}
} // namespace stats_report