Bug 1102687 - Avoid copying and allocating 3 times in GetPrefixes. r=dmajor
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Mon, 24 Nov 2014 08:38:29 +0100
changeset 243466 b1bf9bfbfdc8f23f834d3e2a3741d1553e8b9313
parent 243465 86048e13f7d75c58396959651aa5cbffa52896f9
child 243467 24469463b02a38a7625e1944598320ce16a6f238
push id660
push userraliiev@mozilla.com
push dateWed, 18 Feb 2015 20:30:48 +0000
treeherdermozilla-release@49e493494178 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmajor
bugs1102687
milestone36.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 1102687 - Avoid copying and allocating 3 times in GetPrefixes. r=dmajor
toolkit/components/url-classifier/Classifier.cpp
toolkit/components/url-classifier/LookupCache.cpp
toolkit/components/url-classifier/LookupCache.h
toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
toolkit/components/url-classifier/nsUrlClassifierPrefixSet.h
--- a/toolkit/components/url-classifier/Classifier.cpp
+++ b/toolkit/components/url-classifier/Classifier.cpp
@@ -606,18 +606,18 @@ Classifier::ApplyTableUpdates(nsTArray<T
   rv = store->BeginUpdate();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Read the part of the store that is (only) in the cache
   LookupCache *prefixSet = GetLookupCache(store->TableName());
   if (!prefixSet) {
     return NS_ERROR_FAILURE;
   }
-  nsTArray<uint32_t> AddPrefixHashes;
-  rv = prefixSet->GetPrefixes(&AddPrefixHashes);
+  FallibleTArray<uint32_t> AddPrefixHashes;
+  rv = prefixSet->GetPrefixes(AddPrefixHashes);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = store->AugmentAdds(AddPrefixHashes);
   NS_ENSURE_SUCCESS(rv, rv);
   AddPrefixHashes.Clear();
 
   uint32_t applied = 0;
   bool updateFreshness = false;
   bool hasCompletes = false;
@@ -729,18 +729,18 @@ Classifier::ReadNoiseEntries(const Prefi
                              uint32_t aCount,
                              PrefixArray* aNoiseEntries)
 {
   LookupCache *cache = GetLookupCache(aTableName);
   if (!cache) {
     return NS_ERROR_FAILURE;
   }
 
-  nsTArray<uint32_t> prefixes;
-  nsresult rv = cache->GetPrefixes(&prefixes);
+  FallibleTArray<uint32_t> prefixes;
+  nsresult rv = cache->GetPrefixes(prefixes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   size_t idx = prefixes.BinaryIndexOf(aPrefix.ToUint32());
 
   if (idx == nsTArray<uint32_t>::NoIndex) {
     NS_WARNING("Could not find prefix in PrefixSet during noise lookup");
     return NS_ERROR_FAILURE;
   }
--- a/toolkit/components/url-classifier/LookupCache.cpp
+++ b/toolkit/components/url-classifier/LookupCache.cpp
@@ -679,31 +679,21 @@ LookupCache::LoadPrefixSet()
     LOG(("SB tree done, size = %d bytes\n", size));
   }
 #endif
 
   return NS_OK;
 }
 
 nsresult
-LookupCache::GetPrefixes(nsTArray<uint32_t>* aAddPrefixes)
+LookupCache::GetPrefixes(FallibleTArray<uint32_t>& aAddPrefixes)
 {
   if (!mPrimed) {
     // This can happen if its a new table, so no error.
     LOG(("GetPrefixes from empty LookupCache"));
     return NS_OK;
   }
-  uint32_t cnt;
-  uint32_t *arr;
-  nsresult rv = mPrefixSet->GetPrefixes(&cnt, &arr);
-  NS_ENSURE_SUCCESS(rv, rv);
-  bool appendOk = aAddPrefixes->AppendElements(arr, cnt);
-  nsMemory::Free(arr);
-  if (appendOk) {
-    return NS_OK;
-  } else {
-    return NS_ERROR_FAILURE;
-  }
+  return mPrefixSet->GetPrefixesNative(aAddPrefixes);
 }
 
 
 }
 }
--- a/toolkit/components/url-classifier/LookupCache.h
+++ b/toolkit/components/url-classifier/LookupCache.h
@@ -94,17 +94,17 @@ public:
   nsresult Init();
   nsresult Open();
   // The directory handle where we operate will
   // be moved away when a backup is made.
   nsresult UpdateDirHandle(nsIFile* aStoreDirectory);
   // This will Clear() the passed arrays when done.
   nsresult Build(AddPrefixArray& aAddPrefixes,
                  AddCompleteArray& aAddCompletes);
