Bug 1160703 (Part 2) - Store an ImageURL pointer instead of a URI spec string in ImageCacheKey. r=baku
authorSeth Fowler <mark.seth.fowler@gmail.com>
Wed, 20 May 2015 10:21:11 -0700
changeset 264508 0c1b8244dcb085137418034cd622d52400344e31
parent 264507 da24d90ca18780c51e061fdf4109f636e7152f88
child 264509 74c9d2746692326a6f5746d91534ec5f3ddac480
push idunknown
push userunknown
push dateunknown
reviewersbaku
bugs1160703
milestone41.0a1
Bug 1160703 (Part 2) - Store an ImageURL pointer instead of a URI spec string in ImageCacheKey. r=baku
image/ImageCacheKey.cpp
image/ImageCacheKey.h
image/ImageURL.h
--- a/image/ImageCacheKey.cpp
+++ b/image/ImageCacheKey.cpp
@@ -13,58 +13,66 @@
 
 namespace mozilla {
 
 using namespace dom;
 
 namespace image {
 
 ImageCacheKey::ImageCacheKey(nsIURI* aURI)
+  : mURI(new ImageURL(aURI))
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aURI);
+  MOZ_ASSERT(mURI);
 
   bool isChrome;
   mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
 
-  aURI->GetSpec(mSpec);
-  mHash = ComputeHash(mSpec);
+  mHash = ComputeHash(mURI);
 }
 
 ImageCacheKey::ImageCacheKey(ImageURL* aURI)
+  : mURI(aURI)
 {
-  MOZ_ASSERT(aURI);
+  MOZ_ASSERT(mURI);
 
   bool isChrome;
   mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
 
-  aURI->GetSpec(mSpec);
-  mHash = ComputeHash(mSpec);
+  mHash = ComputeHash(mURI);
 }
 
 ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
-  : mSpec(aOther.mSpec)
+  : mURI(aOther.mURI)
   , mHash(aOther.mHash)
   , mIsChrome(aOther.mIsChrome)
 { }
 
 ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
-  : mSpec(Move(aOther.mSpec))
+  : mURI(Move(aOther.mURI))
   , mHash(aOther.mHash)
   , mIsChrome(aOther.mIsChrome)
 { }
 
 bool
 ImageCacheKey::operator==(const ImageCacheKey& aOther) const
 {
-  return mSpec == aOther.mSpec;
+  return *mURI == *aOther.mURI;
+}
+
+const char*
+ImageCacheKey::Spec() const
+{
+  return mURI->Spec();
 }
 
 /* static */ uint32_t
-ImageCacheKey::ComputeHash(const nsACString& aSpec)
+ImageCacheKey::ComputeHash(ImageURL* aURI)
 {
   // Since we frequently call Hash() several times in a row on the same
   // ImageCacheKey, as an optimization we compute our hash once and store it.
-  return HashString(aSpec);
+  nsAutoCString spec;
+  aURI->GetSpec(spec);
+  return HashString(spec);
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/ImageCacheKey.h
+++ b/image/ImageCacheKey.h
@@ -31,25 +31,25 @@ public:
 
   ImageCacheKey(const ImageCacheKey& aOther);
   ImageCacheKey(ImageCacheKey&& aOther);
 
   bool operator==(const ImageCacheKey& aOther) const;
   uint32_t Hash() const { return mHash; }
 
   /// A weak pointer to the URI spec for this cache entry. For logging only.
-  const char* Spec() const { return mSpec.get(); }
+  const char* Spec() const;
 
   /// Is this cache entry for a chrome image?
   bool IsChrome() const { return mIsChrome; }
 
 private:
-  static uint32_t ComputeHash(const nsACString& aSpec);
+  static uint32_t ComputeHash(ImageURL* aURI);
 
-  nsCString mSpec;
+  nsRefPtr<ImageURL> mURI;
   uint32_t mHash;
   bool mIsChrome;
 };
 
 } // namespace image
 } // namespace mozilla
 
 #endif // mozilla_image_src_ImageCacheKey_h
--- a/image/ImageURL.h
+++ b/image/ImageURL.h
@@ -39,16 +39,19 @@ public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageURL)
 
   nsresult GetSpec(nsACString& result)
   {
     result = mSpec;
     return NS_OK;
   }
 
+  /// A weak pointer to the URI spec for this ImageURL. For logging only.
+  const char* Spec() const { return mSpec.get(); }
+
   nsresult GetScheme(nsACString& result)
   {
     result = mScheme;
     return NS_OK;
   }
 
   nsresult SchemeIs(const char* scheme, bool* result)
   {
@@ -69,16 +72,23 @@ public:
   {
     MOZ_ASSERT(NS_IsMainThread(),
                "Convert to nsIURI on main thread only; it is not threadsafe.");
     nsCOMPtr<nsIURI> newURI;
     NS_NewURI(getter_AddRefs(newURI), mSpec);
     return newURI.forget();
   }
 
+  bool operator==(const ImageURL& aOther) const
+  {
+    // Note that we don't need to consider mScheme and mRef, because they're
+    // already represented in mSpec.
+    return mSpec == aOther.mSpec;
+  }
+
 private:
   // Since this is a basic storage class, no duplication of spec parsing is
   // included in the functionality. Instead, the class depends upon the
   // parsing implementation in the nsIURI class used in object construction.
   // This means each field is stored separately, but since only a few are
   // required, this small memory tradeoff for threadsafe usage should be ok.
   nsAutoCString mSpec;
   nsAutoCString mScheme;