CacheFileUtils.h (6914B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef CacheFileUtils__h__ 6 #define CacheFileUtils__h__ 7 8 #include "nsError.h" 9 #include "nsCOMPtr.h" 10 #include "nsString.h" 11 #include "nsTArray.h" 12 #include "mozilla/Mutex.h" 13 #include "mozilla/StaticMutex.h" 14 #include "mozilla/TimeStamp.h" 15 16 class nsILoadContextInfo; 17 18 namespace mozilla { 19 namespace net { 20 namespace CacheFileUtils { 21 22 extern const char* kAltDataKey; 23 24 already_AddRefed<nsILoadContextInfo> ParseKey(const nsACString& aKey, 25 nsACString* aIdEnhance = nullptr, 26 nsACString* aURISpec = nullptr); 27 28 void AppendKeyPrefix(nsILoadContextInfo* aInfo, nsACString& _retval); 29 30 void AppendTagWithValue(nsACString& aTarget, char const aTag, 31 const nsACString& aValue); 32 33 nsresult KeyMatchesLoadContextInfo(const nsACString& aKey, 34 nsILoadContextInfo* aInfo, bool* _retval); 35 36 class ValidityPair { 37 public: 38 ValidityPair(uint32_t aOffset, uint32_t aLen); 39 40 ValidityPair& operator=(const ValidityPair& aOther) = default; 41 42 // Returns true when two pairs can be merged, i.e. they do overlap or the one 43 // ends exactly where the other begins. 44 bool CanBeMerged(const ValidityPair& aOther) const; 45 46 // Returns true when aOffset is placed anywhere in the validity interval or 47 // exactly after its end. 48 bool IsInOrFollows(uint32_t aOffset) const; 49 50 // Returns true when this pair has lower offset than the other pair. In case 51 // both pairs have the same offset it returns true when this pair has a 52 // shorter length. 53 bool LessThan(const ValidityPair& aOther) const; 54 55 // Merges two pair into one. 56 void Merge(const ValidityPair& aOther); 57 58 uint32_t Offset() const { return mOffset; } 59 uint32_t Len() const { return mLen; } 60 61 private: 62 uint32_t mOffset; 63 uint32_t mLen; 64 }; 65 66 class ValidityMap { 67 public: 68 // Prints pairs in the map into log. 69 void Log() const; 70 71 // Returns number of pairs in the map. 72 uint32_t Length() const; 73 74 // Adds a new pair to the map. It keeps the pairs ordered and merges pairs 75 // when possible. 76 void AddPair(uint32_t aOffset, uint32_t aLen); 77 78 // Removes all pairs from the map. 79 void Clear(); 80 81 size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; 82 83 ValidityPair& operator[](uint32_t aIdx); 84 85 private: 86 nsTArray<ValidityPair> mMap; 87 }; 88 89 class DetailedCacheHitTelemetry { 90 public: 91 enum ERecType { HIT = 0, MISS = 1 }; 92 93 static void AddRecord(ERecType aType, TimeStamp aLoadStart); 94 95 private: 96 class HitRate { 97 public: 98 HitRate(); 99 100 void AddRecord(ERecType aType); 101 uint32_t GetHitRateBucket() const; 102 uint32_t Count(); 103 void Reset(); 104 105 private: 106 uint32_t mHitCnt = 0; 107 uint32_t mMissCnt = 0; 108 }; 109 110 // Group the hits and misses statistics by cache files count ranges (0-5000, 111 // 5001-10000, ... , 95001- ) 112 static const uint32_t kRangeSize = 5000; 113 static const uint32_t kNumOfRanges = 20; 114 static const uint32_t kPercentageRange = 5; 115 static const uint32_t kMaxPercentage = 100; 116 117 // Use the same ranges to report an average hit rate. Report the hit rates 118 // (and reset the counters) every kTotalSamplesReportLimit samples. 119 static const uint32_t kTotalSamplesReportLimit = 1000; 120 121 // Report hit rate for a given cache size range only if it contains 122 // kHitRateSamplesReportLimit or more samples. This limit should avoid 123 // reporting a biased statistics. 124 static const uint32_t kHitRateSamplesReportLimit = 500; 125 126 // All hit rates are accumulated in a single telemetry probe, so to use 127 // a sane number of enumerated values the hit rate is divided into buckets 128 // instead of using a percent value. This constant defines number of buckets 129 // that we divide the hit rates into. I.e. we'll report ranges 0%-5%, 5%-10%, 130 // 10-%15%, ... 131 static const uint32_t kHitRateBuckets = 20; 132 133 // Protects sRecordCnt, sHRStats and Telemetry::Accumulated() calls. 134 static StaticMutex sLock; 135 136 // Counter of samples that is compared against kTotalSamplesReportLimit. 137 static uint32_t sRecordCnt MOZ_GUARDED_BY(sLock); 138 139 // Hit rate statistics for every cache size range. 140 static HitRate sHRStats[kNumOfRanges] MOZ_GUARDED_BY(sLock); 141 }; 142 143 class CachePerfStats { 144 public: 145 // perfStatTypes in displayRcwnStats() in toolkit/content/aboutNetworking.js 146 // must match EDataType 147 enum EDataType { 148 IO_OPEN = 0, 149 IO_READ = 1, 150 IO_WRITE = 2, 151 ENTRY_OPEN = 3, 152 LAST = 4 153 }; 154 155 static void AddValue(EDataType aType, uint32_t aValue, bool aShortOnly); 156 static uint32_t GetAverage(EDataType aType, bool aFiltered); 157 static uint32_t GetStdDev(EDataType aType, bool aFiltered); 158 static bool IsCacheSlow(); 159 static void GetSlowStats(uint32_t* aSlow, uint32_t* aNotSlow); 160 161 private: 162 // This class computes average and standard deviation, it returns an 163 // arithmetic avg and stddev until total number of values reaches mWeight. 164 // Then it returns modified moving average computed as follows: 165 // 166 // avg = (1-a)*avg + a*value 167 // avgsq = (1-a)*avgsq + a*value^2 168 // stddev = sqrt(avgsq - avg^2) 169 // 170 // where 171 // avgsq is an average of the square of the values 172 // a = 1 / weight 173 class MMA { 174 public: 175 MMA(uint32_t aTotalWeight, bool aFilter); 176 177 void AddValue(uint32_t aValue); 178 uint32_t GetAverage(); 179 uint32_t GetStdDev(); 180 181 private: 182 uint64_t mSum; 183 uint64_t mSumSq; 184 uint32_t mCnt; 185 uint32_t mWeight; 186 bool mFilter; 187 }; 188 189 class PerfData { 190 public: 191 PerfData(); 192 193 void AddValue(uint32_t aValue, bool aShortOnly); 194 uint32_t GetAverage(bool aFiltered); 195 uint32_t GetStdDev(bool aFiltered); 196 197 private: 198 // Contains filtered data (i.e. times when we think the cache and disk was 199 // not busy) for a longer time. 200 MMA mFilteredAvg; 201 202 // Contains unfiltered average of few recent values. 203 MMA mShortAvg; 204 }; 205 206 static StaticMutex sLock; 207 208 static PerfData sData[LAST] MOZ_GUARDED_BY(sLock); 209 static uint32_t sCacheSlowCnt MOZ_GUARDED_BY(sLock); 210 static uint32_t sCacheNotSlowCnt MOZ_GUARDED_BY(sLock); 211 }; 212 213 void FreeBuffer(void* aBuf); 214 215 nsresult ParseAlternativeDataInfo(const char* aInfo, int64_t* _offset, 216 nsACString* _type); 217 218 void BuildAlternativeDataInfo(const char* aInfo, int64_t aOffset, 219 nsACString& _retval); 220 221 class CacheFileLock final { 222 public: 223 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheFileLock) 224 CacheFileLock() = default; 225 226 mozilla::Mutex& Lock() MOZ_RETURN_CAPABILITY(mLock) { return mLock; } 227 228 private: 229 ~CacheFileLock() = default; 230 231 mozilla::Mutex mLock{"CacheFile.mLock"}; 232 }; 233 234 } // namespace CacheFileUtils 235 } // namespace net 236 } // namespace mozilla 237 238 #endif