/* * Copyright 2014 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.profiler.sender; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.PriorityQueue; /** * @author Taejin Koo */ public class StandbySpanStreamDataStorage { private static final int DEFAULT_CAPACITY = 5; private static final long DEFAULT_MAX_WAIT_TIME = 5000L; private final int capacity; private final long maxWaitTimeMillis; private final PriorityQueue<SpanStreamSendData> priorityQueue; StandbySpanStreamDataStorage() { this(DEFAULT_CAPACITY, DEFAULT_MAX_WAIT_TIME); } StandbySpanStreamDataStorage(int capacity, long maxWaitTimeMillis) { this.capacity = capacity; this.maxWaitTimeMillis = maxWaitTimeMillis; this.priorityQueue = new PriorityQueue<SpanStreamSendData>(capacity, new SpanStreamSendDataComparator()); } synchronized boolean addStandbySpanStreamData(SpanStreamSendData standbySpanStreamData) { SpanStreamSendDataMode flushMode = standbySpanStreamData.getFlushMode(); if (flushMode == SpanStreamSendDataMode.FLUSH) { return false; } if (standbySpanStreamData.getAvailableBufferCapacity() > 0 && standbySpanStreamData.getAvailableGatheringComponentsCount() > 0) { if (priorityQueue.size() >= capacity) { return false; } return priorityQueue.offer(standbySpanStreamData); } else { return false; } } synchronized SpanStreamSendData getStandbySpanStreamSendData(int availableCapacity) { Iterator<SpanStreamSendData> standbySpanStreamSendDataIterator = priorityQueue.iterator(); while (standbySpanStreamSendDataIterator.hasNext()) { SpanStreamSendData standbySpanStreamSendData = standbySpanStreamSendDataIterator.next(); if (standbySpanStreamSendData.getAvailableBufferCapacity() > availableCapacity) { standbySpanStreamSendDataIterator.remove(); return standbySpanStreamSendData; } } return null; } synchronized SpanStreamSendData getStandbySpanStreamSendData() { SpanStreamSendData mostAvailableBufferCapacityStreamSendData = null; Iterator<SpanStreamSendData> standbySpanStreamSendDataIterator = priorityQueue.iterator(); while (standbySpanStreamSendDataIterator.hasNext()) { SpanStreamSendData standbySpanStreamSendData = standbySpanStreamSendDataIterator.next(); if (mostAvailableBufferCapacityStreamSendData == null) { mostAvailableBufferCapacityStreamSendData = standbySpanStreamSendData; } else { if (mostAvailableBufferCapacityStreamSendData.getAvailableBufferCapacity() < standbySpanStreamSendData.getAvailableBufferCapacity()) { mostAvailableBufferCapacityStreamSendData = standbySpanStreamSendData; } } } if (mostAvailableBufferCapacityStreamSendData != null) { priorityQueue.remove(mostAvailableBufferCapacityStreamSendData); } return mostAvailableBufferCapacityStreamSendData; } synchronized List<SpanStreamSendData> getForceFlushSpanStreamDataList() { List<SpanStreamSendData> forceFlushSpanStreamDataList = new ArrayList<SpanStreamSendData>(capacity); long currentTimeMillis = System.currentTimeMillis(); while (true) { SpanStreamSendData standbySpanStreamSendData = priorityQueue.peek(); if (standbySpanStreamSendData == null) { break; } if (standbySpanStreamSendData.getFirstAccessTime() + maxWaitTimeMillis < currentTimeMillis) { priorityQueue.remove(); forceFlushSpanStreamDataList.add(standbySpanStreamSendData); } else { break; } } return forceFlushSpanStreamDataList; } synchronized long getLeftWaitTime(long defaultLeftWaitTime) { SpanStreamSendData standbySpanStreamSendData = priorityQueue.peek(); if (standbySpanStreamSendData == null) { return defaultLeftWaitTime; } long firstAccessTime = standbySpanStreamSendData.getFirstAccessTime(); return firstAccessTime + maxWaitTimeMillis - System.currentTimeMillis(); } static class SpanStreamSendDataComparator implements Comparator<SpanStreamSendData> { @Override public int compare(SpanStreamSendData newValue, SpanStreamSendData oldValue) { if (newValue.getFirstAccessTime() == -1) { return 1; } if (newValue.getFirstAccessTime() < oldValue.getFirstAccessTime()) { return -1; } else { return 1; } } } }