OverSim
ChordSuccessorList.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #include <cassert>
25 
26 #include "ChordSuccessorList.h"
27 
28 #include "Chord.h"
29 
30 namespace oversim {
31 
32 Define_Module(ChordSuccessorList);
33 
34 using namespace std;
35 
36 std::ostream& operator<<(std::ostream& os, const SuccessorListEntry& e)
37 {
38  os << e.nodeHandle << " " << e.newEntry;
39  return os;
40 };
41 
43 {
44  // because of IPAddressResolver, we need to wait until interfaces
45  // are registered, address auto-assignment takes place etc.
46  if (stage != MIN_STAGE_OVERLAY)
47  return;
48 
49  WATCH_MAP(successorMap);
50 }
51 
53 {
54  error("this module doesn't handle messages, it runs only in initialize()");
55 }
56 
58  Chord *overlay)
59 {
60  successorMap.clear();
61  successorListSize = size;
62  thisNode = owner;
63  this->overlay = overlay;
64  addSuccessor(thisNode);
65 }
66 
68 {
69  return successorMap.size();
70 }
71 
73 {
74  if (successorMap.size() == 1 && getSuccessor() == thisNode)
75  return true;
76  else
77  return false;
78 }
79 
81 {
82  // check boundaries
83  if (pos == 0 && successorMap.size() == 0)
85 
86  if (pos >= successorMap.size()) {
87  error("Index out of bound (ChordSuccessorList, getSuccessor())");
88  }
89 
90  std::map<OverlayKey, SuccessorListEntry>::iterator it =
91  successorMap.begin();
92 
93  for (uint32_t i= 0; i < pos; i++) {
94  it++;
95  if (i == (pos-1))
96  return it->second.nodeHandle;
97  }
98  return it->second.nodeHandle;
99 }
100 
102 {
103  addSuccessor(notifyResponse->getSrcNode(), false);
104 
105  for (uint32_t k = 0; ((k < static_cast<uint32_t>(notifyResponse->getSucNum()))
106  && (k < (successorListSize - 1))); k++) {
107  NodeHandle successor = notifyResponse->getSucNode(k);
108 
109  // don't add nodes, if this would change our successor
110  if (successor.getKey().isBetweenLR(thisNode.getKey(),
111  notifyResponse->getSrcNode().getKey()))
112  continue;
113 
114  addSuccessor(successor, false);
115  }
116 
117  removeOldSuccessors();
118  assert(!isEmpty());
119 }
120 
121 
122 void ChordSuccessorList::addSuccessor(NodeHandle successor, bool resize)
123 {
124  OverlayKey sum = successor.getKey() - (thisNode.getKey() + OverlayKey::ONE);
125 
126  std::map<OverlayKey, SuccessorListEntry>::iterator it =
127  successorMap.find(sum);
128 
129  // Make a CommonAPI update() upcall to inform application
130  // about our new neighbor in the successor list
131 
132  if (it == successorMap.end()) {
133  // TODO: first add node and than call update()
134  overlay->callUpdate(successor, true);
135  } else {
136  successorMap.erase(it);
137  }
138 
139  SuccessorListEntry entry;
140  entry.nodeHandle = successor;
141  entry.newEntry = true;
142 
143  successorMap.insert(make_pair(sum, entry));
144 
145  if ((resize == true) && (successorMap.size() > (uint32_t)successorListSize)) {
146  it = successorMap.end();
147  it--;
148  overlay->callUpdate(it->second.nodeHandle, false);
149  successorMap.erase(it);
150  }
151 }
152 
154 {
155  assert(failed != thisNode);
156  for (std::map<OverlayKey, SuccessorListEntry>::iterator iter =
157  successorMap.begin(); iter != successorMap.end(); ++iter) {
158  if (failed == iter->second.nodeHandle) {
159  successorMap.erase(iter);
160  overlay->callUpdate(failed, false);
161  // ensure that thisNode is always in the successor list
162  if (getSize() == 0)
163  addSuccessor(thisNode);
164  return true;
165  }
166  }
167  return false;
168 }
169 
171 {
172  std::map<OverlayKey,SuccessorListEntry>::iterator it;
173 
174  for (it = successorMap.begin(); it != successorMap.end();) {
175 
176  if (it->second.newEntry == false) {
177  overlay->callUpdate(it->second.nodeHandle, false);
178  successorMap.erase(it++);
179  } else {
180  it->second.newEntry = false;
181  it++;
182  }
183  }
184 
185  it = successorMap.end();
186  it--;
187 
188  while (successorMap.size() > successorListSize) {
189  successorMap.erase(it--);
190  }
191 
192  if (getSize() == 0)
193  addSuccessor(thisNode);
194 }
195 
196 
198 {
199  // FIXME: doesn't work without tcl/tk
200  // if (ev.isGUI()) {
201  if (1) {
202  char buf[80];
203 
204  if (successorMap.size() == 1) {
205  sprintf(buf, "1 successor");
206  } else {
207  sprintf(buf, "%zi successors", successorMap.size());
208  }
209 
210  getDisplayString().setTagArg("t", 0, buf);
211  getDisplayString().setTagArg("t", 2, "blue");
212  }
213 
214 }
215 
217 {
218  if (ev.isGUI()) {
219  std::stringstream str;
220  for (uint32_t i = 0; i < successorMap.size(); i++) {
221  str << getSuccessor(i);
222  if ( i != successorMap.size() - 1 )
223  str << endl;
224  }
225 
226 
227  char buf[1024];
228  sprintf(buf, "%s", str.str().c_str());
229  getDisplayString().setTagArg("tt", 0, buf);
230  }
231 }
232 
234 {
235  cout << "Content of ChordSuccessorList:" << endl;
236  for (std::map<OverlayKey,SuccessorListEntry>::iterator it =
237  successorMap.begin(); it != successorMap.end(); it++)
238  cout << it->first << " with Node: " << it->second.nodeHandle << endl;
239 }
240 
241 }; //namespace