summaryrefslogtreecommitdiffstats
path: root/netwerk/cache2/CacheFileUtils.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/cache2/CacheFileUtils.h238
1 files changed, 238 insertions, 0 deletions
diff --git a/netwerk/cache2/CacheFileUtils.h b/netwerk/cache2/CacheFileUtils.h
new file mode 100644
index 0000000000..aa6fb64312
--- /dev/null
+++ b/netwerk/cache2/CacheFileUtils.h
@@ -0,0 +1,238 @@
+/* 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/. */
+
+#ifndef CacheFileUtils__h__
+#define CacheFileUtils__h__
+
+#include "nsError.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/TimeStamp.h"
+
+class nsILoadContextInfo;
+
+namespace mozilla {
+namespace net {
+namespace CacheFileUtils {
+
+extern const char* kAltDataKey;
+
+already_AddRefed<nsILoadContextInfo> ParseKey(const nsACString& aKey,
+ nsACString* aIdEnhance = nullptr,
+ nsACString* aURISpec = nullptr);
+
+void AppendKeyPrefix(nsILoadContextInfo* aInfo, nsACString& _retval);
+
+void AppendTagWithValue(nsACString& aTarget, char const aTag,
+ const nsACString& aValue);
+
+nsresult KeyMatchesLoadContextInfo(const nsACString& aKey,
+ nsILoadContextInfo* aInfo, bool* _retval);
+
+class ValidityPair {
+ public:
+ ValidityPair(uint32_t aOffset, uint32_t aLen);
+
+ ValidityPair& operator=(const ValidityPair& aOther) = default;
+
+ // Returns true when two pairs can be merged, i.e. they do overlap or the one
+ // ends exactly where the other begins.
+ bool CanBeMerged(const ValidityPair& aOther) const;
+
+ // Returns true when aOffset is placed anywhere in the validity interval or
+ // exactly after its end.
+ bool IsInOrFollows(uint32_t aOffset) const;
+
+ // Returns true when this pair has lower offset than the other pair. In case
+ // both pairs have the same offset it returns true when this pair has a
+ // shorter length.
+ bool LessThan(const ValidityPair& aOther) const;
+
+ // Merges two pair into one.
+ void Merge(const ValidityPair& aOther);
+
+ uint32_t Offset() const { return mOffset; }
+ uint32_t Len() const { return mLen; }
+
+ private:
+ uint32_t mOffset;
+ uint32_t mLen;
+};
+
+class ValidityMap {
+ public:
+ // Prints pairs in the map into log.
+ void Log() const;
+
+ // Returns number of pairs in the map.
+ uint32_t Length() const;
+
+ // Adds a new pair to the map. It keeps the pairs ordered and merges pairs
+ // when possible.
+ void AddPair(uint32_t aOffset, uint32_t aLen);
+
+ // Removes all pairs from the map.
+ void Clear();
+
+ size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
+
+ ValidityPair& operator[](uint32_t aIdx);
+
+ private:
+ nsTArray<ValidityPair> mMap;
+};
+
+class DetailedCacheHitTelemetry {
+ public:
+ enum ERecType { HIT = 0, MISS = 1 };
+
+ static void AddRecord(ERecType aType, TimeStamp aLoadStart);
+
+ private:
+ class HitRate {
+ public:
+ HitRate();
+
+ void AddRecord(ERecType aType);
+ // Returns the bucket index that the current hit rate falls into according
+ // to the given aNumOfBuckets.
+ uint32_t GetHitRateBucket(uint32_t aNumOfBuckets) const;
+ uint32_t Count();
+ void Reset();
+
+ private:
+ uint32_t mHitCnt = 0;
+ uint32_t mMissCnt = 0;
+ };
+
+ // Group the hits and misses statistics by cache files count ranges (0-5000,
+ // 5001-10000, ... , 95001- )
+ static const uint32_t kRangeSize = 5000;
+ static const uint32_t kNumOfRanges = 20;
+
+ // Use the same ranges to report an average hit rate. Report the hit rates
+ // (and reset the counters) every kTotalSamplesReportLimit samples.
+ static const uint32_t kTotalSamplesReportLimit = 1000;
+
+ // Report hit rate for a given cache size range only if it contains
+ // kHitRateSamplesReportLimit or more samples. This limit should avoid
+ // reporting a biased statistics.
+ static const uint32_t kHitRateSamplesReportLimit = 500;
+
+ // All hit rates are accumulated in a single telemetry probe, so to use
+ // a sane number of enumerated values the hit rate is divided into buckets
+ // instead of using a percent value. This constant defines number of buckets
+ // that we divide the hit rates into. I.e. we'll report ranges 0%-5%, 5%-10%,
+ // 10-%15%, ...
+ static const uint32_t kHitRateBuckets = 20;
+
+ // Protects sRecordCnt, sHRStats and Telemetry::Accumulated() calls.
+ static StaticMutex sLock;
+
+ // Counter of samples that is compared against kTotalSamplesReportLimit.
+ static uint32_t sRecordCnt MOZ_GUARDED_BY(sLock);
+
+ // Hit rate statistics for every cache size range.
+ static HitRate sHRStats[kNumOfRanges] MOZ_GUARDED_BY(sLock);
+};
+
+class CachePerfStats {
+ public:
+ // perfStatTypes in displayRcwnStats() in toolkit/content/aboutNetworking.js
+ // must match EDataType
+ enum EDataType {
+ IO_OPEN = 0,
+ IO_READ = 1,
+ IO_WRITE = 2,
+ ENTRY_OPEN = 3,
+ LAST = 4
+ };
+
+ static void AddValue(EDataType aType, uint32_t aValue, bool aShortOnly);
+ static uint32_t GetAverage(EDataType aType, bool aFiltered);
+ static uint32_t GetStdDev(EDataType aType, bool aFiltered);
+ static bool IsCacheSlow();
+ static void GetSlowStats(uint32_t* aSlow, uint32_t* aNotSlow);
+
+ private:
+ // This class computes average and standard deviation, it returns an
+ // arithmetic avg and stddev until total number of values reaches mWeight.
+ // Then it returns modified moving average computed as follows:
+ //
+ // avg = (1-a)*avg + a*value
+ // avgsq = (1-a)*avgsq + a*value^2
+ // stddev = sqrt(avgsq - avg^2)
+ //
+ // where
+ // avgsq is an average of the square of the values
+ // a = 1 / weight
+ class MMA {
+ public:
+ MMA(uint32_t aTotalWeight, bool aFilter);
+
+ void AddValue(uint32_t aValue);
+ uint32_t GetAverage();
+ uint32_t GetStdDev();
+
+ private:
+ uint64_t mSum;
+ uint64_t mSumSq;
+ uint32_t mCnt;
+ uint32_t mWeight;
+ bool mFilter;
+ };
+
+ class PerfData {
+ public:
+ PerfData();
+
+ void AddValue(uint32_t aValue, bool aShortOnly);
+ uint32_t GetAverage(bool aFiltered);
+ uint32_t GetStdDev(bool aFiltered);
+
+ private:
+ // Contains filtered data (i.e. times when we think the cache and disk was
+ // not busy) for a longer time.
+ MMA mFilteredAvg;
+
+ // Contains unfiltered average of few recent values.
+ MMA mShortAvg;
+ };
+
+ static StaticMutex sLock;
+
+ static PerfData sData[LAST] MOZ_GUARDED_BY(sLock);
+ static uint32_t sCacheSlowCnt MOZ_GUARDED_BY(sLock);
+ static uint32_t sCacheNotSlowCnt MOZ_GUARDED_BY(sLock);
+};
+
+void FreeBuffer(void* aBuf);
+
+nsresult ParseAlternativeDataInfo(const char* aInfo, int64_t* _offset,
+ nsACString* _type);
+
+void BuildAlternativeDataInfo(const char* aInfo, int64_t aOffset,
+ nsACString& _retval);
+
+class CacheFileLock final {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheFileLock)
+ CacheFileLock() = default;
+
+ mozilla::Mutex& Lock() MOZ_RETURN_CAPABILITY(mLock) { return mLock; }
+
+ private:
+ ~CacheFileLock() = default;
+
+ mozilla::Mutex mLock{"CacheFile.mLock"};
+};
+
+} // namespace CacheFileUtils
+} // namespace net
+} // namespace mozilla
+
+#endif