-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathNode.java
457 lines (405 loc) · 14.4 KB
/
Node.java
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
import java.util.ArrayList;
import java.sql.Date;
import java.math.*;
public class Node
{
ArrayList<Packet> interests = new ArrayList<Packet>(); // interests to be sent along
ArrayList<Packet> exploratoryData = new ArrayList<Packet>(); // exploratory data to be sent along
ArrayList<Packet> reinforcements = new ArrayList<Packet>(); // reinforcements to be sent along
ArrayList<Packet> reinforcedData = new ArrayList<Packet>(); // reinforced data to be sent along
ArrayList<Packet> interestsSentAsTheSink = new ArrayList<Packet>(); // interests which initiated with this node, which is a sink
ArrayList<Packet> interestsToRespondToAsTheSource = new ArrayList<Packet>(); // reinforced data to be sent from this Node, which is the source.
boolean generating; // whether this node is generating data. Set at the beginning of the simulation by NodeTest
DataType genType; // the type of data being generated by this node. Set at the beginning of the simulation by NodeTest
Data genData; // the data which was generated at the current point in time.
boolean doneSendingRequestedGeneratedData = true;
int genAmount = 0; // the number of requested pieces of data
int genPeriod = 1; // the period of requested pieces of data (1 means at every run(); 2 at every second; etc.).
int genPeriodCounter = 0;
long requestID = 0;
ArrayList<Node> allNodes; // every node in the entire network
ArrayList<Node> myNeighbors = new ArrayList<Node>(); // neighbouring nodes
public int nodeEnergyUsed = 0; //the total energy used by the node.
public boolean suppressOutput = false;
public int nodeID; // the ID of this node (starting at 0)
public int xCoord; // where this node is.
public int yCoord; // where this node is.
public int radioRange;
public int numNodes; // the number of nodes in the entire network.
public Node(int nodeID, int xCoord, int yCoord, int radioRange, int numNodes, boolean suppressOutput)
{
this.nodeID = nodeID;
this.xCoord = xCoord;
this.yCoord = yCoord;
this.radioRange = radioRange;
this.numNodes = numNodes;
this.suppressOutput = suppressOutput;
}
public void run(long currentTime) //This runs at each time-stamp
{
//System.out.println("- - running Node: " + nodeID);
generateData();
//send all interests in the queue.
sendInterests(); //broadcast
//send all expData
sendExploratoryDataPacketThrough(); //broadcast
//send all reinforments
sendReinforcements(); //monocast
//send all reinforcedData
sendReinforcedDataPacketThrough(); //monocast
//send one generated data if enough time has passed as exploratory data.
sendExploratoryDataAsSource(); //broadcast
//reinforce a path
sendReinforcedDataAsSource(); //monocast
}
public void startGeneration(DataType dType)
{
genType = dType;
generating = true;
}
public void generateData()
{
if(generating)
{
//generate random data
genData = new Data((int)(Math.random()*256), genType);
}
}
public void startInterest(int period, int amount, DataType type, long currentTime)
{
//Seed an interest in the network.
Packet pkt = new Packet(this, PacketType.INTEREST, currentTime, false, type, null, amount, period);
interestsSentAsTheSink.add(pkt);
// Make sure we don't re-send this packet when it comes back to us.
Packet tmp = pkt.clone();
tmp.ifsent = true;
interests.add(tmp);
if(!suppressOutput) {System.out.println("oE");}
broadcast(pkt);
}
public void receivePacket(Packet pkt)
{
switch(pkt.pType)
{
case INTEREST:
//see if we have one with this id already
boolean haveAlready = false;
for(Packet p : interests)
{
if(p.id == pkt.id)
{
//We already have this ID. Ignore this packet.
haveAlready = true;
break;
}
}
if(haveAlready)
break;
//See if interest is for this node
if(generating && genType == pkt.dType)
{
//It's for me; I am the source for this packet.
interestsToRespondToAsTheSource.add(pkt.clone());
}
interests.add(pkt); //send it along whether it's for me or not.
break;
case EXPLORATORYDATA:
//See if we already have exploratory data for this id.
boolean foundAlready = false;
for(Packet parket : exploratoryData)
{
if(parket.id == pkt.id)
{
//We already have this ID. Ignore this packet.
foundAlready = true;
break;
}
}
if(foundAlready)
break;
//only ever send the first time we see this ID
//see if this node originated the interest
for(Packet p : interestsSentAsTheSink)
{
//see if this node started this id
if(p.id == pkt.id)
{
//This node started this id. Send reinforcement.
reinforcements.add(new Packet(this, PacketType.REINFORCEMENT, pkt.id, false, pkt.dType, null, pkt.requestedAmount, pkt.requestedPeriod));
pkt.ifsent = true; // so that we don't resend a packet which is for us.
break;
}
}
exploratoryData.add(pkt); //if it's for us or not, but only send the first one we see.
break;
case REINFORCEMENT:
//See if we already have exploratory data for this id.
boolean alreadyHave = false;
for(Packet parket : reinforcements)
{
if(parket.id == pkt.id)
{
//We already have this ID. Ignore this packet.
alreadyHave = true;
break;
}
}
if(alreadyHave)
break;
if(generating && genType == pkt.dType)
{
//It's for me; I am the source for this packet.
//enable the sending of generated data as reinforced data, and sets its parameters.
doneSendingRequestedGeneratedData = false;
genAmount = pkt.requestedAmount;
genPeriod = pkt.requestedPeriod;
requestID = pkt.id;
genPeriodCounter = 0;
pkt.ifsent = true; //don't send along a packet which was for us. ONLY ONE SOURCE PER DATA TYPE.
}
reinforcements.add(pkt); //add it to the list (to be sent if not for us)
break;
case REINFORCEDDATA:
boolean foundIt = false;
// See if the packet is for me
for(Packet p : interestsSentAsTheSink)
{
if(p.id == pkt.id)
{
// It is for us! We are the sink for this packet.
if(!suppressOutput) {System.out.println(" - - -o Sink Node: " + nodeID + " received data: \t" + pkt.datum.datum + "\t id: " + pkt.id);}
foundIt = true;
break;
}
}
if(!foundIt)
{
reinforcedData.add(pkt); //if it wasn't for us, send it along.
}
break;
default:
System.out.println("===ERROR=== No Packet Type.");
break;
}
}
public void sendInterests()
{
// send all of the unsent interests.
for(Packet pkt : interests)
{
if(pkt.ifsent == false)
{
if(!suppressOutput) {System.out.println("-E");}
broadcast(pkt);
pkt.ifsent = true;
}
}
}
public void sendExploratoryDataPacketThrough()
{
// send all of the unsent expData packets.
for(Packet pkt : exploratoryData)
{
if(pkt.ifsent == false)
{
if(!suppressOutput) {System.out.println("- -E");}
broadcast(pkt);
pkt.ifsent = true;
}
}
}
public void sendReinforcements()
{
Node sendTo = null;
// send all of the unsent reinforcements packets.
//System.out.println("SIZE: "+ reinforcements.size());
int siz = reinforcements.size();
for(int i = 0; i < siz; i++)
{
//System.out.println(i + " " + reinforcements.get(i).ifsent + " " + reinforcements.get(i).id);
if(reinforcements.get(i).ifsent == false)
{
//send to the node from the packet with this id from the exploratoryData list.
//there will only be one, and it will have been the fastest.
for(Packet expkt : exploratoryData)
{
if(expkt.id == reinforcements.get(i).id)
{
sendTo = expkt.sender;
//System.out.println("We found which to send reinf to: " + i);
}
}
if(sendTo == null)
{
if(!suppressOutput) {System.out.println("could not find who to send reinf to.");}
return;
}
if(reinforcements.get(i).sender == this)
{
if(!suppressOutput) {System.out.println("o - -+");}
}else{
if(!suppressOutput) {System.out.println("- - -+");}
}
if(!myNeighbors.contains(sendTo))
System.out.println("ERROR 404: Sending to non-neighbours");
monocast(reinforcements.get(i), sendTo);
reinforcements.get(i).ifsent = true;
}
}
}
public void sendReinforcedDataPacketThrough()
{
Node sendTo = null;
// send all of the unsent reinforcedData packets.
for(Packet pkt : reinforcedData)
{
if(pkt.ifsent == false)
{
//send to the node from the packet with this id from the reinforcements list.
//there will only be one.
for(Packet reinfpkt : reinforcements)
{
if(reinfpkt.id == pkt.id)
{
sendTo = reinfpkt.sender;
//System.out.println("We found which to send reinfdata to.");
}
}
if(sendTo == null)
{
System.out.println("===ERROR=== could not find who to send reinfdata to.");
return;
}
if(!suppressOutput) {System.out.println("- - - -+");}
if(!myNeighbors.contains(sendTo))
System.out.println("ERROR 403: Sending to non-neighbours");
monocast(pkt, sendTo);
pkt.ifsent = true;
}
}
}
public void sendExploratoryDataAsSource()
{
for(Packet pkt : interestsToRespondToAsTheSource)
{
if(pkt.ifsent == false)
{
//genPeriodCounter = 0;
if(!suppressOutput) {System.out.println("o -E");}
broadcast(new Packet(this, PacketType.EXPLORATORYDATA, requestID, false, genType, genData, pkt.requestedAmount, pkt.requestedPeriod));
pkt.ifsent = true;
}
}
}
public void sendReinforcedDataAsSource()
{
Packet pkt = null;
//This function will send data of type genType every genPeriod runs for a total of genAmount times.
//check to see that we have received a request
if(doneSendingRequestedGeneratedData)
return;
if(genAmount <= 0)
{
doneSendingRequestedGeneratedData = true;
return;
}
genPeriodCounter++;
if(genPeriodCounter % genPeriod != 0) // send a reinforced data packet every genPeriod time-stamps.
return;
genAmount--;
Node sendTo = null;
//send to the node from the packet with this id from the reinforcements list.
//there will only be one.
for(Packet reinfpkt : reinforcements)
{
if(reinfpkt.id == requestID)
{
sendTo = reinfpkt.sender;
pkt = reinfpkt;
break;
//System.out.println("We found which to send reinfdata to [from source].");
}
}
if(sendTo == null)
{
System.out.println("===ERROR=== could not find who to send reinfdata to [from source].");
return;
}
if(!suppressOutput) {System.out.println("o - - -+");}
if(!myNeighbors.contains(sendTo))
System.out.println("ERROR 402: Sending to non-neighbours");
monocast(new Packet(this, PacketType.REINFORCEDDATA, requestID, false, genType, genData, pkt.requestedAmount, pkt.requestedPeriod), sendTo);
}
public void broadcast(Packet pkt)
{
// if(nodeID == 0) //Single out a specific node for testing
// System.out.println("==== Node " + nodeID + " sent Packet. id: " + pkt.id + ", sender: " + pkt.sender.nodeID + ", pType: " + pkt.pType);
Packet tmp;
nodeEnergyUsed++;
for(Node nod : myNeighbors)
{
tmp = pkt.clone();
tmp.sender = this;
nod.receivePacket(tmp);
}
}
public void monocast(Packet pkt, Node nod)
{
// if(nodeID == 0) //Single out a specific node for testing
// System.out.println("==== Node " + nodeID + " sent Packet. id: " + pkt.id + ", sender: " + pkt.sender.nodeID + ", pType: " + pkt.pType);
Packet tmp;
nodeEnergyUsed++;
if(!myNeighbors.contains(nod))
System.out.println("===ERROR=== monocast sent to node: " + nod.nodeID + ", which is NOT A NEIGHBOUR");
tmp = pkt.clone();
tmp.sender = this;
nod.receivePacket(tmp);
}
public boolean isThereStillWorkToBeDone()
{
if(!doneSendingRequestedGeneratedData)
return true;
for(Packet pkt : interests)
{
if(!pkt.ifsent)
return true;
}
for(Packet pkt : exploratoryData)
{
if(!pkt.ifsent)
return true;
}
for(Packet pkt : reinforcements)
{
if(!pkt.ifsent)
return true;
}
for(Packet pkt : reinforcedData)
{
if(!pkt.ifsent)
return true;
}
return false;
}
public void setAllNodes(ArrayList<Node> allNodes)
{
this.allNodes = allNodes;
}
public void findNeighbors()
{
for(int i=0; i<numNodes; i++)
{
// If we are not the node which is currently being considered.
if(this.xCoord != allNodes.get(i).xCoord || this.yCoord != allNodes.get(i).yCoord)
{
int xDiff = Math.abs(allNodes.get(i).xCoord - this.xCoord);
int yDiff = Math.abs(allNodes.get(i).yCoord - this.yCoord);
if(xDiff <= radioRange && yDiff <= radioRange)
{
// System.out.println("Node " + nodeID + " is adding node " + allNodes.get(i).nodeID + " to its neighbours. It is as far away as x = " + xDiff + " and y = " + yDiff);
myNeighbors.add(allNodes.get(i));
}
}
}
}
}