Alex Bikfalvi
SimStream Documentation
ModelSelect.cpp
00001 #include "Headers.h" 00002 #include "ModelSelect.h" 00003 00004 CModelSelect::CModelSelect( 00005 __uint32 numChannels, 00006 __uint32 numLayers, 00007 __uint32 numPeers 00008 ) 00009 { 00010 assert(numChannels); 00011 assert(numLayers); 00012 assert(numPeers); 00013 assert(peers); 00014 00015 this->numChannels = numChannels; 00016 this->numLayers = numLayers; 00017 this->numPeers = numPeers; 00018 00019 // Peers 00020 this->peers = new CPeer[this->numPeers]; 00021 00022 // Channels index 00023 this->index = new set<CPeer*>[numChannels]; 00024 } 00025 00026 CModelSelect::~CModelSelect() 00027 { 00028 delete[] this->peers; 00029 delete[] this->index; 00030 } 00031 00032 __uint32 CModelSelect::Add(__uint32 channel, __uint32 peer, __time timestamp, __time duration) 00033 { 00034 assert(channel < this->numChannels); 00035 00036 // Add peer to the index 00037 this->index[channel].insert(&this->peers[peer]); 00038 00039 // Set the channel and return the session number 00040 return this->peers[peer].SetChannel(channel, timestamp, duration); 00041 } 00042 00043 void CModelSelect::Add(__uint32 session, __uint32 channel, __uint32 peer) 00044 { 00045 // Return, if the request is for a different session 00046 if(session != this->peers[peer].Session()) return; 00047 00048 // Check the channel 00049 assert(channel == this->peers[peer].Channel()); 00050 00051 // Add peer to the index 00052 this->index[channel].insert(&this->peers[peer]); 00053 } 00054 00055 void CModelSelect::Remove(__uint32 session, __uint32 channel, __uint32 peer) 00056 { 00057 // Return, if the request is for a different session 00058 if(session != this->peers[peer].Session()) return; 00059 00060 // Check the channel 00061 assert(channel == this->peers[peer].Channel()); 00062 00063 // Remove the peer from the index 00064 this->index[channel].erase(&this->peers[peer]); 00065 } 00066 00067 void CModelSelect::Clear() 00068 { 00069 for(__uint32 channel = 0; channel < this->numChannels; channel++) 00070 this->index[channel].clear(); 00071 } 00072 00073 CPeer** CModelSelect::SelectOptimal(__time time, __uint32 channel, __uint32 child) 00074 { 00075 // Select the optimal parent based on child remaining time : 00076 // Search for the parent with the maximum remaining time less that the child remaining time 00077 // and the minimum remaining time greater that the child remaining time 00078 assert(channel < this->numChannels); 00079 assert(child < this->numPeers); 00080 00081 CPeer* peerChild = &this->peers[child]; 00082 00083 for(__uint32 layer = 0; layer < this->numLayers; layer++) 00084 { 00085 __time remainingGreater = 1E300; 00086 __time remainingLess = 0; 00087 00088 CPeer* peerGreater = NULL; 00089 CPeer* peerLess = NULL; 00090 00091 for(set<CPeer*>::iterator iter = this->index[channel].begin(); iter != this->index[channel].end(); iter++) 00092 { 00093 // Get the parent peer 00094 CPeer* peerParent = *iter; 00095 00096 if(!this->IsResult(peerParent, layer)) // Check the peer was not selected parent for a previous layers 00097 { 00098 if(peerChild->VerifyParent(channel, layer, peerParent)) // Check the parent 00099 { 00100 if(peerParent->Remaining(time, channel) >= peerChild->Remaining(time, channel)) 00101 { 00102 // Found a peer with a remaining time greater or equal to the child remaining time 00103 if(peerParent->Remaining(time, channel) < remainingGreater) 00104 { 00105 peerGreater = peerParent; 00106 remainingGreater = peerParent->Remaining(time, channel); 00107 } 00108 } 00109 else 00110 { 00111 // Found a peer with a remaining time less than the child remaining time 00112 if(peerParent->Remaining(time, channel) > remainingLess) 00113 { 00114 peerLess = peerParent; 00115 remainingLess = peerParent->Remaining(time, channel); 00116 } 00117 } 00118 } 00119 } 00120 } 00121 00122 this->result[layer] = peerGreater ? peerGreater : peerLess; 00123 } 00124 00125 return this->result; 00126 } 00127 00128 CPeer* CModelSelect::SelectOptimal(__time time, __uint32 channel, __uint32 layer, __uint32 child) 00129 { 00130 // Select the optimal parent based on child remaining time : 00131 // Search for the parent with the maximum remaining time less that the child remaining time 00132 // and the minimum remaining time greater that the child remaining time 00133 assert(channel < this->numChannels); 00134 assert(child < this->numPeers); 00135 00136 CPeer* peerChild = &this->peers[child]; 00137 00138 __time remainingGreater = 1E300; 00139 __time remainingLess = 0; 00140 00141 CPeer* peerGreater = NULL; 00142 CPeer* peerLess = NULL; 00143 00144 for(set<CPeer*>::iterator iter = this->index[channel].begin(); iter != this->index[channel].end(); iter++) 00145 { 00146 // Get the parent peer 00147 CPeer* peerParent = *iter; 00148 00149 if(!this->IsResult(peerParent, layer)) // Check the peer was not selected parent for a previous layers 00150 { 00151 if(peerChild->VerifyParent(channel, layer, peerParent)) // Check the parent 00152 { 00153 if(peerParent->Remaining(time, channel) >= peerChild->Remaining(time, channel)) 00154 { 00155 // Found a peer with a remaining time greater or equal to the child remaining time 00156 if(peerParent->Remaining(time, channel) < remainingGreater) 00157 { 00158 peerGreater = peerParent; 00159 remainingGreater = peerParent->Remaining(time, channel); 00160 } 00161 } 00162 else 00163 { 00164 // Found a peer with a remaining time less than the child remaining time 00165 if(peerParent->Remaining(time, channel) > remainingLess) 00166 { 00167 peerLess = peerParent; 00168 remainingLess = peerParent->Remaining(time, channel); 00169 } 00170 } 00171 } 00172 } 00173 } 00174 00175 return peerGreater ? peerGreater : peerLess; 00176 } 00177 00178 bool CModelSelect::IsResult(CPeer* peer, __uint32 layer) 00179 { 00180 for(__uint32 idx = 0; idx < layer; idx++) 00181 if(this->result[idx] == peer) 00182 return true; 00183 return false; 00184 }
Last updated: February 8, 2011