Bug 1359299 - Copy gethash cache when update. r?hchang draft
authorDimiL <dlee@mozilla.com>
Mon, 15 May 2017 16:31:54 +0800
changeset 577736 d8b701b13e3a20aed48e02eb99ae84c97ad84288
parent 577612 af08df05137f8d1bd51f7cf71612d9b29d081868
child 628570 24aa5f5fbd32fe1bf6b4b7551b97f1674e3d3356
push id58766
push userbmo:dlee@mozilla.com
push dateMon, 15 May 2017 09:18:50 +0000
reviewershchang
bugs1359299
milestone55.0a1
Bug 1359299 - Copy gethash cache when update. r?hchang After adopting the new thread model for safebrowsing, we will create a new lookup cache for update so we can still check lookup cache at the same time. Prefix set, completions will be generated when we open the new lookup cache but it won't include cache, so we will loss cache after that. This patch will copy cache data from old lookup cache to new lookup cache while update. MozReview-Commit-ID: GnsAsfYXwVx
toolkit/components/url-classifier/Classifier.cpp
toolkit/components/url-classifier/Classifier.h
toolkit/components/url-classifier/Entries.h
toolkit/components/url-classifier/LookupCache.h
toolkit/components/url-classifier/LookupCacheV4.cpp
--- a/toolkit/components/url-classifier/Classifier.cpp
+++ b/toolkit/components/url-classifier/Classifier.cpp
@@ -621,16 +621,32 @@ Classifier::RemoveUpdateIntermediaries()
     // If the directory is locked from removal for some reason,
     // we will fail here and it doesn't matter until the next
     // update. (the next udpate will fail due to the removable
     // "safebrowsing-udpating" directory.)
     LOG(("Failed to remove updating directory."));
   }
 }
 
+#define DLOG(args) printf_stderr args
+
+void
+Classifier::CopyOldLookupCacheToUpdate(LookupCache* aUpdateLookupCache)
+{
+  MOZ_ASSERT(aUpdateLookupCache);
+
+  for (auto c: mLookupCaches) {
+    if (c->TableName() == aUpdateLookupCache->TableName()) {
+      DLOG(("[Dimi]CopyLookupCache table name = %s\n", c->TableName().get()));
+      *aUpdateLookupCache = *c;
+      return;
+    }
+  }
+}
+
 void
 Classifier::MergeNewLookupCaches()
 {
   MOZ_ASSERT(NS_GetCurrentThread() != mUpdateThread,
              "MergeNewLookupCaches cannot be called on update thread "
              "since it mutates mLookupCaches which is only safe on "
              "worker thread.");
 
@@ -1148,16 +1164,17 @@ Classifier::CheckValidUpdate(nsTArray<Ta
   // (common case)
   uint32_t validupdates = 0;
 
   for (uint32_t i = 0; i < aUpdates->Length(); i++) {
     TableUpdate *update = aUpdates->ElementAt(i);
     if (!update || !update->TableName().Equals(aTable))
       continue;
     if (update->Empty()) {
+      LOG(("[Dimi]Check valid update is empty\n"));
       aUpdates->ElementAt(i) = nullptr;
       continue;
     }
     validupdates++;
   }
 
   if (!validupdates) {
     // This can happen if the update was only valid for one table.
@@ -1441,16 +1458,21 @@ Classifier::GetLookupCache(const nsACStr
   UniquePtr<LookupCache> cache;
   nsCString provider = GetProvider(aTable);
   if (StringEndsWith(aTable, NS_LITERAL_CSTRING("-proto"))) {
     cache = MakeUnique<LookupCacheV4>(aTable, provider, rootStoreDirectory);
   } else {
     cache = MakeUnique<LookupCacheV2>(aTable, provider, rootStoreDirectory);
   }
 
+  if (aForUpdate) {
+    DLOG(("[Dimi]CopyLookupCache...\n"));
+    CopyOldLookupCacheToUpdate(cache.get());
+  }
+
   nsresult rv = cache->Init();
   if (NS_FAILED(rv)) {
     return nullptr;
   }
   rv = cache->Open();
   if (NS_SUCCEEDED(rv)) {
     lookupCaches.AppendElement(cache.get());
     return cache.release();
--- a/toolkit/components/url-classifier/Classifier.h
+++ b/toolkit/components/url-classifier/Classifier.h
@@ -132,16 +132,18 @@ private:
   nsresult SetupPathNames();
   nsresult RecoverBackups();
   nsresult CleanToDelete();
   nsresult CopyInUseDirForUpdate();
   nsresult RegenActiveTables();
 
   void MergeNewLookupCaches(); // Merge mNewLookupCaches into mLookupCaches.
 
+  void CopyOldLookupCacheToUpdate(LookupCache* aUpdateLookupCache);
+
   // Remove any intermediary for update, including in-memory
   // and on-disk data.
   void RemoveUpdateIntermediaries();
 
 #ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
   already_AddRefed<nsIFile> GetFailedUpdateDirectroy();
   nsresult DumpFailedUpdate();
 #endif
--- a/toolkit/components/url-classifier/Entries.h
+++ b/toolkit/components/url-classifier/Entries.h
@@ -351,12 +351,24 @@ struct CachedFullHashResponse {
       }
     }
     return true;
   }
 };
 
 typedef nsClassHashtable<nsUint32HashKey, CachedFullHashResponse> FullHashResponseMap;
 
+template<class T>
+void
+CopyClassHashTable(const T& aSource, T& aDestination)
+{
+  aDestination.Clear();
+
+  for (auto iter = aSource.ConstIter(); !iter.Done(); iter.Next()) {
+    auto value = aDestination.LookupOrAdd(iter.Key());
+    *value = *(iter.Data());
+  }
+}
+
 } // namespace safebrowsing
 } // namespace mozilla
 
 #endif // SBEntries_h__
--- a/toolkit/components/url-classifier/LookupCache.h
+++ b/toolkit/components/url-classifier/LookupCache.h
@@ -221,16 +221,21 @@ public:
 
   virtual void ClearAll();
 
   template<typename T>
   static T* Cast(LookupCache* aThat) {
     return ((aThat && T::VER == aThat->Ver()) ? reinterpret_cast<T*>(aThat) : nullptr);
   }
 
+  LookupCache& operator=(const LookupCache& aOther) {
+    CopyClassHashTable<FullHashResponseMap>(aOther.mCache, mCache);
+    return *this;
+  }
+
 private:
   nsresult LoadPrefixSet();
 
   virtual nsresult StoreToFile(nsIFile* aFile) = 0;
   virtual nsresult LoadFromFile(nsIFile* aFile) = 0;
   virtual size_t SizeOfPrefixSet() = 0;
 
   virtual int Ver() const = 0;
--- a/toolkit/components/url-classifier/LookupCacheV4.cpp
+++ b/toolkit/components/url-classifier/LookupCacheV4.cpp
@@ -325,20 +325,17 @@ LookupCacheV4::ApplyUpdate(TableUpdateV4
   }
 
   return NS_OK;
 }
 
 nsresult
 LookupCacheV4::AddFullHashResponseToCache(const FullHashResponseMap& aResponseMap)
 {
-  for (auto iter = aResponseMap.ConstIter(); !iter.Done(); iter.Next()) {
-    CachedFullHashResponse* response = mCache.LookupOrAdd(iter.Key());
-    *response = *(iter.Data());
-  }
+  CopyClassHashTable<FullHashResponseMap>(aResponseMap, mCache);
 
   return NS_OK;
 }
 
 nsresult
 LookupCacheV4::InitCrypto(nsCOMPtr<nsICryptoHash>& aCrypto)
 {
   nsresult rv;