package org.limewire.nio.channel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import org.limewire.collection.Buffer;
import org.limewire.inspection.Inspectable;
import org.limewire.nio.observer.WriteObserver;
import org.limewire.util.ByteUtils;
/** A simple writer that maintains statistics about how much was written. */
public class StatisticGatheringWriter extends AbstractChannelInterestWriter implements Inspectable {
private final static long NANO_START = System.nanoTime();
private static final int HISTORY = 50;
private final Buffer<Long> handleWrites = new Buffer<Long>(HISTORY);
private final Buffer<Long> interestWrites = new Buffer<Long>(HISTORY);
private final Buffer<Boolean> interestWritesStatus = new Buffer<Boolean>(HISTORY);
private final Buffer<Long> writeTimes = new Buffer<Long>(HISTORY);
private final Buffer<Long> writeAmounts = new Buffer<Long>(HISTORY);
private final long msStart = System.currentTimeMillis();
private long amountWrote, totalHandleWrite, totalInterestWrite, positiveInterestWrite;
@Override
public int write(ByteBuffer src) throws IOException {
writeTimes.add(System.nanoTime() - NANO_START);
int wrote = super.write(src);
amountWrote += wrote;
writeAmounts.add((long)wrote);
return wrote;
}
@Override
public boolean handleWrite() throws IOException {
handleWrites.add(System.nanoTime() - NANO_START);
totalHandleWrite++;
return super.handleWrite();
}
@Override
public void interestWrite(WriteObserver observer, boolean status) {
interestWrites.add(System.nanoTime() - NANO_START);
interestWritesStatus.add(status);
totalInterestWrite++;
if (status)
positiveInterestWrite++;
super.interestWrite(observer, status);
}
@Override
public Object inspect() {
Map<String,Object> ret = new HashMap<String,Object>();
ret.put("ver",1);
ret.put("ms",msStart);
ret.put("hw",getPacked(handleWrites));
ret.put("iw",getPacked(interestWrites));
ret.put("iws", getPackedBool(interestWritesStatus));
ret.put("wt",getPacked(writeTimes));
ret.put("wa",getPacked(writeAmounts));
ret.put("totalWrote", amountWrote);
ret.put("totalHW", totalHandleWrite);
ret.put("totalIW", totalInterestWrite);
ret.put("totalIWP", positiveInterestWrite);
return ret;
}
private byte [] getPacked(Buffer<Long> b) {
byte [] ret = new byte[b.getSize() * 8];
for (int i = 0; i < b.getSize(); i++)
ByteUtils.long2beb(b.get(i), ret, i*8);
return ret;
}
private byte [] getPackedBool(Buffer<Boolean> b) {
byte [] ret = new byte[b.getSize()];
for (int i = 0; i < b.getSize(); i++)
ret[i] = (byte)(b.get(i) ? 1 : 0);
return ret;
}
}