package codeine.api; import static com.google.common.collect.Maps.newHashMap; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import codeine.executer.ThreadPoolUtils; import codeine.jsons.labels.LabelJsonProvider; import codeine.model.Constants; import com.google.common.base.Stopwatch; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.inject.Inject; public class NodeAggregator { private static final Logger log = Logger.getLogger(NodeAggregator.class); @Inject private LabelJsonProvider versionLabelJsonProvider; @Inject private NodeGetter nodesGetter; private LoadingCache<String, Integer> nodesCount = CacheBuilder.newBuilder() .refreshAfterWrite(1, TimeUnit.MINUTES) .build(CacheLoader.asyncReloading(new CacheLoader<String, Integer>() { @Override public Integer load(String project) { Stopwatch s = Stopwatch.createStarted(); VersionItemInfo versionItem = aggregateInternal(project).get(Constants.ALL_VERSION); int $ = versionItem.count(); log.info("count for project " + project + " is " + $ + " took " + s); return $; } }, ThreadPoolUtils.newFixedThreadPool(1, "NodeAggregatorCount"))); public Map<String, VersionItemInfo> aggregate(String projectName) { Map<String, VersionItemInfo> $ = aggregateInternal(projectName); nodesCount.put(projectName, $.get(Constants.ALL_VERSION).count()); return $; } private Map<String, VersionItemInfo> aggregateInternal(String projectName) { Multimap<String, NodeWithMonitorsInfo> items = ArrayListMultimap.create(); List<NodeWithMonitorsInfo> nodes = nodesGetter.getNodes(projectName); for (NodeWithMonitorsInfo nodeInfo : nodes) { String version = nodeInfo.version(); String versionLabel = versionLabelJsonProvider.labelForVersion(version, projectName); items.put(Constants.ALL_VERSION, nodeInfo); items.put(versionLabel, nodeInfo); } Map<String, VersionItemInfo> $ = newHashMap(); int max = getMax(items); for (Entry<String, Collection<NodeWithMonitorsInfo>> e : items.asMap().entrySet()) { int countBad = percent(false, e.getValue(), max); String versionName = versionLabelJsonProvider.versionForLabel(e.getKey(), projectName); $.put(e.getKey(), new VersionItemInfo(e.getKey(), versionName, countBad, e.getValue().size(), max)); } if ($.isEmpty()){ $.put(Constants.ALL_VERSION, new VersionItemInfo(Constants.ALL_VERSION, Constants.ALL_VERSION, 0,0,0)); } return $; } private int getMax(Multimap<String, NodeWithMonitorsInfo> items) { int max = 0; for (Entry<String, Collection<NodeWithMonitorsInfo>> e : items.asMap().entrySet()) { if (!e.getKey().equals(Constants.ALL_VERSION)){ max = Math.max(max, e.getValue().size()); } } return max; } private int percent(boolean b, Collection<NodeWithMonitorsInfo> collection, int total) { int count = 0; for (NodeWithMonitorsInfo entry : collection) { if (entry.status() == b){ count++; } } return count; } public int count(String name) { try { Integer $ = nodesCount.get(name); if ($ != null) { return $; } } catch (Exception e) { log.warn("got exception", e); } return 0; } }