Bug 1182961 (part 2) - Use nsTHashtable::Iterator in CacheIndex. r=michal.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 26 Jul 2015 20:15:36 -0700
changeset 287926 ffe0edb2aae7b8ae97c9598c6b0f1a06afb2ddee
parent 287925 bff74cecc67cb09b03974e2fa3fd85a9ba873786
child 287927 b60b7c267cef2cecdb1fee854a0433e79e42e191
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1182961
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1182961 (part 2) - Use nsTHashtable::Iterator in CacheIndex. r=michal.
netwerk/cache2/CacheIndex.cpp
netwerk/cache2/CacheIndex.h
--- a/netwerk/cache2/CacheIndex.cpp
+++ b/netwerk/cache2/CacheIndex.cpp
@@ -624,17 +624,17 @@ CacheIndex::EnsureEntryExists(const SHA1
           // This could happen only if somebody copies files to the entries
           // directory while FF is running.
           LOG(("CacheIndex::EnsureEntryExists() - Cache file was added outside "
                "FF process! Update is needed."));
           index->mIndexNeedsUpdate = true;
         } else if (index->mState == READY ||
                    (entryRemoved && !entry->IsFresh())) {
           // Removed non-fresh entries can be present as a result of
-          // ProcessJournalEntry()
+          // MergeJournal()
           LOG(("CacheIndex::EnsureEntryExists() - Didn't find entry that should"
                " exist, update is needed"));
           index->mIndexNeedsUpdate = true;
         }
 
         if (!entry) {
           entry = index->mIndex.PutEntry(*aHash);
         }
