ExternalIdCacheImpl: Simplify removal of external IDs

Change-Id: I78047f5b895197db215d2ab6cd2845cb850ddb35
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
index 8e7a12e..c94f043 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
@@ -18,6 +18,7 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Module;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Set;
 import org.eclipse.jgit.lib.ObjectId;
 
@@ -33,42 +34,42 @@
   }
 
   @Override
-  public void onCreate(ObjectId newNotesRev, Iterable<ExternalId> extId) {}
+  public void onCreate(ObjectId newNotesRev, Collection<ExternalId> extId) {}
 
   @Override
-  public void onUpdate(ObjectId newNotesRev, Iterable<ExternalId> extId) {}
+  public void onUpdate(ObjectId newNotesRev, Collection<ExternalId> extId) {}
 
   @Override
   public void onReplace(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId> toRemove,
-      Iterable<ExternalId> toAdd) {}
+      Collection<ExternalId> toRemove,
+      Collection<ExternalId> toAdd) {}
 
   @Override
   public void onReplaceByKeys(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId.Key> toRemove,
-      Iterable<ExternalId> toAdd) {}
+      Collection<ExternalId.Key> toRemove,
+      Collection<ExternalId> toAdd) {}
 
   @Override
   public void onReplaceByKeys(
-      ObjectId newNotesRev, Iterable<ExternalId.Key> toRemove, Iterable<ExternalId> toAdd) {}
+      ObjectId newNotesRev, Collection<ExternalId.Key> toRemove, Collection<ExternalId> toAdd) {}
 
   @Override
   public void onReplace(
-      ObjectId newNotesRev, Iterable<ExternalId> toRemove, Iterable<ExternalId> toAdd) {}
+      ObjectId newNotesRev, Collection<ExternalId> toRemove, Collection<ExternalId> toAdd) {}
 
   @Override
-  public void onRemove(ObjectId newNotesRev, Iterable<ExternalId> extId) {}
+  public void onRemove(ObjectId newNotesRev, Collection<ExternalId> extId) {}
 
   @Override
   public void onRemoveByKeys(
-      ObjectId newNotesRev, Account.Id accountId, Iterable<ExternalId.Key> extIdKeys) {}
+      ObjectId newNotesRev, Account.Id accountId, Collection<ExternalId.Key> extIdKeys) {}
 
   @Override
-  public void onRemoveByKeys(ObjectId newNotesRev, Iterable<ExternalId.Key> extIdKeys) {}
+  public void onRemoveByKeys(ObjectId newNotesRev, Collection<ExternalId.Key> extIdKeys) {}
 
   @Override
   public Set<ExternalId> byAccount(Account.Id accountId) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
index ac2c279..f38ae98 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
@@ -16,44 +16,47 @@
 
 import com.google.gerrit.reviewdb.client.Account;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
 import org.eclipse.jgit.lib.ObjectId;
 
 /** Caches external IDs of all accounts */
 interface ExternalIdCache {
-  void onCreate(ObjectId newNotesRev, Iterable<ExternalId> extId) throws IOException;
+  void onCreate(ObjectId newNotesRev, Collection<ExternalId> extId) throws IOException;
 
-  void onUpdate(ObjectId newNotesRev, Iterable<ExternalId> extId) throws IOException;
+  void onUpdate(ObjectId newNotesRev, Collection<ExternalId> extId) throws IOException;
 
   void onReplace(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId> toRemove,
-      Iterable<ExternalId> toAdd)
+      Collection<ExternalId> toRemove,
+      Collection<ExternalId> toAdd)
       throws IOException;
 
   void onReplaceByKeys(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId.Key> toRemove,
-      Iterable<ExternalId> toAdd)
+      Collection<ExternalId.Key> toRemove,
+      Collection<ExternalId> toAdd)
       throws IOException;
 
   void onReplaceByKeys(
-      ObjectId newNotesRev, Iterable<ExternalId.Key> toRemove, Iterable<ExternalId> toAdd)
+      ObjectId newNotesRev, Collection<ExternalId.Key> toRemove, Collection<ExternalId> toAdd)
       throws IOException;
 
-  void onReplace(ObjectId newNotesRev, Iterable<ExternalId> toRemove, Iterable<ExternalId> toAdd)
+  void onReplace(
+      ObjectId newNotesRev, Collection<ExternalId> toRemove, Collection<ExternalId> toAdd)
       throws IOException;
 
-  void onRemove(ObjectId newNotesRev, Iterable<ExternalId> extId) throws IOException;
+  void onRemove(ObjectId newNotesRev, Collection<ExternalId> extId) throws IOException;
 
   void onRemoveByKeys(
-      ObjectId newNotesRev, Account.Id accountId, Iterable<ExternalId.Key> extIdKeys)
+      ObjectId newNotesRev, Account.Id accountId, Collection<ExternalId.Key> extIdKeys)
       throws IOException;
 
-  void onRemoveByKeys(ObjectId newNotesRev, Iterable<ExternalId.Key> extIdKeys) throws IOException;
+  void onRemoveByKeys(ObjectId newNotesRev, Collection<ExternalId.Key> extIdKeys)
+      throws IOException;
 
   Set<ExternalId> byAccount(Account.Id accountId) throws IOException;
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
index 6713021..d0fa2d4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
@@ -18,6 +18,7 @@
 
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.ListMultimap;
@@ -28,6 +29,7 @@
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.locks.Lock;
@@ -60,7 +62,7 @@
   }
 
   @Override
