mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1320894 - Fixed serialization of cache index, r=valentin
This commit is contained in:
parent
8565d5695d
commit
eeff8dadb0
@ -27,7 +27,7 @@
|
||||
#define kMinUnwrittenChanges 300
|
||||
#define kMinDumpInterval 20000 // in milliseconds
|
||||
#define kMaxBufSize 16384
|
||||
#define kIndexVersion 0x00000002
|
||||
#define kIndexVersion 0x00000003
|
||||
#define kUpdateIndexStartDelay 50000 // in milliseconds
|
||||
|
||||
#define INDEX_NAME "index"
|
||||
@ -1649,13 +1649,18 @@ CacheIndex::WriteIndexToDisk()
|
||||
AllocBuffer();
|
||||
mRWHash = new CacheHash();
|
||||
|
||||
CacheIndexHeader *hdr = reinterpret_cast<CacheIndexHeader *>(mRWBuf);
|
||||
NetworkEndian::writeUint32(&hdr->mVersion, kIndexVersion);
|
||||
NetworkEndian::writeUint32(&hdr->mTimeStamp,
|
||||
mRWBufPos = 0;
|
||||
// index version
|
||||
NetworkEndian::writeUint32(mRWBuf + mRWBufPos, kIndexVersion);
|
||||
mRWBufPos += sizeof(uint32_t);
|
||||
// timestamp
|
||||
NetworkEndian::writeUint32(mRWBuf + mRWBufPos,
|
||||
static_cast<uint32_t>(PR_Now() / PR_USEC_PER_SEC));
|
||||
NetworkEndian::writeUint32(&hdr->mIsDirty, 1);
|
||||
mRWBufPos += sizeof(uint32_t);
|
||||
// dirty flag
|
||||
NetworkEndian::writeUint32(mRWBuf + mRWBufPos, 1);
|
||||
mRWBufPos += sizeof(uint32_t);
|
||||
|
||||
mRWBufPos = sizeof(CacheIndexHeader);
|
||||
mSkipEntries = 0;
|
||||
}
|
||||
|
||||
@ -2010,24 +2015,19 @@ CacheIndex::WriteLogToDisk()
|
||||
rv = indexFile->OpenNSPRFileDesc(PR_RDWR, 0600, &fd);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CacheIndexHeader header;
|
||||
int32_t bytesRead = PR_Read(fd, &header, sizeof(CacheIndexHeader));
|
||||
if (bytesRead != sizeof(CacheIndexHeader)) {
|
||||
PR_Close(fd);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NetworkEndian::writeUint32(&header.mIsDirty, 0);
|
||||
|
||||
int64_t offset = PR_Seek64(fd, 0, PR_SEEK_SET);
|
||||
// Seek to dirty flag in the index header and clear it.
|
||||
static_assert(2 * sizeof(uint32_t) == offsetof(CacheIndexHeader, mIsDirty),
|
||||
"Unexpected offset of CacheIndexHeader::mIsDirty");
|
||||
int64_t offset = PR_Seek64(fd, 2 * sizeof(uint32_t), PR_SEEK_SET);
|
||||
if (offset == -1) {
|
||||
PR_Close(fd);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int32_t bytesWritten = PR_Write(fd, &header, sizeof(CacheIndexHeader));
|
||||
uint32_t isDirty = 0;
|
||||
int32_t bytesWritten = PR_Write(fd, &isDirty, sizeof(isDirty));
|
||||
PR_Close(fd);
|
||||
if (bytesWritten != sizeof(CacheIndexHeader)) {
|
||||
if (bytesWritten != sizeof(isDirty)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2140,41 +2140,37 @@ CacheIndex::ParseRecords()
|
||||
uint32_t pos = 0;
|
||||
|
||||
if (!mSkipEntries) {
|
||||
CacheIndexHeader *hdr = reinterpret_cast<CacheIndexHeader *>(
|
||||
moz_xmalloc(sizeof(CacheIndexHeader)));
|
||||
memcpy(hdr, mRWBuf, sizeof(CacheIndexHeader));
|
||||
|
||||
if (NetworkEndian::readUint32(&hdr->mVersion) != kIndexVersion) {
|
||||
free(hdr);
|
||||
if (NetworkEndian::readUint32(mRWBuf + pos) != kIndexVersion) {
|
||||
FinishRead(false);
|
||||
return;
|
||||
}
|
||||
pos += sizeof(uint32_t);
|
||||
|
||||
mIndexTimeStamp = NetworkEndian::readUint32(&hdr->mTimeStamp);
|
||||
mIndexTimeStamp = NetworkEndian::readUint32(mRWBuf + pos);
|
||||
pos += sizeof(uint32_t);
|
||||
|
||||
if (NetworkEndian::readUint32(&hdr->mIsDirty)) {
|
||||
if (NetworkEndian::readUint32(mRWBuf + pos)) {
|
||||
if (mJournalHandle) {
|
||||
CacheFileIOManager::DoomFile(mJournalHandle, nullptr);
|
||||
mJournalHandle = nullptr;
|
||||
}
|
||||
free(hdr);
|
||||
} else {
|
||||
NetworkEndian::writeUint32(&hdr->mIsDirty, 1);
|
||||
uint32_t * isDirty = reinterpret_cast<uint32_t *>(
|
||||
moz_xmalloc(sizeof(uint32_t)));
|
||||
NetworkEndian::writeUint32(isDirty, 1);
|
||||
|
||||
// Mark index dirty. The buffer is freed by CacheFileIOManager when
|
||||
// nullptr is passed as the listener and the call doesn't fail
|
||||
// synchronously.
|
||||
rv = CacheFileIOManager::Write(mIndexHandle, 0,
|
||||
reinterpret_cast<char *>(hdr),
|
||||
sizeof(CacheIndexHeader), true, false,
|
||||
nullptr);
|
||||
rv = CacheFileIOManager::Write(mIndexHandle, 2 * sizeof(uint32_t),
|
||||
reinterpret_cast<char *>(isDirty),
|
||||
sizeof(uint32_t), true, false, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
// This is not fatal, just free the memory
|
||||
free(hdr);
|
||||
free(isDirty);
|
||||
}
|
||||
}
|
||||
|
||||
pos += sizeof(CacheIndexHeader);
|
||||
pos += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t hashOffset = pos;
|
||||
@ -2314,8 +2310,7 @@ CacheIndex::ParseJournal()
|
||||
|
||||
while (pos + sizeof(CacheIndexRecord) <= mRWBufPos &&
|
||||
mSkipEntries != entryCnt) {
|
||||
CacheIndexRecord *rec = reinterpret_cast<CacheIndexRecord *>(mRWBuf + pos);
|
||||
CacheIndexEntry tmpEntry(&rec->mHash);
|
||||
CacheIndexEntry tmpEntry(reinterpret_cast<SHA1Sum::Hash *>(mRWBuf + pos));
|
||||
tmpEntry.ReadFromBuf(mRWBuf + pos);
|
||||
|
||||
CacheIndexEntry *entry = mTmpJournal.PutEntry(*tmpEntry.Hash());
|
||||
|
@ -56,11 +56,16 @@ typedef struct {
|
||||
uint32_t mIsDirty;
|
||||
} CacheIndexHeader;
|
||||
|
||||
static_assert(
|
||||
sizeof(CacheIndexHeader::mVersion) + sizeof(CacheIndexHeader::mTimeStamp) +
|
||||
sizeof(CacheIndexHeader::mIsDirty) == sizeof(CacheIndexHeader),
|
||||
"Unexpected sizeof(CacheIndexHeader)!");
|
||||
|
||||
struct CacheIndexRecord {
|
||||
SHA1Sum::Hash mHash;
|
||||
uint32_t mFrecency;
|
||||
uint32_t mExpirationTime;
|
||||
OriginAttrsHash mOriginAttrsHash;
|
||||
uint32_t mExpirationTime;
|
||||
|
||||
/*
|
||||
* 1000 0000 0000 0000 0000 0000 0000 0000 : initialized
|
||||
@ -72,16 +77,22 @@ struct CacheIndexRecord {
|
||||
* 0000 0011 0000 0000 0000 0000 0000 0000 : reserved
|
||||
* 0000 0000 1111 1111 1111 1111 1111 1111 : file size (in kB)
|
||||
*/
|
||||
uint32_t mFlags;
|
||||
uint32_t mFlags;
|
||||
|
||||
CacheIndexRecord()
|
||||
: mFrecency(0)
|
||||
, mExpirationTime(nsICacheEntry::NO_EXPIRATION_TIME)
|
||||
, mOriginAttrsHash(0)
|
||||
, mExpirationTime(nsICacheEntry::NO_EXPIRATION_TIME)
|
||||
, mFlags(0)
|
||||
{}
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(CacheIndexRecord::mHash) + sizeof(CacheIndexRecord::mFrecency) +
|
||||
sizeof(CacheIndexRecord::mOriginAttrsHash) + sizeof(CacheIndexRecord::mExpirationTime) +
|
||||
sizeof(CacheIndexRecord::mFlags) == sizeof(CacheIndexRecord),
|
||||
"Unexpected sizeof(CacheIndexRecord)!");
|
||||
|
||||
class CacheIndexEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
@ -221,36 +232,24 @@ public:
|
||||
|
||||
void WriteToBuf(void *aBuf)
|
||||
{
|
||||
CacheIndexRecord *dst = reinterpret_cast<CacheIndexRecord *>(aBuf);
|
||||
|
||||
// Copy the whole record to the buffer.
|
||||
memcpy(aBuf, mRec, sizeof(CacheIndexRecord));
|
||||
|
||||
uint8_t* ptr = static_cast<uint8_t*>(aBuf);
|
||||
memcpy(ptr, mRec->mHash, sizeof(SHA1Sum::Hash)); ptr += sizeof(SHA1Sum::Hash);
|
||||
NetworkEndian::writeUint32(ptr, mRec->mFrecency); ptr += sizeof(uint32_t);
|
||||
NetworkEndian::writeUint64(ptr, mRec->mOriginAttrsHash); ptr += sizeof(uint64_t);
|
||||
NetworkEndian::writeUint32(ptr, mRec->mExpirationTime); ptr += sizeof(uint32_t);
|
||||
// Dirty and fresh flags should never go to disk, since they make sense only
|
||||
// during current session.
|
||||
dst->mFlags &= ~kDirtyMask;
|
||||
dst->mFlags &= ~kFreshMask;
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
// Data in the buffer are in machine byte order and we want them in network
|
||||
// byte order.
|
||||
NetworkEndian::writeUint32(&dst->mFrecency, dst->mFrecency);
|
||||
NetworkEndian::writeUint32(&dst->mExpirationTime, dst->mExpirationTime);
|
||||
NetworkEndian::writeUint64(&dst->mOriginAttrsHash, dst->mOriginAttrsHash);
|
||||
NetworkEndian::writeUint32(&dst->mFlags, dst->mFlags);
|
||||
#endif
|
||||
NetworkEndian::writeUint32(ptr, mRec->mFlags & ~(kDirtyMask | kFreshMask));
|
||||
}
|
||||
|
||||
void ReadFromBuf(void *aBuf)
|
||||
{
|
||||
CacheIndexRecord *src= reinterpret_cast<CacheIndexRecord *>(aBuf);
|
||||
MOZ_ASSERT(memcmp(&mRec->mHash, &src->mHash,
|
||||
sizeof(SHA1Sum::Hash)) == 0);
|
||||
|
||||
mRec->mFrecency = NetworkEndian::readUint32(&src->mFrecency);
|
||||
mRec->mExpirationTime = NetworkEndian::readUint32(&src->mExpirationTime);
|
||||
mRec->mOriginAttrsHash = NetworkEndian::readUint64(&src->mOriginAttrsHash);
|
||||
mRec->mFlags = NetworkEndian::readUint32(&src->mFlags);
|
||||
const uint8_t* ptr = static_cast<const uint8_t*>(aBuf);
|
||||
MOZ_ASSERT(memcmp(&mRec->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); ptr += sizeof(SHA1Sum::Hash);
|
||||
mRec->mFrecency = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t);
|
||||
mRec->mOriginAttrsHash = NetworkEndian::readUint64(ptr); ptr += sizeof(uint64_t);
|
||||
mRec->mExpirationTime = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t);
|
||||
mRec->mFlags = NetworkEndian::readUint32(ptr);
|
||||
}
|
||||
|
||||
void Log() const {
|
||||
|
Loading…
Reference in New Issue
Block a user