@@ -843,17 +843,17 @@ CacheIndex::RemoveEntry(const SHA1Sum::H
           // This could happen only if somebody copies files to the entries
           // directory while FF is running.
           LOG(("CacheIndex::RemoveEntry() - Cache file was added outside FF "
                "process! Update is needed."));
           index->mIndexNeedsUpdate = true;
         } else if (index->mState == READY ||
                    (entryRemoved && !entry->IsFresh())) {
           // Removed non-fresh entries can be present as a result of
-          // ProcessJournalEntry()
+          // MergeJournal()
           LOG(("CacheIndex::RemoveEntry() - Didn't find entry that should exist"
                ", update is needed"));
           index->mIndexNeedsUpdate = true;
         }
       } else {
         if (entry) {
           if (!entry->IsDirty() && entry->IsFileEmpty()) {
             index->mIndex.RemoveEntry(*aHash);
@@ -1599,31 +1599,16 @@ CacheIndex::WriteIndexToDisk()
   NetworkEndian::writeUint32(&hdr->mTimeStamp,
                              static_cast<uint32_t>(PR_Now() / PR_USEC_PER_SEC));
   NetworkEndian::writeUint32(&hdr->mIsDirty, 1);
 
   mRWBufPos = sizeof(CacheIndexHeader);
   mSkipEntries = 0;
 }
 
-namespace {
-
-struct WriteRecordsHelper
-{
-  char    *mBuf;
-  uint32_t mSkip;
-  uint32_t mProcessMax;
-  uint32_t mProcessed;
-#ifdef DEBUG
-  bool     mHasMore;
-#endif
-};
-
-} // namespace
-
 void
 CacheIndex::WriteRecords()
 {
   LOG(("CacheIndex::WriteRecords()"));
 
   nsresult rv;
 
   AssertOwnsLock();
@@ -1636,49 +1621,71 @@ CacheIndex::WriteRecords()
     fileOffset = sizeof(CacheIndexHeader);
     fileOffset += sizeof(CacheIndexRecord) * mSkipEntries;
   } else {
     MOZ_ASSERT(mRWBufPos == sizeof(CacheIndexHeader));
     fileOffset = 0;
   }
   uint32_t hashOffset = mRWBufPos;
 
-  WriteRecordsHelper data;
-  data.mBuf = mRWBuf + mRWBufPos;
-  data.mSkip = mSkipEntries;
-  data.mProcessMax = (mRWBufSize - mRWBufPos) / sizeof(CacheIndexRecord);
-  MOZ_ASSERT(data.mProcessMax != 0 || mProcessEntries == 0); // TODO make sure we can write an empty index
-  data.mProcessed = 0;
+  char* buf = mRWBuf + mRWBufPos;
+  uint32_t skip = mSkipEntries;
+  uint32_t processMax = (mRWBufSize - mRWBufPos) / sizeof(CacheIndexRecord);
+  MOZ_ASSERT(processMax != 0 || mProcessEntries == 0); // TODO make sure we can write an empty index
+  uint32_t processed = 0;
 #ifdef DEBUG
-  data.mHasMore = false;
+  bool hasMore = false;
 #endif
-
-  mIndex.EnumerateEntries(&CacheIndex::CopyRecordsToRWBuf, &data);
-  MOZ_ASSERT(mRWBufPos != static_cast<uint32_t>(data.mBuf - mRWBuf) ||
+  for (auto iter = mIndex.Iter(); !iter.Done(); iter.Next()) {
+    CacheIndexEntry* entry = iter.Get();
+    if (entry->IsRemoved() ||
+        !entry->IsInitialized() ||
+        entry->IsFileEmpty()) {
+      continue;
+    }
+
+    if (skip) {
+      skip--;
+      continue;
+    }
+
+    if (processed == processMax) {
+  #ifdef DEBUG
+      hasMore = true;
+  #endif
+      break;
+    }
+
+    entry->WriteToBuf(buf);
+    buf += sizeof(CacheIndexRecord);
+    processed++;
+  }
+
+  MOZ_ASSERT(mRWBufPos != static_cast<uint32_t>(buf - mRWBuf) ||
              mProcessEntries == 0);
-  mRWBufPos = data.mBuf - mRWBuf;
-  mSkipEntries += data.mProcessed;
+  mRWBufPos = buf - mRWBuf;
+  mSkipEntries += processed;
   MOZ_ASSERT(mSkipEntries <= mProcessEntries);
 
   mRWHash->Update(mRWBuf + hashOffset, mRWBufPos - hashOffset);
 
   if (mSkipEntries == mProcessEntries) {
-    MOZ_ASSERT(!data.mHasMore);
+    MOZ_ASSERT(!hasMore);
 
     // We've processed all records
     if (mRWBufPos + sizeof(CacheHash::Hash32_t) > mRWBufSize) {
       // realloc buffer to spare another write cycle
       mRWBufSize = mRWBufPos + sizeof(CacheHash::Hash32_t);
       mRWBuf = static_cast<char *>(moz_xrealloc(mRWBuf, mRWBufSize));
     }
 
     NetworkEndian::writeUint32(mRWBuf + mRWBufPos, mRWHash->GetHash());
     mRWBufPos += sizeof(CacheHash::Hash32_t);
   } else {
-    MOZ_ASSERT(data.mHasMore);
+    MOZ_ASSERT(hasMore);
   }
 
   rv = CacheFileIOManager::Write(mIndexHandle, fileOffset, mRWBuf, mRWBufPos,
                                  mSkipEntries == mProcessEntries, false, this);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::WriteRecords() - CacheFileIOManager::Write() failed "
          "synchronously [rv=0x%08x]", rv));
     FinishWrite(false);
@@ -1722,52 +1729,16 @@ CacheIndex::FinishWrite(bool aSucceeded)
   if (mState == WRITING) {
     ChangeState(READY);
     mLastDumpTime = TimeStamp::NowLoRes();
   }
 }
 
 // static
 PLDHashOperator