-  public void onCreate(ObjectId newNotesRev, Iterable<ExternalId> extIds) throws IOException {
+  public void onCreate(ObjectId newNotesRev, Collection<ExternalId> extIds) throws IOException {
     updateCache(
         newNotesRev,
         m -> {
@@ -71,7 +73,7 @@
   }
 
   @Override
-  public void onRemove(ObjectId newNotesRev, Iterable<ExternalId> extIds) throws IOException {
+  public void onRemove(ObjectId newNotesRev, Collection<ExternalId> extIds) throws IOException {
     updateCache(
         newNotesRev,
         m -> {
@@ -83,52 +85,25 @@
 
   @Override
   public void onRemoveByKeys(
-      ObjectId newNotesRev, Account.Id accountId, Iterable<ExternalId.Key> extIdKeys)
+      ObjectId newNotesRev, Account.Id accountId, Collection<ExternalId.Key> extIdKeys)
       throws IOException {
-    updateCache(
-        newNotesRev,
-        m -> {
-          for (ExternalId extId : m.get(accountId)) {
-            for (ExternalId.Key extIdKey : extIdKeys) {
-              if (extIdKey.equals(extId.key())) {
-                m.remove(accountId, extId);
-                break;
-              }
-            }
-          }
-        });
+    updateCache(newNotesRev, m -> removeKeys(m.get(accountId), extIdKeys));
   }
 
   @Override
-  public void onRemoveByKeys(ObjectId newNotesRev, Iterable<ExternalId.Key> extIdKeys)
+  public void onRemoveByKeys(ObjectId newNotesRev, Collection<ExternalId.Key> extIdKeys)
       throws IOException {
-    updateCache(
-        newNotesRev,
-        m -> {
-          for (ExternalId extId : m.values()) {
-            for (ExternalId.Key extIdKey : extIdKeys) {
-              if (extIdKey.equals(extId.key())) {
-                m.remove(extId.accountId(), extId);
-                break;
-              }
-            }
-          }
-        });
+    updateCache(newNotesRev, m -> removeKeys(m.values(), extIdKeys));
   }
 
   @Override
-  public void onUpdate(ObjectId newNotesRev, Iterable<ExternalId> updatedExtIds)
+  public void onUpdate(ObjectId newNotesRev, Collection<ExternalId> updatedExtIds)
       throws IOException {
     updateCache(
         newNotesRev,
         m -> {
+          removeKeys(m.values(), updatedExtIds.stream().map(e -> e.key()).collect(toSet()));
           for (ExternalId updatedExtId : updatedExtIds) {
-            for (ExternalId extId : m.get(updatedExtId.accountId())) {
-              if (updatedExtId.key().equals(extId.key())) {
-                m.remove(updatedExtId.accountId(), extId);
-                break;
-              }
-            }
             m.put(updatedExtId.accountId(), updatedExtId);
           }
         });
@@ -138,8 +113,8 @@
   public void onReplace(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId> toRemove,
-      Iterable<ExternalId> toAdd)
+      Collection<ExternalId> toRemove,
+      Collection<ExternalId> toAdd)
       throws IOException {
     ExternalIdsUpdate.checkSameAccount(Iterables.concat(toRemove, toAdd), accountId);
 
@@ -159,21 +134,15 @@
   public void onReplaceByKeys(
       ObjectId newNotesRev,
       Account.Id accountId,
-      Iterable<ExternalId.Key> toRemove,
-      Iterable<ExternalId> toAdd)
+      Collection<ExternalId.Key> toRemove,
+      Collection<ExternalId> toAdd)
       throws IOException {
     ExternalIdsUpdate.checkSameAccount(toAdd, accountId);
 
     updateCache(
         newNotesRev,
         m -> {
-          for (ExternalId extId : m.get(accountId)) {
-            for (ExternalId.Key extIdKey : toRemove) {
-              if (extIdKey.equals(extId.key())) {
-                m.remove(accountId, extId);
-              }
-            }
-          }
+          removeKeys(m.get(accountId), toRemove);
           for (ExternalId extId : toAdd) {
             m.put(extId.accountId(), extId);
           }
@@ -182,18 +151,12 @@
 
   @Override
   public void onReplaceByKeys(
-      ObjectId newNotesRev, Iterable<ExternalId.Key> toRemove, Iterable<ExternalId> toAdd)
+      ObjectId newNotesRev, Collection<ExternalId.Key> toRemove, Collection<ExternalId> toAdd)
       throws IOException {
     updateCache(
         newNotesRev,
         m -> {
-          for (ExternalId extId : m.values()) {
-            for (ExternalId.Key extIdKey : toRemove) {
-              if (extIdKey.equals(extId.key())) {
-                m.remove(extId.accountId(), extId);
-              }
-            }
-          }
+          removeKeys(m.values(), toRemove);
           for (ExternalId extId : toAdd) {
             m.put(extId.accountId(), extId);
           }
@@ -202,7 +165,7 @@
 
   @Override
   public void onReplace(
-      ObjectId newNotesRev, Iterable<ExternalId> toRemove, Iterable<ExternalId> toAdd)
+      ObjectId newNotesRev, Collection<ExternalId> toRemove, Collection<ExternalId> toAdd)
       throws IOException {
     updateCache(
         newNotesRev,
@@ -256,6 +219,10 @@
     }
   }
 
+  private static void removeKeys(Collection<ExternalId> ids, Collection<ExternalId.Key> toRemove) {
+    Collections2.transform(ids, e -> e.key()).removeAll(toRemove);
+  }
+
   static class Loader extends CacheLoader<ObjectId, ImmutableSetMultimap<Account.Id, ExternalId>> {
     private final ExternalIdReader externalIdReader;