| /* |
| * 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 |