/*
* Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
*
* This file is part of the Lock Contention Tracing Subsystem for the HotSpot
* Virtual Machine, which is developed at Christian Doppler Laboratory on
* Monitoring and Evolution of Very-Large-Scale Software Systems. Please
* contact us at if you need additional information
* or have any questions.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work. If not, see .
*
*/
package sun.evtracing.processing;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import sun.evtracing.parser.SequenceOrderedEvent;
public class SequenceOrderedEventQueue {
private static class SequenceOrderedEventComparator implements Comparator {
@Override
public int compare(SequenceOrderedEvent e1, SequenceOrderedEvent e2) {
return (int) (e1.sequenceNumber() - e2.sequenceNumber());
}
}
private final TraceEventHandler delegateHandler;
public SequenceOrderedEventQueue(TraceEventHandler delegate) {
this.delegateHandler = delegate;
}
private long nextSeqNumber = 1;
private final Queue queue = new PriorityQueue<>(new SequenceOrderedEventComparator());
public int size() {
return queue.size();
}
public void addEvent(SequenceOrderedEvent event) {
if (tryNotify(event)) {
tryFlushQueue();
} else {
queue.add(event);
}
}
private boolean tryNotify(SequenceOrderedEvent event) {
if (nextSeqNumber == event.sequenceNumber()) {
event.accept(delegateHandler);
nextSeqNumber++;
return true;
}
return false;
}
private void tryFlushQueue() {
while (!queue.isEmpty() && tryNotify(queue.peek())) {
queue.remove();
}
}
}