From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../mediacapabilities/BenchmarkStorageParent.cpp | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 dom/media/mediacapabilities/BenchmarkStorageParent.cpp (limited to 'dom/media/mediacapabilities/BenchmarkStorageParent.cpp') diff --git a/dom/media/mediacapabilities/BenchmarkStorageParent.cpp b/dom/media/mediacapabilities/BenchmarkStorageParent.cpp new file mode 100644 index 0000000000..64ae6ddd44 --- /dev/null +++ b/dom/media/mediacapabilities/BenchmarkStorageParent.cpp @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "BenchmarkStorageParent.h" +#include "KeyValueStorage.h" + +namespace mozilla { + +/* Moving average window size. */ +const int32_t AVG_WINDOW = 20; +/* Calculate the moving average for the new value aValue for the current window + * aWindow and the already existing average aAverage. When the method returns + * aAverage will contain the new average and aWindow will contain the new + * window.*/ +void BenchmarkStorageParent::MovingAverage(int32_t& aAverage, int32_t& aWindow, + const int32_t aValue) { + if (aWindow < AVG_WINDOW) { + aAverage = (aAverage * aWindow + aValue) / (aWindow + 1); + aWindow++; + return; + } + MOZ_ASSERT(aWindow == AVG_WINDOW); + aAverage = (aAverage - aAverage / aWindow) + (aValue / aWindow); +} + +/* In order to decrease the number of times the database is accessed when the + * moving average is stored or retrieved we use the same value to store _both_ + * the window and the average. The range of the average is limited since it is + * a percentage (0-100), and the range of the window is limited + * (1-20). Thus the number that is stored in the database is in the form + * (digits): WWAAA. For example, the value stored when an average(A) of 88 + * corresponds to a window(W) 7 is 7088. The average of 100 that corresponds to + * a window of 20 is 20100. The following methods are helpers to extract or + * construct the stored value according to the above. */ + +/* Stored value will be in the form WWAAA(19098). We need to extract the window + * (19) and the average score (98). The aValue will + * be parsed, the aWindow will contain the window (of the moving average) and + * the return value will contain the average itself. */ +int32_t BenchmarkStorageParent::ParseStoredValue(int32_t aValue, + int32_t& aWindow) { + MOZ_ASSERT(aValue > 999); + MOZ_ASSERT(aValue < 100000); + + int32_t score = aValue % 1000; + aWindow = (aValue / 1000) % 100; + return score; +} + +int32_t BenchmarkStorageParent::PrepareStoredValue(int32_t aScore, + int32_t aWindow) { + MOZ_ASSERT(aScore >= 0); + MOZ_ASSERT(aScore <= 100); + MOZ_ASSERT(aWindow > 0); + MOZ_ASSERT(aWindow < 21); + + return aWindow * 1000 + aScore; +} + +BenchmarkStorageParent::BenchmarkStorageParent() + : mStorage(new KeyValueStorage) {} + +IPCResult BenchmarkStorageParent::RecvPut(const nsCString& aDbName, + const nsCString& aKey, + const int32_t& aValue) { + // In order to calculate and store the new moving average, we need to get the + // stored value and window first, to calculate the new score and window, and + // then to store the new aggregated value. + mStorage->Get(aDbName, aKey) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [storage = mStorage, aDbName, aKey, aValue](int32_t aResult) { + int32_t window = 0; + int32_t average = 0; + if (aResult >= 0) { + // The key found. + average = ParseStoredValue(aResult, window); + } + MovingAverage(average, window, aValue); + int32_t newValue = PrepareStoredValue(average, window); + // Avoid storing if the values are the same. This is an optimization + // to minimize the disk usage. + if (aResult != newValue) { + storage->Put(aDbName, aKey, newValue); + } + }, + [](nsresult rv) { /*do nothing*/ }); + + return IPC_OK(); +} + +IPCResult BenchmarkStorageParent::RecvGet(const nsCString& aDbName, + const nsCString& aKey, + GetResolver&& aResolve) { + mStorage->Get(aDbName, aKey) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [aResolve](int32_t aResult) { + int32_t window = 0; // not used + aResolve(aResult < 0 ? -1 : ParseStoredValue(aResult, window)); + }, + [aResolve](nsresult rv) { aResolve(-1); }); + + return IPC_OK(); +} + +IPCResult BenchmarkStorageParent::RecvCheckVersion(const nsCString& aDbName, + int32_t aVersion) { + mStorage->Get(aDbName, "Version"_ns) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [storage = mStorage, aDbName, aVersion](int32_t aResult) { + if (aVersion != aResult) { + storage->Clear(aDbName)->Then( + GetCurrentSerialEventTarget(), __func__, + [storage, aDbName, aVersion](bool) { + storage->Put(aDbName, "Version"_ns, aVersion); + }, + [](nsresult rv) { /*do nothing*/ }); + } + }, + [](nsresult rv) { /*do nothing*/ }); + + return IPC_OK(); +} + +}; // namespace mozilla -- cgit v1.2.3