Merge: doc: fixed some typos and other misc. corrections
[nit.git] / tests / bench_netsim.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2005-2008 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 class Node
18 redef fun to_s: String
19 do
20 return _name
21 end
22 var name: String = "noname"
23 end
24
25 class WakeUpNode
26 super Node
27 fun wake_up is abstract
28 # Wake up the node
29 fun wake_up_in(d: Int)
30 # Ask to be weaked up in `d' time units
31 do
32 _scheduler.add_event(self, d)
33 end
34 var scheduler: Scheduler is noinit
35 end
36
37 class NodeSource
38 super Node
39 var nexts: nullable ArraySet[NodeSink] = null
40 fun attach(n: NodeSink)
41 # Add the sink `n' the the connected nodes
42 # Do nothing if `n' is already connected
43 do
44 # Create the collection if needed
45 if _nexts == null then
46 _nexts = new ArraySet[NodeSink]
47 end
48 _nexts.add(n)
49 end
50
51 fun detach(n: NodeSink)
52 # Remove the sink `n' from the connected nodes
53 # Do nothing if `n' is not connected
54 do
55 _nexts.remove(n)
56 end
57
58 protected fun send
59 # Notify the sinks by calling the recieve(1) method of each sink
60 do
61 if _nexts == null then
62 return
63 end
64 for n in _nexts.as(not null) do
65 n.recieve(self)
66 end
67 end
68 end
69
70 class NodeSink
71 super Node
72 fun recieve(n: NodeSource) is abstract
73 # the `n' has emeted a signal
74 end
75
76 #
77
78 class Scheduler
79 var time_list: Array[Couple[Int, WakeUpNode]] = new Array[Couple[Int, WakeUpNode]]
80 var time: Int = 0 # What time is it ?
81 fun add_event(n: WakeUpNode, d: Int)
82 # The node `n' whant to be weaked up in `d' time units
83 do
84 var entry = new Couple[Int, WakeUpNode](d+_time, n)
85 _time_list.add(entry)
86 end
87
88 fun next_event: nullable WakeUpNode
89 # Get the
90 do
91 if _time_list.is_empty then
92 return null
93 end
94
95 # Get the next entry
96 var entry = _time_list.first
97 for e in _time_list do
98 if e.first < entry.first then
99 entry = e
100 end
101 end
102 _time_list.remove(entry)
103
104 _time = entry.first
105 return entry.second
106 end
107
108 fun run_for(time_limit: Int)
109 do
110 loop
111 var node = next_event
112 if _time > time_limit then
113 print("Time limit.")
114 return
115 end
116 if node == null then
117 print("No more event.")
118 return
119 end
120 node.wake_up
121 end
122 end
123
124 init
125 do
126 end
127 end
128
129 #
130
131 class BeepSource
132 super NodeSource
133 super WakeUpNode
134 redef fun wake_up
135 do
136 send
137 wake_up_in(_delay)
138 end
139 var delay: Int
140 fun start
141 do
142 wake_up_in(_delay)
143 end
144
145 init(name: String, s: Scheduler, delay: Int)
146 do
147 _name = name
148 _scheduler = s
149 _delay = delay
150 end
151 end
152
153 class CountSink
154 super NodeSink
155 var count: Int = 0
156 redef fun recieve(n: NodeSource)
157 do
158 count = count + 1
159 end
160 end
161
162 class SimpleCountSink
163 super CountSink
164
165 init(name: String)
166 do
167 _name = name
168 end
169 end
170
171 class NodeAlternate
172 super NodeSink
173 super NodeSource
174 var last: nullable NodeSource
175 redef fun recieve(n: NodeSource)
176 do
177 if n != _last then
178 _last = n
179 send
180 end
181 end
182
183 init(name: String)
184 do
185 _name = name
186 end
187 end
188
189 class NodeEat
190 super CountSink
191 super NodeSource
192 var limit: Int
193 redef fun recieve(n: NodeSource)
194 do
195 var c = count + 1
196 if c >= _limit then
197 count = 0
198 send
199 else
200 count = c
201 end
202 end
203
204 init(name: String, limit: Int)
205 do
206 _name = name
207 _limit = limit
208 end
209 end
210
211 class NodeDelay
212 super NodeSource
213 super NodeSink
214 super WakeUpNode
215 var delay: Int
216 redef fun recieve(n: NodeSource)
217 do
218 wake_up_in(_delay)
219 end
220 redef fun wake_up
221 do
222 send
223 end
224
225 init(name: String, scheduler: Scheduler, delay: Int)
226 do
227 _name = name
228 _scheduler = scheduler
229 _delay = delay
230 end
231 end
232
233 #
234
235 var s = new Scheduler
236
237 var b1 = new BeepSource("Beep 1", s, 10)
238 var b2 = new BeepSource("Beep 2", s, 7)
239 var a1 = new NodeAlternate("Alternate 1")
240 var a2 = new NodeAlternate("Alternate 2")
241 var a3 = new NodeAlternate("Alternate 3")
242 var d1 = new NodeDelay("Delay 1", s, 2)
243 var e1 = new NodeEat("Eat 1", 5)
244 var c1 = new SimpleCountSink("Count 1")
245 b1.attach(a1)
246 b1.attach(a3)
247
248 b2.attach(a1)
249 b2.attach(a2)
250
251 b2.attach(a3)
252
253 a1.attach(e1)
254 a1.attach(a2)
255
256 a2.attach(a2)
257 a2.attach(a3)
258
259 a3.attach(e1)
260 a3.attach(d1)
261
262 d1.attach(e1)
263
264 e1.attach(c1)
265 e1.attach(a1)
266
267 b1.start
268 b2.start
269
270 var nb = 10
271 if not args.is_empty then
272 nb = args.first.to_i
273 end
274
275 s.run_for(1 << nb)
276 print(c1.count)
277