package net.minecraftforge.server;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.MapMaker;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
public class ForgeTimeTracker {
public static boolean tileEntityTracking;
public static int tileEntityTrackingDuration;
public static long tileEntityTrackingTime;
private Map<TileEntity,int[]> tileEntityTimings;
private Map<Entity,int[]> entityTimings;
private static final ForgeTimeTracker INSTANCE = new ForgeTimeTracker();
private WeakReference<TileEntity> tile;
private WeakReference<Entity> entity;
private long timing;
private ForgeTimeTracker()
{
MapMaker mm = new MapMaker();
mm.weakKeys();
tileEntityTimings = mm.makeMap();
entityTimings = mm.makeMap();
}
private void trackTileStart(TileEntity tileEntity, long nanoTime)
{
if (tileEntityTrackingTime == 0)
{
tileEntityTrackingTime = nanoTime;
}
else if (tileEntityTrackingTime + tileEntityTrackingDuration < nanoTime)
{
tileEntityTracking = false;
tileEntityTrackingTime = 0;
return;
}
tile = new WeakReference<TileEntity>(tileEntity);
timing = nanoTime;
}
private void trackTileEnd(TileEntity tileEntity, long nanoTime)
{
if (tile == null || tile.get() != tileEntity)
{
tile = null;
// race, exit
return;
}
int[] timings = tileEntityTimings.get(tileEntity);
if (timings == null)
{
timings = new int[101];
tileEntityTimings.put(tileEntity, timings);
}
int idx = timings[100] = (timings[100] + 1) % 100;
timings[idx] = (int) (nanoTime - timing);
}
public static ImmutableMap<TileEntity,int[]> getTileTimings()
{
return INSTANCE.buildImmutableTileEntityTimingMap();
}
private ImmutableMap<TileEntity, int[]> buildImmutableTileEntityTimingMap()
{
Builder<TileEntity, int[]> builder = ImmutableMap.<TileEntity,int[]>builder();
for (Entry<TileEntity, int[]> entry : tileEntityTimings.entrySet())
{
builder.put(entry.getKey(), Arrays.copyOfRange(entry.getValue(), 0, 100));
}
return builder.build();
}
public static void trackStart(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileStart(tileEntity, System.nanoTime());
}
public static void trackEnd(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileEnd(tileEntity, System.nanoTime());
}
public static void trackStart(Entity par1Entity)
{
}
public static void trackEnd(Entity par1Entity)
{
}
}