from chord import *
from cPickle import *
import random
from math import sqrt
import psyco
import sys
import Gnuplot, Gnuplot.funcutils
psyco.full()


def avg(lst,lstLen):
    tot = 0
    for i in lst:
        tot = tot + i
    return float(tot)/lstLen

class Test:
    def __init__(self,numNodes, avgDataPerNode):
        random.seed()
        self.numNodes = numNodes
        self.avgDataPerNode = avgDataPerNode
        self.c = Chord({},{})
        self.files = []
        
    def setup(self):
        for i in range(0,self.numNodes):
            self.c.join(i)
            
        for j in range(0,self.avgDataPerNode*self.numNodes):
            node = random.randint(0,self.numNodes-1)
            oid = random.randint(0,2**128)
            self.files.add(oid)
            x = self.c.insert(oid*(2**32)+2**32-1, node)
            if (j%(10) == 0):
                self.c.stabilize()                    
            while (not x):
                x = self.c.insert(randVID(oid), node)
        print "Done adding "+repr(self.numNodes)+" with "+repr(self.avgDataPerNode)+" objects each"
        
        
    def test(self, numTests):
        #self.c.clearStats()
        for i in range(0,numTests):
            node = random.randint(0,self.numNodes-1)
            oid = random.randint(0,2**128)
            while self.c.findSuccessor(oid,node) == -1:
                node = random.randint(0,self.numNodes-1)            
            
        print "Done running "+repr(numTests)+" tests"
        return self.printResults()
    
    def printResults(self):
        print "Summary -----------------------------------"
        print "Number of physical nodes: "+repr(self.numNodes)
        print "Number of virtual nodes: "+repr(self.numNodes*self.avgDataPerNode)
        print "Average number of virutal nodes per physical node: "+repr(self.avgDataPerNode)
        print "Average number of messages sent by node: "+repr(avg(self.c.getMsgOutPerNode().values(),self.numNodes))
        print "Average number of messages received by node: "+repr(avg(self.c.getMsgInPerNode().values(),self.numNodes))
        print "Average number of hops per search: "+repr(avg(self.c.getHopsPerSearch(),len(self.c.getHopsPerSearch())))
        print "Average amount of routing data per node: "+repr(avg(self.c.getRoutingDataPerNode(), self.numNodes))
        return [self.numNodes,
                self.numNodes*self.avgDataPerNode,
                self.avgDataPerNode,
                avg(self.c.getMsgInPerNode().values(),self.numNodes),
                avg(self.c.getMsgOutPerNode().values(),self.numNodes),
                avg(self.c.getHopsPerSearch(), len(self.c.getHopsPerSearch())),
                avg(self.c.getRoutingDataPerNode(), self.numNodes)]

nodesVShops = [(0,0.0)]
nodesVSmsg = [(0,0.0)]
nodesVSdata = [(0,0.0)]
dataPerNode = 10
start = 50
stop = 2000

for i in range(start,start+stop,start):
    t = Test(i, dataPerNode)
    t.setup()
    results = t.test(i)
    nodesVShops.append((results[0],results[5]))
    nodesVSmsg.append((results[0],results[3]+results[4]))
    nodesVSdata.append((results[0],results[6]*20))

prefix = "k-5"

f = file("data/hops-"+prefix+"-"+repr(start)+"-"+repr(stop), "w")

for d in nodesVShops:
    f.write(repr(d[0])+" "+repr(d[1])+"\n")
f.close()

f = file("data/msg-"+prefix+"-"+repr(start)+"-"+repr(stop), "w")
for d in nodesVSmsg:
    f.write(repr(d[0])+" "+repr(d[1])+"\n")
f.close()

f = file("data/data-"+prefix+"-"+repr(start)+"-"+repr(stop), "w")
for d in nodesVSdata:
    f.write(repr(d[0])+" "+repr(d[1])+"\n")
f.close()

g = Gnuplot.Gnuplot(debug=1)
g.xlabel('Average number of objects per node')
g.ylabel("Number of hops")
g('set data style linespoints')
g.title('Average Number of Hops Per Search')
g.plot(nodesVShops)
g.hardcopy('hops.ps', enhanced=1, color=1)

h = Gnuplot.Gnuplot(debug=1)
h.xlabel('Average number of objects per node')
h.ylabel("Number of messages")
h('set data style linespoints')
h.title('Average Number of Messages Sent and Received Per Node')
h.plot(nodesVSmsg)
h.hardcopy('messages.ps', enhanced=1, color=1)

k = Gnuplot.Gnuplot(debug=1)
k.xlabel('# of nodes in the system')
k.ylabel("Bytes of data")
k('set data style linespoints')
k.title('Average Amount of data per node')
k.plot(nodesVSdata)
k.hardcopy('data.ps', enhanced=1, color=1)

raw_input("press enter to continue:")

