/* * Copyright 2012 Thomas Bocek * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package net.tomp2p.p2p; import java.util.Collection; import java.util.List; import java.util.Map; import net.tomp2p.peers.Number160; import net.tomp2p.peers.PeerAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Statistics { final private static Logger logger = LoggerFactory.getLogger(Statistics.class); private final static double MAX = Math.pow(2, Number160.BITS); private double estimatedNumberOfPeers = 1; private double avgGap = MAX / 2; // private final List<Map<Number160, PeerAddress>> peerMap; // private final Number160 remotePeer; private final int maxSize; private final int bagSize; private int currentSize; // no need to be volatile, since they are synced private long tcpCreationCount = 0; private long udpCreationCount = 0; private long tcpCount = 0; private long udpCount = 0; public Statistics(List<Map<Number160, PeerAddress>> peerMap, Number160 remotePeer, int maxSize, int bagSize) { this.peerMap = peerMap; // this.remotePeer = remotePeer; this.maxSize = maxSize; this.bagSize = bagSize; } // TODO: with increasing number of peers, the diff gets lower and lower public void triggerStatUpdate(boolean insert, int currentSize) { this.currentSize = currentSize; } public double getEstimatedNumberOfNodes() { // we know it exactly if (currentSize < maxSize) { estimatedNumberOfPeers = currentSize; return estimatedNumberOfPeers; } // otherwise we know we are full! double gap = 0D; int gapCount = 0; int oldNumPeers = 0; for (int i = Number160.BITS - 1; i >= 0; i--) { Map<Number160, PeerAddress> peers = peerMap.get(i); int numPeers = peers.size(); // System.out.print(numPeers); // System.out.print(","); if (numPeers > 0 && (numPeers < bagSize || numPeers < oldNumPeers)) { double currentGap = Math.pow(2, i) / numPeers; // System.out.print("gap("+i+"):"+currentGap+";"); gap += currentGap * numPeers; gapCount += numPeers; } else { // System.out.print("ignoring "+i+";"); } oldNumPeers = numPeers; } // System.out.print("\n"); avgGap = gap / gapCount; estimatedNumberOfPeers = (MAX / avgGap); return estimatedNumberOfPeers; } public double getAvgGap() { return avgGap; } public static void tooClose(Collection<PeerAddress> collection) { } public void incrementTCPChannelCreation() { synchronized (this) { tcpCreationCount++; tcpCount++; } } public void incrementUDPChannelCreation() { synchronized (this) { udpCreationCount++; udpCount++; } } public void decrementTCPChannelCreation() { synchronized (this) { tcpCount--; if (logger.isDebugEnabled()) { logger.debug("TCP channel count is " + tcpCount); } } } public void decrementUDPChannelCreation() { synchronized (this) { udpCount--; if (logger.isDebugEnabled()) { logger.debug("UDP channel count is " + udpCount); } } } public long getTCPChannelCreationCount() { synchronized (this) { return tcpCreationCount; } } public long getUDPChannelCreationCount() { synchronized (this) { return udpCreationCount; } } public long getTCPChannelCount() { synchronized (this) { return tcpCount; } } public long getUDPChannelCount() { synchronized (this) { return udpCount; } } }