]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7168 don't query Components of CETasks 1 by 1 in TaskFormatter 741/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 28 Jan 2016 10:41:13 +0000 (11:41 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 29 Jan 2016 12:56:54 +0000 (13:56 +0100)
server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskFormatter.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskFormatterTest.java

index a3c9bcc7ce7b2fcc41073591302860fff8f54f90..5913f9acdf3f956b754335dea8e08ade115858cd 100644 (file)
  */
 package org.sonar.server.computation.ws;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
-import java.util.ArrayList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
@@ -34,10 +37,14 @@ import org.sonar.db.DbSession;
 import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeQueueDto;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentDtoFunctions;
 import org.sonar.server.computation.log.CeLogging;
 import org.sonar.server.computation.log.LogFileRef;
 import org.sonarqube.ws.WsCe;
 
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.FluentIterable.from;
+
 /**
  * Converts {@link CeActivityDto} and {@link CeQueueDto} to the protobuf objects
  * used to write WS responses (see ws-ce.proto in module sonar-ws)
@@ -54,20 +61,17 @@ public class TaskFormatter {
     this.system2 = system2;
   }
 
-  public List<WsCe.Task> formatQueue(DbSession dbSession, List<CeQueueDto> dtos) {
-    ComponentCache cache = new ComponentCache(dbSession);
-    List<WsCe.Task> result = new ArrayList<>();
-    for (CeQueueDto dto : dtos) {
-      result.add(formatQueue(dto, cache));
-    }
-    return result;
+  public Iterable<WsCe.Task> formatQueue(DbSession dbSession, List<CeQueueDto> dtos) {
+    ComponentDtoCache cache = new ComponentDtoCache(dbSession, ceQueueDtoToComponentUuids(dtos));
+    return from(dtos)
+      .transform(new CeQueueDtoToTask(cache));
   }
 
   public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto dto) {
-    return formatQueue(dto, new ComponentCache(dbSession));
+    return formatQueue(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()));
   }
 
-  private WsCe.Task formatQueue(CeQueueDto dto, ComponentCache componentCache) {
+  private WsCe.Task formatQueue(CeQueueDto dto, ComponentDtoCache componentDtoCache) {
     WsCe.Task.Builder builder = WsCe.Task.newBuilder();
     builder.setId(dto.getUuid());
     builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
@@ -75,7 +79,7 @@ public class TaskFormatter {
     builder.setLogs(ceLogging.getFile(LogFileRef.from(dto)).isPresent());
     if (dto.getComponentUuid() != null) {
       builder.setComponentId(dto.getComponentUuid());
-      buildComponent(builder, componentCache.get(dto.getComponentUuid()));
+      buildComponent(builder, componentDtoCache.get(dto.getComponentUuid()));
     }
     if (dto.getSubmitterLogin() != null) {
       builder.setSubmitterLogin(dto.getSubmitterLogin());
@@ -93,19 +97,15 @@ public class TaskFormatter {
   }
 
   public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto) {
-    return formatActivity(dto, new ComponentCache(dbSession));
+    return formatActivity(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()));
   }
 
-  public List<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
-    ComponentCache cache = new ComponentCache(dbSession);
-    List<WsCe.Task> result = new ArrayList<>();
-    for (CeActivityDto dto : dtos) {
-      result.add(formatActivity(dto, cache));
-    }
-    return result;
+  public Iterable<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
+    ComponentDtoCache cache = new ComponentDtoCache(dbSession, ceActivityDtoToComponentUuids(dtos));
+    return from(dtos).transform(new CeActivityDtoToTask(cache));
   }
 
-  private WsCe.Task formatActivity(CeActivityDto dto, ComponentCache componentCache) {
+  private WsCe.Task formatActivity(CeActivityDto dto, ComponentDtoCache componentDtoCache) {
     WsCe.Task.Builder builder = WsCe.Task.newBuilder();
     builder.setId(dto.getUuid());
     builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
@@ -113,7 +113,7 @@ public class TaskFormatter {
     builder.setLogs(ceLogging.getFile(LogFileRef.from(dto)).isPresent());
     if (dto.getComponentUuid() != null) {
       builder.setComponentId(dto.getComponentUuid());
-      buildComponent(builder, componentCache.get(dto.getComponentUuid()));
+      buildComponent(builder, componentDtoCache.get(dto.getComponentUuid()));
     }
     if (dto.getSnapshotId() != null) {
       builder.setAnalysisId(String.valueOf(dto.getSnapshotId()));
@@ -142,25 +142,50 @@ public class TaskFormatter {
     }
   }
 
-  private class ComponentCache {
-    private final DbSession dbSession;
-    private final Map<String, ComponentDto> componentsByUuid = new HashMap<>();
+  private static Set<String> ceQueueDtoToComponentUuids(Iterable<CeQueueDto> dtos) {
+    return from(dtos)
+      .transform(new Function<CeQueueDto, String>() {
+        @Override
+        @Nullable
+        public String apply(@Nonnull CeQueueDto input) {
+          return input.getComponentUuid();
+        }
+      })
+      .filter(notNull())
+      .toSet();
+  }
+
+  private static Set<String> ceActivityDtoToComponentUuids(Iterable<CeActivityDto> dtos) {
+    return from(dtos)
+      .transform(new Function<CeActivityDto, String>() {
+        @Override
+        @Nullable
+        public String apply(@Nonnull CeActivityDto input) {
+          return input.getComponentUuid();
+        }
+      })
+      .filter(notNull())
+      .toSet();
+  }
+
+  private class ComponentDtoCache {
+    private final Map<String, ComponentDto> componentsByUuid;
 
-    ComponentCache(DbSession dbSession) {
-      this.dbSession = dbSession;
+    public ComponentDtoCache(DbSession dbSession, Set<String> uuids) {
+      this.componentsByUuid = from(dbClient.componentDao().selectByUuids(dbSession, uuids)).uniqueIndex(ComponentDtoFunctions.toUuid());
+    }
+
+    public ComponentDtoCache(DbSession dbSession, String uuid) {
+      Optional<ComponentDto> componentDto = dbClient.componentDao().selectByUuid(dbSession, uuid);
+      this.componentsByUuid = componentDto.isPresent() ? ImmutableMap.of(uuid, componentDto.get()) : Collections.<String, ComponentDto>emptyMap();
     }
 
     @CheckForNull
-    ComponentDto get(String uuid) {
-      ComponentDto dto = componentsByUuid.get(uuid);
-      if (dto == null) {
-        Optional<ComponentDto> opt = dbClient.componentDao().selectByUuid(dbSession, uuid);
-        if (opt.isPresent()) {
-          dto = opt.get();
-          componentsByUuid.put(uuid, dto);
-        }
+    ComponentDto get(@Nullable String uuid) {
+      if (uuid == null) {
+        return null;
       }
-      return dto;
+      return componentsByUuid.get(uuid);
     }
   }
 
@@ -175,4 +200,32 @@ public class TaskFormatter {
     }
     return system2.now() - startedAt;
   }
+
+  private final class CeActivityDtoToTask implements Function<CeActivityDto, WsCe.Task> {
+    private final ComponentDtoCache cache;
+
+    public CeActivityDtoToTask(ComponentDtoCache cache) {
+      this.cache = cache;
+    }
+
+    @Override
+    @Nonnull
+    public WsCe.Task apply(@Nonnull CeActivityDto input) {
+      return formatActivity(input, cache);
+    }
+  }
+
+  private final class CeQueueDtoToTask implements Function<CeQueueDto, WsCe.Task> {
+    private final ComponentDtoCache cache;
+
+    public CeQueueDtoToTask(ComponentDtoCache cache) {
+      this.cache = cache;
+    }
+
+    @Override
+    @Nonnull
+    public WsCe.Task apply(@Nonnull CeQueueDto input) {
+      return formatQueue(input, cache);
+    }
+  }
 }
index db5b82a67ad3fa6888f3b1191cdaf0fcff1d97c9..15883c853d23494a4ec96cc3bb03c91e560a8f7d 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.server.computation.ws;
 import com.google.common.base.Optional;
 import java.io.IOException;
 import java.util.Date;
-import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -160,7 +159,7 @@ public class TaskFormatterTest {
     dto2.setStatus(CeQueueDto.Status.PENDING);
     dto2.setCreatedAt(1_451_000_000_000L);
 
-    List<WsCe.Task> wsTasks = underTest.formatQueue(db.getSession(), asList(dto1, dto2));
+    Iterable<WsCe.Task> wsTasks = underTest.formatQueue(db.getSession(), asList(dto1, dto2));
     assertThat(wsTasks).extracting("id").containsExactly("UUID1", "UUID2");
   }
 
@@ -195,7 +194,7 @@ public class TaskFormatterTest {
     CeActivityDto dto1 = newActivity("UUID1", "COMPONENT_UUID", CeActivityDto.Status.FAILED);
     CeActivityDto dto2 = newActivity("UUID2", "COMPONENT_UUID", CeActivityDto.Status.SUCCESS);
 
-    List<WsCe.Task> wsTasks = underTest.formatActivity(db.getSession(), asList(dto1, dto2));
+    Iterable<WsCe.Task> wsTasks = underTest.formatActivity(db.getSession(), asList(dto1, dto2));
 
     assertThat(wsTasks).extracting("id").containsExactly("UUID1", "UUID2");
   }