/* * 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, ®_value)) { // TODO: clean up?? } reg_value += value; DWORD err = count_key_.SetBinaryValue(name, ®_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, ®_value)) { memcpy(®_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, ®_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