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/. */
5 #ifndef CacheFileMetadata__h__
6 #define CacheFileMetadata__h__
8 #include "CacheFileIOManager.h"
9 #include "CacheStorageService.h"
10 #include "CacheHashUtils.h"
11 #include "CacheObserver.h"
12 #include "mozilla/Endian.h"
13 #include "nsAutoPtr.h"
16 class nsICacheEntryMetaDataVisitor
;
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())
35 class CacheFileMetadataHeader
{
39 uint32_t mLastFetched
;
40 uint32_t mLastModified
;
42 uint32_t mExpirationTime
;
45 void WriteToBuf(void *aBuf
)
47 EnsureCorrectClassSize();
49 uint8_t* ptr
= static_cast<uint8_t*>(aBuf
);
50 NetworkEndian::writeUint32(ptr
, mVersion
); ptr
+= sizeof(uint32_t);
51 NetworkEndian::writeUint32(ptr
, mFetchCount
); ptr
+= sizeof(uint32_t);
52 NetworkEndian::writeUint32(ptr
, mLastFetched
); ptr
+= sizeof(uint32_t);
53 NetworkEndian::writeUint32(ptr
, mLastModified
); ptr
+= sizeof(uint32_t);
54 NetworkEndian::writeUint32(ptr
, mFrecency
); ptr
+= sizeof(uint32_t);
55 NetworkEndian::writeUint32(ptr
, mExpirationTime
); ptr
+= sizeof(uint32_t);
56 NetworkEndian::writeUint32(ptr
, mKeySize
);
59 void ReadFromBuf(const void *aBuf
)
61 EnsureCorrectClassSize();
63 const uint8_t* ptr
= static_cast<const uint8_t*>(aBuf
);
64 mVersion
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
65 mFetchCount
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
66 mLastFetched
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
67 mLastModified
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
68 mFrecency
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
69 mExpirationTime
= BigEndian::readUint32(ptr
); ptr
+= sizeof(uint32_t);
70 mKeySize
= BigEndian::readUint32(ptr
);
73 inline void EnsureCorrectClassSize()
75 static_assert((sizeof(mVersion
) + sizeof(mFetchCount
) +
76 sizeof(mLastFetched
) + sizeof(mLastModified
) + sizeof(mFrecency
) +
77 sizeof(mExpirationTime
) + sizeof(mKeySize
)) ==
78 sizeof(CacheFileMetadataHeader
),
79 "Unexpected sizeof(CacheFileMetadataHeader)!");
86 #define CACHEFILEMETADATALISTENER_IID \
87 { /* a9e36125-3f01-4020-9540-9dafa8d31ba7 */ \
91 {0x95, 0x40, 0x9d, 0xaf, 0xa8, 0xd3, 0x1b, 0xa7} \
94 class CacheFileMetadataListener
: public nsISupports
97 NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILEMETADATALISTENER_IID
)
99 NS_IMETHOD
OnMetadataRead(nsresult aResult
) = 0;
100 NS_IMETHOD
OnMetadataWritten(nsresult aResult
) = 0;
103 NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileMetadataListener
,
104 CACHEFILEMETADATALISTENER_IID
)
107 class CacheFileMetadata
: public CacheFileIOListener
108 , public CacheMemoryConsumer
111 NS_DECL_THREADSAFE_ISUPPORTS
113 CacheFileMetadata(CacheFileHandle
*aHandle
,
114 const nsACString
&aKey
);
115 CacheFileMetadata(bool aMemoryOnly
,
116 const nsACString
&aKey
);
119 void SetHandle(CacheFileHandle
*aHandle
);
121 nsresult
GetKey(nsACString
&_retval
);
123 nsresult
ReadMetadata(CacheFileMetadataListener
*aListener
);
124 nsresult
WriteMetadata(uint32_t aOffset
,
125 CacheFileMetadataListener
*aListener
);
126 nsresult
SyncReadMetadata(nsIFile
*aFile
);
128 bool IsAnonymous() { return mAnonymous
; }
129 bool IsInBrowser() { return mInBrowser
; }
130 uint32_t AppId() { return mAppId
; }
132 const char * GetElement(const char *aKey
);
133 nsresult
SetElement(const char *aKey
, const char *aValue
);
134 nsresult
Visit(nsICacheEntryMetaDataVisitor
*aVisitor
);
136 CacheHash::Hash16_t
GetHash(uint32_t aIndex
);
137 nsresult
SetHash(uint32_t aIndex
, CacheHash::Hash16_t aHash
);
139 nsresult
SetExpirationTime(uint32_t aExpirationTime
);
140 nsresult
GetExpirationTime(uint32_t *_retval
);
141 nsresult
SetFrecency(uint32_t aFrecency
);
142 nsresult
GetFrecency(uint32_t *_retval
);
143 nsresult
GetLastModified(uint32_t *_retval
);
144 nsresult
GetLastFetched(uint32_t *_retval
);
145 nsresult
GetFetchCount(uint32_t *_retval
);
146 // Called by upper layers to indicate the entry this metadata belongs
147 // with has been fetched, i.e. delivered to the consumer.
148 nsresult
OnFetched();
150 int64_t Offset() { return mOffset
; }
151 uint32_t ElementsSize() { return mElementsSize
; }
152 void MarkDirty(bool aUpdateLastModified
= true);
153 bool IsDirty() { return mIsDirty
; }
154 uint32_t MemoryUsage() { return sizeof(CacheFileMetadata
) + mHashArraySize
+ mBufSize
; }
156 NS_IMETHOD
OnFileOpened(CacheFileHandle
*aHandle
, nsresult aResult
);
157 NS_IMETHOD
OnDataWritten(CacheFileHandle
*aHandle
, const char *aBuf
,
159 NS_IMETHOD
OnDataRead(CacheFileHandle
*aHandle
, char *aBuf
, nsresult aResult
);
160 NS_IMETHOD
OnFileDoomed(CacheFileHandle
*aHandle
, nsresult aResult
);
161 NS_IMETHOD
OnEOFSet(CacheFileHandle
*aHandle
, nsresult aResult
);
162 NS_IMETHOD
OnFileRenamed(CacheFileHandle
*aHandle
, nsresult aResult
);
165 size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf
) const;
166 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf
) const;
169 virtual ~CacheFileMetadata();
171 void InitEmptyMetadata();
172 nsresult
ParseMetadata(uint32_t aMetaOffset
, uint32_t aBufOffset
, bool aHaveKey
);
173 nsresult
CheckElements(const char *aBuf
, uint32_t aSize
);
174 void EnsureBuffer(uint32_t aSize
);
175 nsresult
ParseKey(const nsACString
&aKey
);
177 nsRefPtr
<CacheFileHandle
> mHandle
;
179 CacheHash::Hash16_t
*mHashArray
;
180 uint32_t mHashArraySize
;
183 char *mBuf
; // used for parsing, then points
187 CacheFileMetadataHeader mMetaHdr
;
188 uint32_t mElementsSize
;
193 nsCOMPtr
<CacheFileMetadataListener
> mListener
;