/** * Computes sleep delay needed based on the block that just got copied. we * copy using a burst mode, that is we let the copy proceed in full * throttle. Once a copy is done, we compute how many bytes have been * transferred and try to average it over the user specified bandwidth. In * other words, This code implements a poor man's token bucket algorithm for * traffic shaping. * * @param bytesCopied - byteCopied. * @param timeUsed in milliseconds * @param item DiskBalancerWorkItem * @return sleep delay in Milliseconds. */ private long computeDelay(long bytesCopied, long timeUsed, DiskBalancerWorkItem item) { // we had an overflow, ignore this reading and continue. if (timeUsed == 0) { return 0; } final int megaByte = 1024 * 1024; long bytesInMB = bytesCopied / megaByte; long lastThroughput = bytesInMB / SECONDS.convert(timeUsed, TimeUnit.MILLISECONDS); long delay = (bytesInMB / getDiskBandwidth(item)) - lastThroughput; return (delay <= 0) ? 0 : MILLISECONDS.convert(delay, TimeUnit.SECONDS); }