001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.batch.profiling;
021
022 import com.google.common.collect.Maps;
023 import org.sonar.api.resources.Project;
024 import org.sonar.api.utils.System2;
025 import org.sonar.batch.phases.Phases;
026 import org.sonar.batch.phases.Phases.Phase;
027
028 import javax.annotation.Nullable;
029
030 import java.util.HashMap;
031 import java.util.LinkedHashMap;
032 import java.util.Map;
033 import java.util.Map.Entry;
034
035 public class ModuleProfiling extends AbstractTimeProfiling {
036
037 private Map<Phases.Phase, PhaseProfiling> profilingPerPhase = new HashMap<Phases.Phase, PhaseProfiling>();
038 private Map<String, ItemProfiling> profilingPerBatchStep = new LinkedHashMap<String, ItemProfiling>();
039 private final Project module;
040
041 public ModuleProfiling(@Nullable Project module, System2 system) {
042 super(system);
043 this.module = module;
044 }
045
046 public String moduleName() {
047 if (module != null) {
048 return module.getName();
049 }
050 return null;
051 }
052
053 public PhaseProfiling getProfilingPerPhase(Phase phase) {
054 return profilingPerPhase.get(phase);
055 }
056
057 public ItemProfiling getProfilingPerBatchStep(String stepName) {
058 return profilingPerBatchStep.get(stepName);
059 }
060
061 public void addPhaseProfiling(Phase phase) {
062 profilingPerPhase.put(phase, PhaseProfiling.create(system(), phase));
063 }
064
065 public void addBatchStepProfiling(String stepName) {
066 profilingPerBatchStep.put(stepName, new ItemProfiling(system(), stepName));
067 }
068
069 public void dump() {
070 double percent = this.totalTime() / 100.0;
071 Map<Object, AbstractTimeProfiling> categories = Maps.newLinkedHashMap();
072 categories.putAll(profilingPerPhase);
073 categories.putAll(profilingPerBatchStep);
074
075 for (Map.Entry<Object, AbstractTimeProfiling> batchStep : sortByDescendingTotalTime(categories).entrySet()) {
076 println(" * " + batchStep.getKey() + " execution time: ", percent, batchStep.getValue());
077 }
078 // Breakdown per phase
079 for (Phase phase : Phases.Phase.values()) {
080 if (profilingPerPhase.containsKey(phase) && getProfilingPerPhase(phase).hasItems()) {
081 println("");
082 println(" * " + phase + " execution time breakdown: ", getProfilingPerPhase(phase));
083 getProfilingPerPhase(phase).dump();
084 }
085 }
086 }
087
088 public void merge(ModuleProfiling other) {
089 super.add(other);
090 for (Entry<Phases.Phase, PhaseProfiling> entry : other.profilingPerPhase.entrySet()) {
091 if (!this.profilingPerPhase.containsKey(entry.getKey())) {
092 this.addPhaseProfiling(entry.getKey());
093 }
094 this.getProfilingPerPhase(entry.getKey()).merge(entry.getValue());
095 }
096 for (Map.Entry<String, ItemProfiling> entry : other.profilingPerBatchStep.entrySet()) {
097 if (!this.profilingPerBatchStep.containsKey(entry.getKey())) {
098 profilingPerBatchStep.put(entry.getKey(), new ItemProfiling(system(), entry.getKey()));
099 }
100 this.getProfilingPerBatchStep(entry.getKey()).add(entry.getValue());
101 }
102 }
103
104 }