Bug 1186791 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in storage/ with iterators. r=mak.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 29 Oct 2015 16:04:41 -0700
changeset 270384 582ecb12478ae567b439bb5aa01a1ac3b9551e61
parent 270383 dd5adab01830fec1b51918a9626702fea0d454f7
child 270385 15aad0a5b3cb1695bacaf3e4ecb40339cb7a2a1c
push id16025
push userkwierso@gmail.com
push dateSat, 31 Oct 2015 00:00:26 +0000
treeherderfx-team@23a54dcff6ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1186791
milestone45.0a1
Bug 1186791 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in storage/ with iterators. r=mak.
storage/mozStorageBindingParams.cpp
storage/mozStorageBindingParams.h
--- a/storage/mozStorageBindingParams.cpp
+++ b/storage/mozStorageBindingParams.cpp
@@ -150,59 +150,16 @@ BindingParams::unlock(Statement *aOwning
 }
 
 const mozIStorageBindingParamsArray *
 BindingParams::getOwner() const
 {
   return mOwningArray;
 }
 
-PLDHashOperator
-AsyncBindingParams::iterateOverNamedParameters(const nsACString &aName,
-                                               nsIVariant *aValue,
-                                               void *voidClosureThunk)
-{
-  NamedParameterIterationClosureThunk *closureThunk =
-    static_cast<NamedParameterIterationClosureThunk *>(voidClosureThunk);
-
-  // We do not accept any forms of names other than ":name", but we need to add
-  // the colon for SQLite.
-  nsAutoCString name(":");
-  name.Append(aName);
-  int oneIdx = ::sqlite3_bind_parameter_index(closureThunk->statement,
-                                              name.get());
-
-  if (oneIdx == 0) {
-    nsAutoCString errMsg(aName);
-    errMsg.AppendLiteral(" is not a valid named parameter.");
-    closureThunk->err = new Error(SQLITE_RANGE, errMsg.get());
-    return PL_DHASH_STOP;
-  }
-
-  // XPCVariant's AddRef and Release are not thread-safe and so we must not do
-  // anything that would invoke them here on the async thread.  As such we can't
-  // cram aValue into self->mParameters using ReplaceObjectAt so that we can
-  // freeload off of the BindingParams::Bind implementation.
-  int rc = variantToSQLiteT(BindingColumnData(closureThunk->statement,
-                                              oneIdx - 1),
-                            aValue);
-  if (rc != SQLITE_OK) {
-    // We had an error while trying to bind.  Now we need to create an error
-    // object with the right message.  Note that we special case
-    // SQLITE_MISMATCH, but otherwise get the message from SQLite.
-    const char *msg = "Could not covert nsIVariant to SQLite type.";
-    if (rc != SQLITE_MISMATCH)
-      msg = ::sqlite3_errmsg(::sqlite3_db_handle(closureThunk->statement));
-
-    closureThunk->err = new Error(rc, msg);
-    return PL_DHASH_STOP;
-  }
-  return PL_DHASH_NEXT;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 //// nsISupports
 
 NS_IMPL_ISUPPORTS(
   BindingParams
 , mozIStorageBindingParams
 , IStorageBindingParamsInternal
 )
@@ -236,23 +193,54 @@ BindingParams::bind(sqlite3_stmt *aState
 already_AddRefed<mozIStorageError>
 AsyncBindingParams::bind(sqlite3_stmt * aStatement)
 {
   // We should bind by index using the super-class if there is nothing in our
   // hashtable.
   if (!mNamedParameters.Count())
     return BindingParams::bind(aStatement);
 
-  // Enumerate over everyone in the map, propagating them into mParameters if
-  // we can and creating an error immediately when we cannot.
-  NamedParameterIterationClosureThunk closureThunk = {this, aStatement, nullptr};
-  (void)mNamedParameters.EnumerateRead(iterateOverNamedParameters,
-                                       (void *)&closureThunk);
+  nsCOMPtr<mozIStorageError> err;
+
+  for (auto iter = mNamedParameters.Iter(); !iter.Done(); iter.Next()) {
+    const nsACString &key = iter.Key();
+
+    // We do not accept any forms of names other than ":name", but we need to
+    // add the colon for SQLite.
+    nsAutoCString name(":");
+    name.Append(key);
+    int oneIdx = ::sqlite3_bind_parameter_index(aStatement, name.get());
+
+    if (oneIdx == 0) {
+      nsAutoCString errMsg(key);
+      errMsg.AppendLiteral(" is not a valid named parameter.");
+      err = new Error(SQLITE_RANGE, errMsg.get());
+      break;
+    }
 
-  return closureThunk.err.forget();
+    // XPCVariant's AddRef and Release are not thread-safe and so we must not
+    // do anything that would invoke them here on the async thread.  As such we
+    // can't cram aValue into mParameters using ReplaceObjectAt so that
+    // we can freeload off of the BindingParams::Bind implementation.
+    int rc = variantToSQLiteT(BindingColumnData(aStatement, oneIdx - 1),
+                              iter.UserData());
+    if (rc != SQLITE_OK) {
+      // We had an error while trying to bind.  Now we need to create an error
+      // object with the right message.  Note that we special case
+      // SQLITE_MISMATCH, but otherwise get the message from SQLite.
+      const char *msg = "Could not covert nsIVariant to SQLite type.";
+      if (rc != SQLITE_MISMATCH) {
+        msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));
+      }
+      err = new Error(rc, msg);
+      break;
+    }
+  }
+
+  return err.forget();
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 //// mozIStorageBindingParams
 
 NS_IMETHODIMP
 BindingParams::BindByName(const nsACString &aName,
--- a/storage/mozStorageBindingParams.h
+++ b/storage/mozStorageBindingParams.h
@@ -100,25 +100,14 @@ public:
 
   virtual already_AddRefed<mozIStorageError> bind(sqlite3_stmt * aStatement);
 
   explicit AsyncBindingParams(mozIStorageBindingParamsArray *aOwningArray);
   virtual ~AsyncBindingParams() {}
 
 private:
   nsInterfaceHashtable<nsCStringHashKey, nsIVariant> mNamedParameters;
-
-  struct NamedParameterIterationClosureThunk
-  {
-    AsyncBindingParams *self;
-    sqlite3_stmt *statement;
-    nsCOMPtr<mozIStorageError> err;
-  };
-
-  static PLDHashOperator iterateOverNamedParameters(const nsACString &aName,
-                                                    nsIVariant *aValue,
-                                                    void *voidClosureThunk);
 };
 
 } // namespace storage
 } // namespace mozilla
 
 #endif // mozStorageBindingParams_h