package rocks.inspectit.ui.rcp.editor.preferences.control.samplingrate; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.collections.CollectionUtils; import rocks.inspectit.shared.all.communication.DefaultData; import rocks.inspectit.shared.cs.indexing.aggregation.IAggregator; import rocks.inspectit.shared.cs.indexing.aggregation.impl.AggregationPerformer; /** * The enumeration for sampling rate modes. * * @author Eduard Tudenhoefner * */ public enum SamplingRateMode implements ISamplingRateMode { /** * The identifier of the sampling rate modes. */ TIMEFRAME_DIVIDER { /** * {@inheritDoc} */ @Override public <E extends DefaultData> List<E> adjustSamplingRate(List<E> defaultDataList, Date from, Date to, int samplingRate, IAggregator<E> aggregator) { long timeframe = 0; if ((samplingRate > 0) && (defaultDataList != null)) { timeframe = (to.getTime() - from.getTime()) / samplingRate; } else { return defaultDataList; } List<E> resultList = new ArrayList<>(); // define the start and end position of the first time frame long timeframeStartTime = Long.MAX_VALUE; long timeframeEndTime = 0; int fromIndex = 0; int toIndex = -1; // find the starting value for (int i = 0; i < defaultDataList.size(); i++) { Date dataDate = defaultDataList.get(i).getTimeStamp(); // find first data object which lies in the specified time range if (((dataDate.getTime() == from.getTime()) || dataDate.after(from)) && dataDate.before(to)) { fromIndex = i; timeframeStartTime = dataDate.getTime() - (timeframe / 2); timeframeEndTime = dataDate.getTime() + (timeframe / 2); if ((i - 1) >= 0) { // we add a data object so that the drawn graph does not start with the // first drawn object, but the line will go out of the graph. if ((i - 1) > 0) { // this data object is not the first of the list, thus we add the very // first data object to the result list because of the auto range of // jfreechart. Otherwise the graph would not scale correctly. resultList.add(defaultDataList.get(0)); } resultList.add(defaultDataList.get(i - 1)); } break; } } AggregationPerformer<E> aggregationPerformer = new AggregationPerformer<>(aggregator); // iterate over time frames while (timeframeStartTime < (to.getTime() + timeframe)) { long averageTime = (timeframeStartTime + timeframeEndTime) / 2; for (int i = fromIndex; i < defaultDataList.size(); i++) { long dataTime = defaultDataList.get(i).getTimeStamp().getTime(); if (dataTime > timeframeEndTime) { // if the actual data object is not anymore in the actual time frame, then // the last data object was toIndex = i - 1; break; } else if ((i + 1) == defaultDataList.size()) { // if end of list is reached then toIndex is the end of the list toIndex = i; } } // aggregate data objects only when toIndex changed if ((toIndex >= 0) && (fromIndex <= toIndex)) { // aggregate data and set the average time stamp aggregationPerformer.reset(); // aggregation performer does not include toIndex to the aggregation aggregationPerformer.processList(defaultDataList, fromIndex, toIndex + 1); List<E> aggregatedData = aggregationPerformer.getResultList(); if (CollectionUtils.isNotEmpty(aggregatedData)) { E data = aggregatedData.get(0); data.setTimeStamp(new Timestamp(averageTime)); resultList.add(data); } // set the fromIndex on the actual data object fromIndex = toIndex + 1; } // adjust timeframe timeframeStartTime = timeframeEndTime; timeframeEndTime += timeframe; // reset the toIndex toIndex = -1; } if (0 != fromIndex) { // we try to append an object at the right non-visible part of the graph so that a // line is drawn. if (defaultDataList.size() > fromIndex) { resultList.add(defaultDataList.get(fromIndex)); } if (defaultDataList.size() > (fromIndex + 1)) { // there are some objects untouched, thus we need to add the very last data // object to the result list for the auto scaling of jfreechart to work. resultList.add(defaultDataList.get(defaultDataList.size() - 1)); } } return resultList; } }; }