-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
150 lines (127 loc) · 4.26 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""
Authors:
David Saper - 302598032 dav_sap
Alon Perelmuter - 20063088 alonperl
A set of utils for the OpenFlow exercise.
This file was created as part of the course Workshop in Communication Networks
in the Hebrew University of Jerusalem.
"""
import threading
from collections import defaultdict
class UnionFind:
""" This class implements the operations on the disjoint-set data structure.
The operations are performed on any Python object, by adding two additional
fields on each set element object given.
Based on code from here: http://code.activestate.com/recipes/577225-union-find/
"""
class RootElm:
def __init__(self):
self.uf_rank = 0
self.uf_parent = self
@staticmethod
def make_set(x):
""" Creates a singleton set out of some given object.
"""
x.uf_parent = UnionFind.RootElm()
@staticmethod
def union(x, y):
""" Unions two set elements (objects) to the same set.
If elements are in the same set, does nothing.
"""
xRoot = UnionFind.find(x)
yRoot = UnionFind.find(y)
if xRoot.uf_rank > yRoot.uf_rank:
yRoot.uf_parent = xRoot
elif xRoot.uf_rank < yRoot.uf_rank:
xRoot.uf_parent = yRoot
elif xRoot != yRoot:
yRoot.uf_parent = xRoot
xRoot.uf_rank = xRoot.uf_rank + 1
@staticmethod
def find(x):
""" Finds the set root element of a given element (object).
Also compresses the path from the element to its root.
"""
if x.uf_parent == x:
return x
else:
x.uf_parent = UnionFind.find(x.uf_parent)
return x.uf_parent
class SingletonType(type):
""" A singleton metaclass """
def __init__(cls, name, bases, dictionary):
super(SingletonType, cls).__init__(name, bases, dictionary)
cls._instance = None
cls._rlock = threading.RLock()
def __call__(cls, *args, **kws):
if cls._instance is not None:
return cls._instance
with cls._rlock:
if cls._instance is None:
cls._instance = super(SingletonType, cls).__call__(*args, **kws)
return cls._instance
## Example: How to create a singleton class:
# class MyOwnSingletonClass:
# __metaclass__ = utils.SingletonType
# #... rest of class ...
class Node(object):
def __init__(self, dpid):
self.dpid = dpid
self.tutorial = None
def __str__(self):
return str(self.dpid)
# class IPv4:
# def __init__(self,ipv4_str):
#
class Graph:
def __init__(self):
self.nodes = defaultdict(Node)
self.edges = {}
def add_node(self, label, data):
if label not in self.nodes:
self.nodes[label] = data
def add_edge(self, a, b, data):
if (a, b) not in self.edges and (b, a) not in self.edges:
self.edges[(a, b)] = data
def delete_edge(self, a, b):
if (a, b) in self.edges:
self.edges.pop((a, b), None)
if (b, a) in self.edges:
self.edges.pop((b, a), None)
def get_edge(self, a, b):
if (a, b) in self.edges:
return self.edges[(a, b)]
elif (b, a) in self.edges:
return self.edges[(b, a)]
else:
return None
def update_edge(self, a, b, data):
if (a, b) in self.edges:
self.edges[(a, b)] = data
elif (b, a) in self.edges:
self.edges[(b, a)] = data
else:
return None
def remove_node(self, label):
self.nodes.pop(label, None)
class Timer:
def __init__(self, interval, function, args = [], recurring = False):
self.interval = interval
self.func = function
self.args = args
self.recurring = recurring
self.active = False
# starting automatically
self.start()
def __do_func__(self):
self.func(*self.args)
if (self.recurring and self.active):
self.start()
def start(self):
self.active = True
self.timer = threading.Timer(self.interval, self.__do_func__)
self.timer.start()
def stop(self):
if (self.timer is not None):
self.timer.cancel()
self.active = False