From: Sébastien Lesaint Date: Thu, 28 Jan 2016 10:41:13 +0000 (+0100) Subject: SONAR-7168 don't query Components of CETasks 1 by 1 in TaskFormatter X-Git-Tag: 5.4-M11~29 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F741%2Fhead;p=sonarqube.git SONAR-7168 don't query Components of CETasks 1 by 1 in TaskFormatter --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskFormatter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskFormatter.java index a3c9bcc7ce7..5913f9acdf3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskFormatter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskFormatter.java @@ -19,13 +19,16 @@ */ 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 formatQueue(DbSession dbSession, List dtos) { - ComponentCache cache = new ComponentCache(dbSession); - List result = new ArrayList<>(); - for (CeQueueDto dto : dtos) { - result.add(formatQueue(dto, cache)); - } - return result; + public Iterable formatQueue(DbSession dbSession, List 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 formatActivity(DbSession dbSession, List dtos) { - ComponentCache cache = new ComponentCache(dbSession); - List result = new ArrayList<>(); - for (CeActivityDto dto : dtos) { - result.add(formatActivity(dto, cache)); - } - return result; + public Iterable formatActivity(DbSession dbSession, List 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 componentsByUuid = new HashMap<>(); + private static Set ceQueueDtoToComponentUuids(Iterable dtos) { + return from(dtos) + .transform(new Function() { + @Override + @Nullable + public String apply(@Nonnull CeQueueDto input) { + return input.getComponentUuid(); + } + }) + .filter(notNull()) + .toSet(); + } + + private static Set ceActivityDtoToComponentUuids(Iterable dtos) { + return from(dtos) + .transform(new Function() { + @Override + @Nullable + public String apply(@Nonnull CeActivityDto input) { + return input.getComponentUuid(); + } + }) + .filter(notNull()) + .toSet(); + } + + private class ComponentDtoCache { + private final Map componentsByUuid; - ComponentCache(DbSession dbSession) { - this.dbSession = dbSession; + public ComponentDtoCache(DbSession dbSession, Set uuids) { + this.componentsByUuid = from(dbClient.componentDao().selectByUuids(dbSession, uuids)).uniqueIndex(ComponentDtoFunctions.toUuid()); + } + + public ComponentDtoCache(DbSession dbSession, String uuid) { + Optional componentDto = dbClient.componentDao().selectByUuid(dbSession, uuid); + this.componentsByUuid = componentDto.isPresent() ? ImmutableMap.of(uuid, componentDto.get()) : Collections.emptyMap(); } @CheckForNull - ComponentDto get(String uuid) { - ComponentDto dto = componentsByUuid.get(uuid); - if (dto == null) { - Optional 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 { + 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 { + private final ComponentDtoCache cache; + + public CeQueueDtoToTask(ComponentDtoCache cache) { + this.cache = cache; + } + + @Override + @Nonnull + public WsCe.Task apply(@Nonnull CeQueueDto input) { + return formatQueue(input, cache); + } + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskFormatterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskFormatterTest.java index db5b82a67ad..15883c853d2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskFormatterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskFormatterTest.java @@ -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 wsTasks = underTest.formatQueue(db.getSession(), asList(dto1, dto2)); + Iterable 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 wsTasks = underTest.formatActivity(db.getSession(), asList(dto1, dto2)); + Iterable wsTasks = underTest.formatActivity(db.getSession(), asList(dto1, dto2)); assertThat(wsTasks).extracting("id").containsExactly("UUID1", "UUID2"); }