Keep queued tasks to persist in a Set and not a List

No point in persisting duplicates.

Change-Id: Iadc559df3ebfd0a92f562709f95634879bae160e
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
index 720cec1..4a378c7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
@@ -18,7 +18,7 @@
 import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType.SCC;
 import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType.SCS;
 
-import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.Project.NameKey;
@@ -29,8 +29,8 @@
 import com.google.gerrit.server.util.time.TimeUtil;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledFuture;
 
@@ -106,7 +106,7 @@
   }
 
   public void shutDown() {
-    List<ParsingQueueTask> tasks = Lists.newArrayListWithCapacity(pending.size());
+    Set<ParsingQueueTask> tasks = Sets.newHashSet();
     for (Map.Entry<EventParsingWorker, ScheduledFuture<?>> e : pending.entrySet()) {
       e.getValue().cancel(true);
       tasks.add(e.getKey().task);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistence.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistence.java
index b62206b..2852d4d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistence.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistence.java
@@ -26,7 +26,9 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 public class ParsingQueuePersistence {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -42,7 +44,7 @@
     this.persistenceFile = pluginDataDir.resolve(PERSISTED_FILE_NAME);
   }
 
-  public void persist(List<ParsingQueueTask> tasks) {
+  public void persist(Set<ParsingQueueTask> tasks) {
     try {
       if (Files.isRegularFile(persistenceFile)) {
         Files.delete(persistenceFile);
@@ -59,14 +61,14 @@
     }
   }
 
-  public List<ParsingQueueTask> getPersistedTasks() {
-    List<ParsingQueueTask> persistedTasks = null;
+  public Collection<ParsingQueueTask> getPersistedTasks() {
+    Set<ParsingQueueTask> persistedTasks = null;
     try {
       if (Files.isRegularFile(persistenceFile)) {
         persistedTasks =
             GSON.fromJson(
                 Files.newBufferedReader(persistenceFile, UTF_8),
-                new TypeToken<List<ParsingQueueTask>>() {
+                new TypeToken<Set<ParsingQueueTask>>() {
 
                   private static final long serialVersionUID = 1L;
                 }.getType());
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueueIT.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueueIT.java
index ec9e0c5..dc39eff 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueueIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueueIT.java
@@ -22,7 +22,7 @@
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.ArtifactEventKey;
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.CompositionDefinedEventKey;
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType;
-import java.util.List;
+import java.util.Set;
 import org.eclipse.jgit.lib.Constants;
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +47,7 @@
   @Test
   public void persistedScsFromBranchIsScheduledAndPushed() throws Exception {
     queuePersistence.persist(
-        List.of(ParsingQueueTask.builder(EiffelEventType.SCS, project.get(), getHead()).build()));
+        Set.of(ParsingQueueTask.builder(EiffelEventType.SCS, project.get(), getHead()).build()));
     parsingQueue.init();
     assertCorrectEvent(0, eventForHead(EiffelEventType.SCC));
     assertCorrectEvent(1, eventForHead(EiffelEventType.SCS));
@@ -59,7 +59,7 @@
     PushOneCommit.Result res = createChange();
     merge(res);
     queuePersistence.persist(
-        List.of(
+        Set.of(
             ParsingQueueTask.builder(EiffelEventType.SCS, project.get(), "refs/heads/master")
                 .commit(res.getCommit().name())
                 .build()));
@@ -73,7 +73,7 @@
     setScsHandled();
     PushOneCommit.Result res = createChange();
     queuePersistence.persist(
-        List.of(
+        Set.of(
             ParsingQueueTask.builder(EiffelEventType.SCC, project.get(), "refs/heads/master")
                 .commit(res.getCommit().name())
                 .build()));
@@ -87,7 +87,7 @@
     PushOneCommit.Result res = createChange();
     merge(res);
     queuePersistence.persist(
-        List.of(
+        Set.of(
             ParsingQueueTask.builder(EiffelEventType.SCS, project.get(), "refs/heads/master")
                 .build()));
     parsingQueue.init();
@@ -103,7 +103,7 @@
     CompositionDefinedEventKey cd =
         CompositionDefinedEventKey.create(tagCompositionName(project.get(), "localhost"), tag);
     queuePersistence.persist(
-        List.of(
+        Set.of(
             ParsingQueueTask.builder(EiffelEventType.ARTC, project.get(), tag)
                 .updateTime(EPOCH_MILLIS)
                 .force(false)
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistenceIT.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistenceIT.java
index 7fa9bb5..c0f1457 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistenceIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/ParsingQueuePersistenceIT.java
@@ -14,7 +14,6 @@
 package com.googlesource.gerrit.plugins.eventseiffel.parsing;
 
 import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
 
 import autovaluegson.factory.shaded.com.google.common.collect.Lists;
 import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
@@ -29,6 +28,7 @@
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Delayed;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledFuture;
@@ -57,28 +57,25 @@
 
   @Test
   public void tasksArePersisted() throws Exception {
-    List<ParsingQueueTask> original = createTasks(1, 5);
+    Set<ParsingQueueTask> original = createTasks(1, 5);
     queuePersistence.persist(original);
-    List<ParsingQueueTask> deserialized = queuePersistence.getPersistedTasks();
-    assertEquals(original, deserialized);
+    assertThat(queuePersistence.getPersistedTasks()).containsExactlyElementsIn(original);
   }
 
   @Test
   public void multiplePersistenceRuns() throws Exception {
-    List<ParsingQueueTask> original = createTasks(1, 6);
+    Set<ParsingQueueTask> original = createTasks(1, 6);
     queuePersistence.persist(original);
-    List<ParsingQueueTask> deserialized = queuePersistence.getPersistedTasks();
-    assertEquals(original, deserialized);
+    assertThat(queuePersistence.getPersistedTasks()).containsExactlyElementsIn(original);
 
     original = createTasks(6, 10);
     queuePersistence.persist(original);
-    deserialized = queuePersistence.getPersistedTasks();
-    assertEquals(original, deserialized);
+    assertThat(queuePersistence.getPersistedTasks()).containsExactlyElementsIn(original);
   }
 
   @Test
   public void persistedTasksAreScheduledOnInit() throws Exception {
-    List<ParsingQueueTask> tasks = createTasks(1, 6);
+    Set<ParsingQueueTask> tasks = createTasks(1, 6);
     queuePersistence.persist(tasks);
     parsingQueue.init();
     assertThat(
@@ -89,10 +86,10 @@
             tasks.stream().map(t -> Project.nameKey(t.repoName)).collect(Collectors.toList()));
   }
 
-  private List<ParsingQueueTask> createTasks(int start, int end) {
+  private Set<ParsingQueueTask> createTasks(int start, int end) {
     return IntStream.range(start, end)
         .mapToObj(ParsingQueuePersistenceIT::createTask)
-        .collect(Collectors.toList());
+        .collect(Collectors.toSet());
   }
 
   public static ParsingQueueTask createTask(int id) {