-  nsresult GetPrefixes(nsTArray<uint32_t>* aAddPrefixes);
+  nsresult GetPrefixes(FallibleTArray<uint32_t>& aAddPrefixes);
   void ClearCompleteCache();
 
 #if DEBUG && defined(PR_LOGGING)
   void Dump();
 #endif
   nsresult WriteFile();
   nsresult Has(const Completion& aCompletion,
                bool* aHas, bool* aComplete);
--- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
@@ -135,43 +135,60 @@ nsUrlClassifierPrefixSet::MakePrefixSet(
 
   LOG(("Total number of indices: %d", aLength));
   LOG(("Total number of deltas: %d", totalDeltas));
   LOG(("Total number of delta chunks: %d", mIndexDeltas.Length()));
 
   return NS_OK;
 }
 
+nsresult
+nsUrlClassifierPrefixSet::GetPrefixesNative(FallibleTArray<uint32_t>& outArray)
+{
+  if (!outArray.SetLength(mTotalPrefixes)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  uint32_t prefixIdxLength = mIndexPrefixes.Length();
+  uint32_t prefixCnt = 0;
+
+  for (uint32_t i = 0; i < prefixIdxLength; i++) {
+    uint32_t prefix = mIndexPrefixes[i];
+
+    outArray[prefixCnt++] = prefix;
+    for (uint32_t j = 0; j < mIndexDeltas[i].Length(); j++) {
+      prefix += mIndexDeltas[i][j];
+      outArray[prefixCnt++] = prefix;
+    }
+  }
+
+  NS_ASSERTION(mTotalPrefixes == prefixCnt, "Lengths are inconsistent");
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsUrlClassifierPrefixSet::GetPrefixes(uint32_t* aCount,
                                       uint32_t** aPrefixes)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
   NS_ENSURE_ARG_POINTER(aPrefixes);
   *aPrefixes = nullptr;
 
-  uint64_t itemCount = mTotalPrefixes;
+  FallibleTArray<uint32_t> prefixes;
+  nsresult rv = GetPrefixesNative(prefixes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  uint64_t itemCount = prefixes.Length();
   uint32_t* prefixArray = static_cast<uint32_t*>(nsMemory::Alloc(itemCount * sizeof(uint32_t)));
   NS_ENSURE_TRUE(prefixArray, NS_ERROR_OUT_OF_MEMORY);
 
-  uint32_t prefixIdxLength = mIndexPrefixes.Length();
-  uint32_t prefixCnt = 0;
-
-  for (uint32_t i = 0; i < prefixIdxLength; i++) {
-    uint32_t prefix = mIndexPrefixes[i];
-
-    prefixArray[prefixCnt++] = prefix;
-    for (uint32_t j = 0; j < mIndexDeltas[i].Length(); j++) {
-      prefix += mIndexDeltas[i][j];
-      prefixArray[prefixCnt++] = prefix;
-    }
-  }
-
-  NS_ASSERTION(itemCount == prefixCnt, "Lengths are inconsistent");
+  memcpy(prefixArray, prefixes.Elements(), sizeof(uint32_t) * itemCount);
 
   *aCount = itemCount;
   *aPrefixes = prefixArray;
 
   return NS_OK;
 }
 
 uint32_t nsUrlClassifierPrefixSet::BinSearch(uint32_t start,
--- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.h
+++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.h
@@ -31,16 +31,17 @@ public:
   NS_IMETHOD Init(const nsACString& aName);
   NS_IMETHOD SetPrefixes(const uint32_t* aArray, uint32_t aLength);
   NS_IMETHOD GetPrefixes(uint32_t* aCount, uint32_t** aPrefixes);
   NS_IMETHOD Contains(uint32_t aPrefix, bool* aFound);
   NS_IMETHOD IsEmpty(bool* aEmpty);
   NS_IMETHOD LoadFromFile(nsIFile* aFile);
   NS_IMETHOD StoreToFile(nsIFile* aFile);
 
+  nsresult GetPrefixesNative(FallibleTArray<uint32_t>& outArray);
   size_t SizeInMemory() { return mMemoryInUse; };
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIMEMORYREPORTER
 
 protected:
   virtual ~nsUrlClassifierPrefixSet();