184 lines
5.4 KiB
Java
184 lines
5.4 KiB
Java
package com.comphenix.protocol.timing;
|
|
|
|
import com.comphenix.protocol.events.PacketListener;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.Set;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentMap;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
/**
|
|
* Represents a system for recording the time spent by each packet listener.
|
|
* @author Kristian
|
|
*/
|
|
public class TimedListenerManager {
|
|
public enum ListenerType {
|
|
ASYNC_SERVER_SIDE,
|
|
ASYNC_CLIENT_SIDE,
|
|
SYNC_SERVER_SIDE,
|
|
SYNC_CLIENT_SIDE
|
|
}
|
|
|
|
// The shared manager
|
|
private final static TimedListenerManager INSTANCE = new TimedListenerManager();
|
|
// Running?
|
|
private final static AtomicBoolean timing = new AtomicBoolean();
|
|
// When it was started
|
|
private volatile Date started;
|
|
private volatile Date stopped;
|
|
|
|
// The map of time trackers
|
|
private final ConcurrentMap<String, ImmutableMap<ListenerType, TimedTracker>> map = new ConcurrentHashMap<>();
|
|
|
|
/**
|
|
* Retrieve the shared listener manager.
|
|
* <p>
|
|
* This should never change.
|
|
* @return The shared listener manager.
|
|
*/
|
|
public static TimedListenerManager getInstance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
/**
|
|
* Start timing listeners.
|
|
* @return TRUE if we started timing, FALSE if we are already timing listeners.
|
|
*/
|
|
public boolean startTiming() {
|
|
if (setTiming(true)) {
|
|
started = Calendar.getInstance().getTime();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**s
|
|
* Stop timing listeners.
|
|
* @return TRUE if we stopped timing, FALSE otherwise.
|
|
*/
|
|
public boolean stopTiming() {
|
|
if (setTiming(false)) {
|
|
stopped = Calendar.getInstance().getTime();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the time the listener was started.
|
|
* @return The time it was started, or NULL if they have never been started.
|
|
*/
|
|
public Date getStarted() {
|
|
return started;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the time the time listeners was stopped.
|
|
* @return The time they were stopped, or NULL if not found.
|
|
*/
|
|
public Date getStopped() {
|
|
return stopped;
|
|
}
|
|
|
|
/**
|
|
* Set whether or not the timing manager is enabled.
|
|
* @param value - TRUE if it should be enabled, FALSE otherwise.
|
|
* @return TRUE if the value was changed, FALSE otherwise.
|
|
*/
|
|
private boolean setTiming(boolean value) {
|
|
return timing.compareAndSet(!value, value);
|
|
}
|
|
|
|
/**
|
|
* Determine if we are currently timing listeners.
|
|
* @return TRUE if we are, FALSE otherwise.
|
|
*/
|
|
public boolean isTiming() {
|
|
return timing.get();
|
|
}
|
|
|
|
/**
|
|
* Reset all packet gathering data.
|
|
*/
|
|
public void clear() {
|
|
map.clear();
|
|
}
|
|
|
|
/**
|
|
* Retrieve every tracked plugin.
|
|
* @return Every tracked plugin.
|
|
*/
|
|
public Set<String> getTrackedPlugins() {
|
|
return map.keySet();
|
|
}
|
|
|
|
/**
|
|
* Retrieve the timed tracker associated with the given plugin and listener type.
|
|
* @param plugin - the plugin.
|
|
* @param type - the listener type.
|
|
* @return The timed tracker.
|
|
*/
|
|
public TimedTracker getTracker(Plugin plugin, ListenerType type) {
|
|
return getTracker(plugin.getName(), type);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the timed tracker associated with the given listener and listener type.
|
|
* @param listener - the listener.
|
|
* @param type - the listener type.
|
|
* @return The timed tracker.
|
|
*/
|
|
public TimedTracker getTracker(PacketListener listener, ListenerType type) {
|
|
return getTracker(listener.getPlugin().getName(), type);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the timed tracker associated with the given plugin and listener type.
|
|
* @param pluginName - the plugin name.
|
|
* @param type - the listener type.
|
|
* @return The timed tracker.
|
|
*/
|
|
public TimedTracker getTracker(String pluginName, ListenerType type) {
|
|
return getTrackers(pluginName).get(type);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the map of timed trackers for a specific plugin.
|
|
* @param pluginName - the plugin name.
|
|
* @return Map of timed trackers.
|
|
*/
|
|
private ImmutableMap<ListenerType, TimedTracker> getTrackers(String pluginName) {
|
|
ImmutableMap<ListenerType, TimedTracker> trackers = map.get(pluginName);
|
|
|
|
// Atomic pattern
|
|
if (trackers == null) {
|
|
ImmutableMap<ListenerType, TimedTracker> created = newTrackerMap();
|
|
trackers = map.putIfAbsent(pluginName, created);
|
|
|
|
// Success!
|
|
if (trackers == null) {
|
|
trackers = created;
|
|
}
|
|
}
|
|
return trackers;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a new map of trackers for an unspecified plugin.
|
|
* @return A map of listeners and timed trackers.
|
|
*/
|
|
private ImmutableMap<ListenerType, TimedTracker> newTrackerMap() {
|
|
ImmutableMap.Builder<ListenerType, TimedTracker> builder = ImmutableMap.builder();
|
|
|
|
// Construct a map with every listener type
|
|
for (ListenerType type : ListenerType.values()) {
|
|
builder.put(type, new TimedTracker());
|
|
}
|
|
return builder.build();
|
|
}
|
|
}
|