00001 // 00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH) 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 00025 #include "PubSubSubspace.h" 00026 00027 using namespace std; 00028 00029 PubSubSubspace::PubSubSubspace( PubSubSubspaceId id ) : spaceId(id) 00030 { 00031 responsibleNode = NodeHandle::UNSPECIFIED_NODE; 00032 lastTimestamp = 0; 00033 } 00034 00035 PubSubSubspace::~PubSubSubspace( ) 00036 { 00037 } 00038 00039 std::ostream& operator<< (std::ostream& o, const PubSubSubspace& subspace) 00040 { 00041 o << "Id: " << subspace.spaceId << " responsible: " << subspace.responsibleNode; 00042 return o; 00043 } 00044 00045 PubSubSubspaceLobby::PubSubSubspaceLobby( PubSubSubspaceId id ) : PubSubSubspace( id ) 00046 { 00047 waitingForRespNode = false; 00048 } 00049 00050 std::ostream& operator<< (std::ostream& o, const PubSubSubspaceIntermediate& subspace) 00051 { 00052 o << dynamic_cast<const PubSubSubspace&>(subspace) << "\n"; 00053 o << " Children:\n"; 00054 set<NodeHandle>::iterator it; 00055 for( it = subspace.children.begin(); it != subspace.children.end(); ++it ){ 00056 o << " " << *it << "\n"; 00057 } 00058 return o; 00059 } 00060 00061 unsigned int PubSubSubspaceResponsible::maxChildren; 00062 00063 PubSubSubspaceResponsible::PubSubSubspaceResponsible( PubSubSubspaceId id ) 00064 : PubSubSubspaceIntermediate( id ) 00065 { 00066 backupNode = NodeHandle::UNSPECIFIED_NODE; 00067 heartbeatTimer = NULL; 00068 heartbeatFailCount = 0; 00069 totalChildrenCount = 0; 00070 } 00071 00072 bool PubSubSubspaceResponsible::addChild( NodeHandle child ) 00073 { 00074 if( getNumChildren() + getNumIntermediates() < (int) maxChildren ) { 00075 // we still have room in our children list, add to our own 00076 if( PubSubSubspaceIntermediate::addChild( child ) ){ 00077 ++totalChildrenCount; 00078 } 00079 return true; 00080 } else { 00081 // Child has to go to an intermediate 00082 if( cachedChildren.insert( make_pair(child, false) ).second ){ 00083 ++totalChildrenCount; 00084 } 00085 return false; 00086 } 00087 } 00088 00089 PubSubSubspaceResponsible::IntermediateNode* PubSubSubspaceResponsible::removeAnyChild( NodeHandle child ) 00090 { 00091 if( removeChild( child ) || cachedChildren.erase( child )){ 00092 --totalChildrenCount; 00093 return NULL; 00094 } else { 00095 std::deque<IntermediateNode>::iterator it; 00096 for( it = intermediateNodes.begin(); it != intermediateNodes.end(); ++it ){ 00097 if( it->children.erase( child ) ) { 00098 --totalChildrenCount; 00099 return &*it; 00100 } 00101 } 00102 return NULL; 00103 } 00104 } 00105 00106 PubSubSubspaceResponsible::IntermediateNode* PubSubSubspaceResponsible::getNextFreeIntermediate() 00107 { 00108 std::deque<IntermediateNode>::iterator it; 00109 for( it = intermediateNodes.begin(); it != intermediateNodes.end(); ++it ){ 00110 if( it->node.isUnspecified() ) continue; 00111 int childIntermediates = intermediateNodes.size() - (it - intermediateNodes.begin() +1 )* maxChildren; 00112 if( childIntermediates < 0 ) childIntermediates = 0; 00113 if( it->children.size() + it->waitingChildren + childIntermediates < maxChildren ) return &*it; 00114 } 00115 return NULL; 00116 } 00117 00118 void PubSubSubspaceResponsible::fixTotalChildrenCount() 00119 { 00120 totalChildrenCount = children.size() + cachedChildren.size(); 00121 std::deque<IntermediateNode>::iterator it; 00122 for( it = intermediateNodes.begin(); it != intermediateNodes.end(); ++it ){ 00123 totalChildrenCount += it->children.size(); 00124 } 00125 } 00126 00127 std::ostream& operator<< (std::ostream& o, const PubSubSubspaceResponsible& subspace) 00128 { 00129 o << dynamic_cast<const PubSubSubspaceIntermediate&>(subspace) << " BackupNode: " << subspace.backupNode; 00130 o << "\n cachedChildren:\n"; 00131 map<NodeHandle, bool>::const_iterator iit; 00132 for( iit = subspace.cachedChildren.begin(); iit != subspace.cachedChildren.end(); ++iit ){ 00133 o << " " << iit->first << " waiting: " << iit->second << "\n"; 00134 } 00135 o << " totalChildrenCount: " << subspace.totalChildrenCount; 00136 o << "\n IntermediateNodes:\n"; 00137 std::deque<PubSubSubspaceResponsible::IntermediateNode>::const_iterator it; 00138 for( it = subspace.intermediateNodes.begin(); it != subspace.intermediateNodes.end(); ++it ){ 00139 o << " " << it->node; 00140 o << "\n Children:\n"; 00141 for( set<NodeHandle>::iterator iit = it->children.begin(); iit != it->children.end(); ++iit ){ 00142 o << " " << *iit << "\n"; 00143 } 00144 } 00145 return o; 00146 } 00147