package net.tomp2p; import java.io.IOException; import java.lang.management.ManagementFactory; import net.tomp2p.connection.Bindings; import net.tomp2p.connection.ChannelServerConfiguration; import net.tomp2p.connection.Ports; import net.tomp2p.p2p.Peer; import net.tomp2p.p2p.PeerBuilder; import net.tomp2p.peers.Number160; import net.tomp2p.peers.PeerMap; import net.tomp2p.peers.PeerMapConfiguration; import net.tomp2p.utils.InteropRandom; public class BenchmarkUtil { /** * Creates peers for benchmarking. The first peer will be used as the master. * This means that shutting down the master will shut down all other peers as well. * * @param nrOfPeers Number of peers to create. * @param rnd The random object used for peer ID creation. * @param port The UDP and TCP port. * @param maintenance Indicates whether maintenance should be enabled. * @param timeout Indicates whether timeout should be enabled. * @return * @throws IOException */ public static Peer[] createNodes(int nrOfPeers, InteropRandom rnd, int port, boolean maintenance, boolean timeout) throws IOException { Peer[] peers = new Peer[nrOfPeers]; Number160 masterId = createRandomId(rnd); PeerMap masterMap = new PeerMap(new PeerMapConfiguration(masterId)); PeerBuilder pb = new PeerBuilder(masterId).ports(port).enableMaintenance(maintenance) .externalBindings(new Bindings()).peerMap(masterMap); if (!timeout) { pb.channelServerConfiguration(createInfiniteTimeoutChannelServerConfiguration(port)); } peers[0] = pb.start(); //System.out.printf("Created master peer: %s.\n", peers[0].peerID()); for (int i = 1; i < nrOfPeers; i++) { peers[i] = createSlave(peers[0], rnd, maintenance, timeout); } return peers; } public static Peer createSlave(Peer master, InteropRandom rnd, boolean maintenance, boolean timeout) throws IOException { Number160 slaveId = createRandomId(rnd); PeerMap slaveMap = new PeerMap(new PeerMapConfiguration(slaveId).peerNoVerification()); PeerBuilder pb = new PeerBuilder(slaveId).masterPeer(master).enableMaintenance(maintenance) .externalBindings(new Bindings()).peerMap(slaveMap); if (!timeout) { pb.channelServerConfiguration(createInfiniteTimeoutChannelServerConfiguration(Ports.DEFAULT_PORT)); } Peer slave = pb.start(); //System.out.printf("Created slave peer %s.\n", slave.peerID()); return slave; } /** * Creates and returns a ChannelServerConfiguration that has infinite values for all timeouts. * * @param port * @return */ public static ChannelServerConfiguration createInfiniteTimeoutChannelServerConfiguration(int port) { return PeerBuilder.createDefaultChannelServerConfiguration().idleTCPSeconds(0).idleUDPSeconds(0) .connectionTimeoutTCPMillis(0).ports(new Ports(port, port)); } /*public static long startBenchmark(String argument) { warmupTimer(); reclaimResources(); System.out.printf("%s: Starting Benchmarking...\n", argument); return System.nanoTime(); } public static double stopBenchmark(long start, String argument) { long stop = System.nanoTime(); long nanos = stop - start; System.out.printf("%s: Stopped Benchmarking.\n", argument); System.out.printf("%s: %s ns | %s ms | %s s\n", argument, toNanos(nanos), toMillis(nanos), toSeconds(nanos)); return toMillis(nanos); }*/ public static void warmupTimer() { System.out.println("Timer warmup..."); long anker = 0; for (int i = 0; i < 100; i++) { anker |= System.nanoTime(); } ankerTrash(anker); } public static void reclaimResources() { // best-effort only System.out.println("Garbage Collection attempted..."); System.out.println("Object Finalization attempted..."); restoreJvm(); } private static Number160 createRandomId(InteropRandom rnd) { int[] vals = new int[Number160.INT_ARRAY_SIZE]; for (int i = 0; i < vals.length; i++) { vals[i] = rnd.nextInt(Integer.MAX_VALUE); } return new Number160(vals); } public static void printStopwatchProperties() { // TODO implement } /** * This helper method receives an "anker object" just to "throw it away". * This allows such an object to be "used". * @param anker * @return */ public static Object ankerTrash(Object anker) { return anker; } // ---------------------------------------------------- // Java Specific: Force GC / OF // ---------------------------------------------------- /** * Tries to resotre the JVM to as clean a state as possible. * @param maxLoops */ private static void restoreJvm() { long memoryUsedPrev = memoryUsed(); for (int i = 0; i < 100; i++) { Runtime.getRuntime().runFinalization(); Runtime.getRuntime().gc(); long memoryUsedNow = memoryUsed(); if (ManagementFactory.getMemoryMXBean().getObjectPendingFinalizationCount() == 0 && memoryUsedNow >= memoryUsedPrev) { break; } else { memoryUsedPrev = memoryUsedNow; } } } /** * Returns the amount of memory on the heap that is currently being used by the JVM. * * @return */ private static long memoryUsed() { Runtime rt = Runtime.getRuntime(); return rt.totalMemory() - rt.freeMemory(); } }