/* * Copyright 2016 NAVER Corp. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.navercorp.pinpoint.web.scatter; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.navercorp.pinpoint.web.view.ScatterDataSerializer; import com.navercorp.pinpoint.web.vo.scatter.Dot; import com.navercorp.pinpoint.web.vo.scatter.DotAgentInfo; /** * @Author Taejin Koo */ @JsonSerialize(using = ScatterDataSerializer.class) public class ScatterData { private final long from; private final long to; private final int xGroupUnitMillis; private final int yGroupUnitMillis; private final ScatterAgentMetadataRepository scatterAgentMetadataRepository = new ScatterAgentMetadataRepository(); private final Map<Long, DotGroups> scatterData = new HashMap<>(); private long oldestAcceptedTime = Long.MAX_VALUE; private long latestAcceptedTime = Long.MIN_VALUE; public ScatterData(long from, long to, int xGroupUnitMillis, int yGroupUnitMillis) { if (from <= 0) { throw new IllegalArgumentException("from value must be higher than 0"); } if (from > to) { throw new IllegalArgumentException("from value must be lower or equal to to value"); } this.from = from; this.to = to; this.xGroupUnitMillis = xGroupUnitMillis; this.yGroupUnitMillis = yGroupUnitMillis; } public void addDot(List<Dot> dotList) { for (Dot dot : dotList) { addDot(dot); } } public void addDot(Dot dot) { if (dot == null) { return; } long acceptedTimeDiff = dot.getAcceptedTime() - from; long x = acceptedTimeDiff - (acceptedTimeDiff % xGroupUnitMillis); if (x < 0) { x = 0L; } int y = dot.getElapsedTime() - (dot.getElapsedTime() % yGroupUnitMillis); Coordinates coordinates = new Coordinates(x, y); addDot(coordinates, new Dot(dot.getTransactionId(), acceptedTimeDiff, dot.getElapsedTime(), dot.getExceptionCode(), dot.getAgentId())); if (oldestAcceptedTime > dot.getAcceptedTime()) { oldestAcceptedTime = dot.getAcceptedTime(); } if (latestAcceptedTime < dot.getAcceptedTime()) { latestAcceptedTime = dot.getAcceptedTime(); } } private void addDot(Coordinates coordinates, Dot dot) { DotGroups dotGroups = scatterData.get(coordinates.getX()); if (dotGroups == null) { dotGroups = new DotGroups(coordinates.getX()); scatterData.put(coordinates.getX(), dotGroups); } dotGroups.addDot(coordinates, dot); scatterAgentMetadataRepository.addDotAgentInfo(new DotAgentInfo(dot)); } public void merge(ScatterData scatterData) { if (scatterData == null) { return; } Map<Long, DotGroups> scatterDataMap = scatterData.getScatterDataMap(); for (Map.Entry<Long, DotGroups> entry : scatterDataMap.entrySet()) { Long key = entry.getKey(); DotGroups dotGroups = this.scatterData.get(key); if (dotGroups == null) { this.scatterData.put(key, entry.getValue()); } else { dotGroups.merge(entry.getValue()); } } scatterAgentMetadataRepository.merge(scatterData.getScatterAgentMetadataRepository()); if (oldestAcceptedTime > scatterData.getOldestAcceptedTime()) { oldestAcceptedTime = scatterData.getOldestAcceptedTime(); } if (latestAcceptedTime < scatterData.getLatestAcceptedTime()) { latestAcceptedTime = scatterData.getLatestAcceptedTime(); } } ScatterAgentMetadataRepository getScatterAgentMetadataRepository() { return scatterAgentMetadataRepository; } public ScatterAgentMetaData getScatterAgentMetadata() { return new ScatterAgentMetaData(scatterAgentMetadataRepository); } public Map<Long, DotGroups> getScatterDataMap() { return scatterData; } public Map<Long, DotGroups> getSortedScatterDataMap() { TreeMap<Long, DotGroups> sortedMap = new TreeMap<>(new XCoordinatesComparator()); sortedMap.putAll(scatterData); return sortedMap; } public int getDotSize() { int totalDotSize = 0; Collection<DotGroups> dotGroupsList = scatterData.values(); for (DotGroups dotGroups : dotGroupsList) { Collection<DotGroup> dotGroupList = dotGroups.getDotGroupMap().values(); for (DotGroup dotGroup : dotGroupList) { totalDotSize += dotGroup.getDotSize(); } } return totalDotSize; } public long getFrom() { return from; } public long getTo() { return to; } public long getOldestAcceptedTime() { if (oldestAcceptedTime == Long.MAX_VALUE) { return -1; } return oldestAcceptedTime; } public long getLatestAcceptedTime() { if (latestAcceptedTime == Long.MIN_VALUE) { return -1; } return latestAcceptedTime; } private static class XCoordinatesComparator implements Comparator<Long> { @Override public int compare(Long o1, Long o2) { return Long.compare(o2, o1); } } }