-CacheIndex::CopyRecordsToRWBuf(CacheIndexEntry *aEntry, void* aClosure)
-{
-  if (aEntry->IsRemoved()) {
-    return PL_DHASH_NEXT;
-  }
-
-  if (!aEntry->IsInitialized()) {
-    return PL_DHASH_NEXT;
-  }
-
-  if (aEntry->IsFileEmpty()) {
-    return PL_DHASH_NEXT;
-  }
-
-  WriteRecordsHelper *data = static_cast<WriteRecordsHelper *>(aClosure);
-  if (data->mSkip) {
-    data->mSkip--;
-    return PL_DHASH_NEXT;
-  }
-
-  if (data->mProcessed == data->mProcessMax) {
-#ifdef DEBUG
-    data->mHasMore = true;
-#endif
-    return PL_DHASH_STOP;
-  }
-
-  aEntry->WriteToBuf(data->mBuf);
-  data->mBuf += sizeof(CacheIndexRecord);
-  data->mProcessed++;
-
-  return PL_DHASH_NEXT;
-}
-
-// static
-PLDHashOperator
 CacheIndex::ApplyIndexChanges(CacheIndexEntry *aEntry, void* aClosure)
 {
   CacheIndex *index = static_cast<CacheIndex *>(aClosure);
 
   CacheIndexEntryAutoManage emng(aEntry->Hash(), index);
 
   if (aEntry->IsRemoved()) {
     emng.DoNotSearchInIndex();
@@ -2335,51 +2306,46 @@ CacheIndex::ParseJournal()
 
 void
 CacheIndex::MergeJournal()
 {
   LOG(("CacheIndex::MergeJournal()"));
 
   AssertOwnsLock();
 
-  mTmpJournal.EnumerateEntries(&CacheIndex::ProcessJournalEntry, this);
+  for (auto iter = mTmpJournal.Iter(); !iter.Done(); iter.Next()) {
+    CacheIndexEntry* entry = iter.Get();
+
+    LOG(("CacheIndex::MergeJournal() [hash=%08x%08x%08x%08x%08x]",
+         LOGSHA1(entry->Hash())));
+
+    CacheIndexEntry* entry2 = mIndex.GetEntry(*entry->Hash());
+
+    CacheIndexEntryAutoManage emng(entry->Hash(), this);
+
+    if (entry->IsRemoved()) {
+      if (entry2) {
+        entry2->MarkRemoved();
+        entry2->MarkDirty();
+      }
+    } else {
+      if (!entry2) {
+        entry2 = mIndex.PutEntry(*entry->Hash());
+      }
+
+      *entry2 = *entry;
+      entry2->MarkDirty();
+    }
+
+    iter.Remove();
+  }
 
   MOZ_ASSERT(mTmpJournal.Count() == 0);
 }
 
-// static
-PLDHashOperator
-CacheIndex::ProcessJournalEntry(CacheIndexEntry *aEntry, void* aClosure)
-{
-  CacheIndex *index = static_cast<CacheIndex *>(aClosure);
-
-  LOG(("CacheIndex::ProcessJournalEntry() [hash=%08x%08x%08x%08x%08x]",
-       LOGSHA1(aEntry->Hash())));
-
-  CacheIndexEntry *entry = index->mIndex.GetEntry(*aEntry->Hash());
-
-  CacheIndexEntryAutoManage emng(aEntry->Hash(), index);
-
-  if (aEntry->IsRemoved()) {
-    if (entry) {
-      entry->MarkRemoved();
-      entry->MarkDirty();
-    }
-  } else {
-    if (!entry) {
-      entry = index->mIndex.PutEntry(*aEntry->Hash());
-    }
-
-    *entry = *aEntry;
-    entry->MarkDirty();
-  }
-
-  return PL_DHASH_REMOVE;
-}
-
 void
 CacheIndex::EnsureNoFreshEntry()
 {
 #ifdef DEBUG_STATS
   CacheIndexStats debugStats;
   debugStats.DisableLogging();
   for (auto iter = mIndex.Iter(); !iter.Done(); iter.Next()) {
     debugStats.BeforeChange(nullptr);
--- a/netwerk/cache2/CacheIndex.h
+++ b/netwerk/cache2/CacheIndex.h
@@ -738,18 +738,16 @@ private:
   // Starts writing of index file.
   void WriteIndexToDisk();
   // Serializes part of mIndex hashtable to the write buffer a writes the buffer
   // to the file.
   void WriteRecords();
   // Finalizes writing process.
   void FinishWrite(bool aSucceeded);
 
-  static PLDHashOperator CopyRecordsToRWBuf(CacheIndexEntry *aEntry,
-                                            void* aClosure);
   static PLDHashOperator ApplyIndexChanges(CacheIndexEntry *aEntry,
                                            void* aClosure);
 
   // Following methods perform writing of the journal during shutdown. All these
   // methods must be called only during shutdown since they write/delete files
   // directly on the main thread instead of using CacheFileIOManager that does
   // it asynchronously on IO thread. Journal contains only entries that are
   // dirty, i.e. changes that are not present in the index file on the disk.
@@ -813,19 +811,16 @@ private:
   // after we finish reading index and before we process pending operations.
   void EnsureNoFreshEntry();
   // In debug build this method is called after processing pending operations
   // to make sure mIndexStats contains correct information.
   void EnsureCorrectStats();
   // Finalizes reading process.
   void FinishRead(bool aSucceeded);
 
-  static PLDHashOperator ProcessJournalEntry(CacheIndexEntry *aEntry,
-                                             void* aClosure);
-
   // Following methods perform updating and building of the index.
   // Timer callback that starts update or build process.
   static void DelayedUpdate(nsITimer *aTimer, void *aClosure);
   // Posts timer event that start update or build process.
   nsresult ScheduleUpdateTimer(uint32_t aDelay);
   nsresult SetupDirectoryEnumerator();
   void InitEntryFromDiskData(CacheIndexEntry *aEntry,
                              CacheFileMetadata *aMetaData,