OverSim
PastryNeighborhoodSet.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 "PastryNeighborhoodSet.h"
25 #include "PastryTypes.h"
26 
27 
29 
30 
32 {
33  WATCH_VECTOR(neighbors);
34 }
35 
36 
37 void PastryNeighborhoodSet::initializeSet(uint32_t numberOfNeighbors,
38  uint32_t bitsPerDigit,
39  const NodeHandle& owner)
40 {
41  this->owner = owner;
42  this->numberOfNeighbors = numberOfNeighbors;
43  this->bitsPerDigit = bitsPerDigit;
44  if (!neighbors.empty()) neighbors.clear();
45 
46  // fill Set with unspecified node handles
47  for (uint32_t i = numberOfNeighbors; i>0; i--)
48  neighbors.push_back(unspecNode());
49 }
50 
51 
53 {
54  uint32_t i = 0;
55  uint32_t size = 0;
56  std::vector<PastryExtendedNode>::const_iterator it;
57 
59  for (it = neighbors.begin(); it != neighbors.end(); it++) {
60  if (!it->node.isUnspecified()) {
61  ++size;
62  msg->setNeighborhoodSet(i++, it->node);
63  }
64  }
65  msg->setNeighborhoodSetArraySize(size);
66 }
67 
68 
70  bool optimize)
71 {
72  std::vector<PastryExtendedNode>::const_iterator it;
73 
74  if (optimize) {
75  // pointer to later return value, initialize to unspecified, so
76  // the specialCloserCondition() check will be done against our own
77  // node as long as no node closer to the destination than our own was
78  // found.
80 
81  for (it = neighbors.begin(); it != neighbors.end(); it++) {
82  if (it->node.isUnspecified()) break;
83  if (specialCloserCondition(it->node, destination, *ret))
84  ret = &(it->node);
85  }
86  return *ret;
87  } else {
88  for (it = neighbors.begin(); it != neighbors.end(); it++) {
89  if (it->node.isUnspecified()) break;
90  if (specialCloserCondition(it->node, destination)) return it->node;
91  }
93  }
94 }
95 
96 
98  NodeVector* nodes)
99 {
100  std::vector<PastryExtendedNode>::const_iterator it;
101 
102  for (it = neighbors.begin(); it != neighbors.end(); it++)
103  if (! it->node.isUnspecified())
104  nodes->add(it->node);
105 }
106 
107 
108 bool PastryNeighborhoodSet::mergeNode(const NodeHandle& node, simtime_t prox)
109 {
110  std::vector<PastryExtendedNode>::iterator it;
111 
112  bool nodeAlreadyInVector = false; // was the node already in the list?
113  bool nodeValueWasChanged = false; // true if the list was changed, false if the rtt was too big
114  // look for node in the set, if it's there and the value was changed, erase it (since the position is no longer valid)
115  for (it = neighbors.begin(); it != neighbors.end(); it++) {
116  if (!it->node.isUnspecified() && it->node == node) {
117  if (prox == SimTime::getMaxTime() || it->rtt == prox) return false; // nothing to do!
118  neighbors.erase(it);
119  nodeAlreadyInVector = true;
120  break;
121  }
122  }
123  // look for the correct position for the node
124  for (it = neighbors.begin(); it != neighbors.end(); it++) {
125  if (it->node.isUnspecified() || (it->rtt > prox)) {
126  nodeValueWasChanged = true;
127  break;
128  }
129  }
130  neighbors.insert(it, PastryExtendedNode(node, prox)); // insert the entry there
131  if (!nodeAlreadyInVector) neighbors.pop_back(); // if a new entry was inserted, erase the last entry
132  return !nodeAlreadyInVector && nodeValueWasChanged; // return whether a new entry was added
133 }
134 
135 
136 void PastryNeighborhoodSet::dumpToVector(std::vector<TransportAddress>& affected) const
137 {
138  std::vector<PastryExtendedNode>::const_iterator it;
139 
140  for (it = neighbors.begin(); it != neighbors.end(); it++)
141  if (! it->node.isUnspecified())
142  affected.push_back(it->node);
143 }
144 
145 
147 {
148  std::vector<PastryExtendedNode>::iterator it;
149 
150  for (it = neighbors.begin(); it != neighbors.end(); it++) {
151  if (it->node.isUnspecified()) break;
152  if (it->node.getIp() == failed.getIp()) {
153  neighbors.erase(it);
154  neighbors.push_back(unspecNode());
155  break;
156  }
157  }
158 
159  // never ask for repair
161 }
162 
163 
164 std::ostream& operator<<(std::ostream& os, const PastryExtendedNode& n)
165 {
166  os << n.node << ";";
167  if (n.rtt != SimTime::getMaxTime())
168  os << " Ping: " << n.rtt;
169 
170  return os;
171 }