CacheFileMetadata.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. #ifndef CacheFileMetadata__h__
  5. #define CacheFileMetadata__h__
  6. #include "CacheFileIOManager.h"
  7. #include "CacheStorageService.h"
  8. #include "CacheHashUtils.h"
  9. #include "CacheObserver.h"
  10. #include "mozilla/EndianUtils.h"
  11. #include "mozilla/BasePrincipal.h"
  12. #include "nsAutoPtr.h"
  13. #include "nsString.h"
  14. class nsICacheEntryMetaDataVisitor;
  15. namespace mozilla {
  16. namespace net {
  17. // Flags stored in CacheFileMetadataHeader.mFlags
  18. // Whether an entry is a pinned entry (created with
  19. // nsICacheStorageService.pinningCacheStorage.)
  20. static const uint32_t kCacheEntryIsPinned = 1 << 0;
  21. // By multiplying with the current half-life we convert the frecency
  22. // to time independent of half-life value. The range fits 32bits.
  23. // When decay time changes on next run of the browser, we convert
  24. // the frecency value to a correct internal representation again.
  25. // It might not be 100% accurate, but for the purpose it suffice.
  26. #define FRECENCY2INT(aFrecency) \
  27. ((uint32_t)((aFrecency) * CacheObserver::HalfLifeSeconds()))
  28. #define INT2FRECENCY(aInt) \
  29. ((double)(aInt) / (double)CacheObserver::HalfLifeSeconds())
  30. #define kCacheEntryVersion 3
  31. #pragma pack(push)
  32. #pragma pack(1)
  33. class CacheFileMetadataHeader {
  34. public:
  35. uint32_t mVersion;
  36. uint32_t mFetchCount;
  37. uint32_t mLastFetched;
  38. uint32_t mLastModified;
  39. uint32_t mFrecency;
  40. uint32_t mExpirationTime;
  41. uint32_t mKeySize;
  42. uint32_t mFlags;
  43. void WriteToBuf(void *aBuf)
  44. {
  45. EnsureCorrectClassSize();
  46. uint8_t* ptr = static_cast<uint8_t*>(aBuf);
  47. MOZ_ASSERT(mVersion == kCacheEntryVersion);
  48. NetworkEndian::writeUint32(ptr, mVersion); ptr += sizeof(uint32_t);
  49. NetworkEndian::writeUint32(ptr, mFetchCount); ptr += sizeof(uint32_t);
  50. NetworkEndian::writeUint32(ptr, mLastFetched); ptr += sizeof(uint32_t);
  51. NetworkEndian::writeUint32(ptr, mLastModified); ptr += sizeof(uint32_t);
  52. NetworkEndian::writeUint32(ptr, mFrecency); ptr += sizeof(uint32_t);
  53. NetworkEndian::writeUint32(ptr, mExpirationTime); ptr += sizeof(uint32_t);
  54. NetworkEndian::writeUint32(ptr, mKeySize); ptr += sizeof(uint32_t);
  55. NetworkEndian::writeUint32(ptr, mFlags);
  56. }
  57. void ReadFromBuf(const void *aBuf)
  58. {
  59. EnsureCorrectClassSize();
  60. const uint8_t* ptr = static_cast<const uint8_t*>(aBuf);
  61. mVersion = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  62. mFetchCount = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  63. mLastFetched = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  64. mLastModified = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  65. mFrecency = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  66. mExpirationTime = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  67. mKeySize = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
  68. if (mVersion >= 2) {
  69. mFlags = BigEndian::readUint32(ptr);
  70. } else {
  71. mFlags = 0;
  72. }
  73. }
  74. inline void EnsureCorrectClassSize()
  75. {
  76. static_assert((sizeof(mVersion) + sizeof(mFetchCount) +
  77. sizeof(mLastFetched) + sizeof(mLastModified) + sizeof(mFrecency) +
  78. sizeof(mExpirationTime) + sizeof(mKeySize)) + sizeof(mFlags) ==
  79. sizeof(CacheFileMetadataHeader),
  80. "Unexpected sizeof(CacheFileMetadataHeader)!");
  81. }
  82. };
  83. #pragma pack(pop)
  84. #define CACHEFILEMETADATALISTENER_IID \
  85. { /* a9e36125-3f01-4020-9540-9dafa8d31ba7 */ \
  86. 0xa9e36125, \
  87. 0x3f01, \
  88. 0x4020, \
  89. {0x95, 0x40, 0x9d, 0xaf, 0xa8, 0xd3, 0x1b, 0xa7} \
  90. }
  91. class CacheFileMetadataListener : public nsISupports
  92. {
  93. public:
  94. NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILEMETADATALISTENER_IID)
  95. NS_IMETHOD OnMetadataRead(nsresult aResult) = 0;
  96. NS_IMETHOD OnMetadataWritten(nsresult aResult) = 0;
  97. virtual bool IsKilled() = 0;
  98. };
  99. NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileMetadataListener,
  100. CACHEFILEMETADATALISTENER_IID)
  101. class CacheFileMetadata : public CacheFileIOListener
  102. , public CacheMemoryConsumer
  103. {
  104. public:
  105. NS_DECL_THREADSAFE_ISUPPORTS
  106. CacheFileMetadata(CacheFileHandle *aHandle,
  107. const nsACString &aKey);
  108. CacheFileMetadata(bool aMemoryOnly,
  109. bool aPinned,
  110. const nsACString &aKey);
  111. CacheFileMetadata();
  112. void SetHandle(CacheFileHandle *aHandle);
  113. nsresult GetKey(nsACString &_retval);
  114. nsresult ReadMetadata(CacheFileMetadataListener *aListener);
  115. uint32_t CalcMetadataSize(uint32_t aElementsSize, uint32_t aHashCount);
  116. nsresult WriteMetadata(uint32_t aOffset,
  117. CacheFileMetadataListener *aListener);
  118. nsresult SyncReadMetadata(nsIFile *aFile);
  119. bool IsAnonymous() const { return mAnonymous; }
  120. mozilla::NeckoOriginAttributes const & OriginAttributes() const { return mOriginAttributes; }
  121. bool Pinned() const { return !!(mMetaHdr.mFlags & kCacheEntryIsPinned); }
  122. const char * GetElement(const char *aKey);
  123. nsresult SetElement(const char *aKey, const char *aValue);
  124. nsresult Visit(nsICacheEntryMetaDataVisitor *aVisitor);
  125. CacheHash::Hash16_t GetHash(uint32_t aIndex);
  126. nsresult SetHash(uint32_t aIndex, CacheHash::Hash16_t aHash);
  127. nsresult AddFlags(uint32_t aFlags);
  128. nsresult RemoveFlags(uint32_t aFlags);
  129. nsresult GetFlags(uint32_t *_retval);
  130. nsresult SetExpirationTime(uint32_t aExpirationTime);
  131. nsresult GetExpirationTime(uint32_t *_retval);
  132. nsresult SetFrecency(uint32_t aFrecency);
  133. nsresult GetFrecency(uint32_t *_retval);
  134. nsresult GetLastModified(uint32_t *_retval);
  135. nsresult GetLastFetched(uint32_t *_retval);
  136. nsresult GetFetchCount(uint32_t *_retval);
  137. // Called by upper layers to indicate the entry this metadata belongs
  138. // with has been fetched, i.e. delivered to the consumer.
  139. nsresult OnFetched();
  140. int64_t Offset() { return mOffset; }
  141. uint32_t ElementsSize() { return mElementsSize; }
  142. void MarkDirty(bool aUpdateLastModified = true);
  143. bool IsDirty() { return mIsDirty; }
  144. uint32_t MemoryUsage() { return sizeof(CacheFileMetadata) + mHashArraySize + mBufSize; }
  145. NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override;
  146. NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf,
  147. nsresult aResult) override;
  148. NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override;
  149. NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override;
  150. NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
  151. NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
  152. virtual bool IsKilled() override { return mListener && mListener->IsKilled(); }
  153. void InitEmptyMetadata();
  154. // Memory reporting
  155. size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
  156. size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
  157. private:
  158. virtual ~CacheFileMetadata();
  159. nsresult ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset, bool aHaveKey);
  160. nsresult CheckElements(const char *aBuf, uint32_t aSize);
  161. nsresult EnsureBuffer(uint32_t aSize);
  162. nsresult ParseKey(const nsACString &aKey);
  163. RefPtr<CacheFileHandle> mHandle;
  164. nsCString mKey;
  165. CacheHash::Hash16_t *mHashArray;
  166. uint32_t mHashArraySize;
  167. uint32_t mHashCount;
  168. int64_t mOffset;
  169. char *mBuf; // used for parsing, then points
  170. // to elements
  171. uint32_t mBufSize;
  172. char *mWriteBuf;
  173. CacheFileMetadataHeader mMetaHdr;
  174. uint32_t mElementsSize;
  175. bool mIsDirty : 1;
  176. bool mAnonymous : 1;
  177. bool mAllocExactSize : 1;
  178. bool mFirstRead : 1;
  179. mozilla::NeckoOriginAttributes mOriginAttributes;
  180. mozilla::TimeStamp mReadStart;
  181. nsCOMPtr<CacheFileMetadataListener> mListener;
  182. };
  183. } // namespace net
  184. } // namespace mozilla
  185. #endif