00001 #ifndef MPIInputSpikeBuffer_H_
00002 #define MPIInputSpikeBuffer_H_
00003
00004 #include <vector>
00005 #include <iostream>
00006 #include "globaldefinitions.h"
00007
00008 using std::vector;
00009 using std::cout;
00010 using std::endl;
00011
00013
00016 class MPIInputSpikeBufferElement
00017 {
00018 public:
00019 int timestamp;
00020 local_objectid_t oid;
00021 gl_engineid_t engine;
00022 };
00023
00024 bool compareMPIInputSpikeBufferElem(const MPIInputSpikeBufferElement &el1,const MPIInputSpikeBufferElement &el2);
00025
00026 bool equalMPIInputSpikeBufferElem(const MPIInputSpikeBufferElement &el1,const MPIInputSpikeBufferElement &el2);
00027
00028 template<typename T>
00029 class MPIInputSpikeBuffer;
00030
00031
00032 template<typename T>
00033 class MPIInputSpikeBufferIterator;
00034
00035 template <typename T>
00036 inline bool operator==(const MPIInputSpikeBufferIterator<T> &it1, const MPIInputSpikeBufferIterator<T> &it2)
00037 {
00038 return (it1.pbuf == it2.pbuf && it1.curr_pos == it2.curr_pos);
00039 }
00040
00041 template <typename T>
00042 inline bool operator!=(const MPIInputSpikeBufferIterator<T> &it1, const MPIInputSpikeBufferIterator<T> &it2)
00043 {
00044 return !operator==(it1,it2);
00045 }
00046
00047
00048
00050
00054 template<typename T = unsigned short>
00055 class MPIInputSpikeBufferIterator
00056 {
00057 public:
00058 MPIInputSpikeBufferIterator();
00059
00060 MPIInputSpikeBufferIterator<T> & operator++();
00061
00062 MPIInputSpikeBufferElement & operator*()
00063 {
00064 return elem;
00065 }
00066
00067 MPIInputSpikeBufferElement* operator->()
00068 {
00069 return &elem;
00070 }
00071
00072 protected:
00073 MPIInputSpikeBufferElement elem;
00074
00075 T *pbuf;
00076 T *curr_pos;
00077 unsigned int len ;
00078
00079 T guard_value ;
00080
00081 friend class MPIInputSpikeBuffer<T>;
00082 friend bool operator==<T>(const MPIInputSpikeBufferIterator<T> &it1, const MPIInputSpikeBufferIterator<T> &it2);
00083 friend bool operator!=<T>(const MPIInputSpikeBufferIterator<T> &it1, const MPIInputSpikeBufferIterator<T> &it2);
00084
00085 };
00086
00087
00088 template<class T>
00089 class MPIInputSpikeBufferVector;
00090
00092
00101 template<typename T = unsigned short >
00102 class MPIInputSpikeBuffer
00103 {
00104 public:
00106 typedef MPIInputSpikeBufferIterator<T> const_iterator;
00107
00109 typedef MPIInputSpikeBufferElement value_type;
00110
00111
00113
00116 typedef T coding_element_type;
00117
00119 T guard_value;
00120
00122
00125 MPIInputSpikeBuffer();
00126
00127 virtual ~MPIInputSpikeBuffer();
00128
00129 void initialize(T * buffer) {
00130 _buffer = buffer;
00131 *_buffer = 2;
00132 *(_buffer+1) = 1;
00133 contentIndicator = false;
00134 }
00135
00137 const_iterator begin();
00138
00140 const_iterator end();
00141
00143 T * getBuffer();
00144
00145 int & getLength();
00146
00148
00152 bool isLastReceivedBuffer();
00153
00154
00156 void setHasNewContent(bool indicator) {
00157 contentIndicator = indicator;
00158 }
00159
00160
00161 bool hasNewContent() {
00162 return contentIndicator;
00163 };
00164
00165 protected:
00166 bool contentIndicator;
00167
00168
00170 T* _buffer;
00171
00173 int len;
00174
00175 friend class MPIInputSpikeBufferIterator<T>;
00176 friend class MPIInputSpikeBufferVector<T>;
00177
00178 };
00179
00180
00182
00190 template<class T = unsigned short>
00191 class MPIInputSpikeBufferVector
00192 {
00193 public:
00194
00196
00200 MPIInputSpikeBufferVector(int numBuffers, size_t buf_size = MPIBUFFER_BLOCK_SIZE);
00201
00202 virtual ~MPIInputSpikeBufferVector()
00203 {
00204 delete [] inputBuffersPool;
00205 }
00206
00208 MPIInputSpikeBuffer<T> & operator[](int idx)
00209 {
00210 return _buffers[idx];
00211 }
00212
00214 T *getBuffersPool()
00215 {
00216 return inputBuffersPool;
00217 }
00218
00220 unsigned int size()
00221 {
00222 return nNodes;
00223 }
00224
00225 protected:
00227 int nNodes;
00228
00230 size_t _buf_size;
00231
00233 vector<MPIInputSpikeBuffer<T> > _buffers;
00234
00236 T *inputBuffersPool;
00237
00238 };
00239
00240
00241 inline bool compareMPIInputSpikeBufferElem(const MPIInputSpikeBufferElement &el1,const MPIInputSpikeBufferElement &el2)
00242 {
00243 if (el1.engine < el2.engine)
00244 return true;
00245 if (el1.engine == el2.engine) {
00246 if (el1.timestamp < el2.timestamp)
00247 return true;
00248 if (el1.timestamp == el2.timestamp)
00249 return el1.oid < el2.oid ;
00250 }
00251 return false;
00252 }
00253
00254 inline bool equalMPIInputSpikeBufferElem(const MPIInputSpikeBufferElement &el1,const MPIInputSpikeBufferElement &el2)
00255 {
00256 return el1.engine == el2.engine && el1.timestamp == el2.timestamp && el1.oid == el2.oid ;
00257 }
00258
00259 template<typename T>
00260 MPIInputSpikeBufferIterator<T>::MPIInputSpikeBufferIterator()
00261 {
00262 guard_value = 0xFF;
00263 for (unsigned int i = 1 ; i < sizeof(T) ; ++i)
00264 guard_value = (guard_value << 8) + 0xFF;
00265 }
00266
00267 template<typename T>
00268 MPIInputSpikeBufferIterator<T> & MPIInputSpikeBufferIterator<T>::operator++()
00269 {
00270
00271 curr_pos++;
00272 if (*curr_pos == guard_value) {
00273 curr_pos++;
00274 while (*curr_pos == guard_value) {
00275 if (++curr_pos == (pbuf + len - 2)) {
00276 return (*this);
00277 }
00278 elem.engine = *(curr_pos++);
00279 curr_pos++;
00280 }
00281 elem.timestamp = *(curr_pos++);
00282 }
00283
00284 elem.oid = *curr_pos;
00285 return (*this);
00286 }
00287
00288 template<typename T>
00289 MPIInputSpikeBuffer<T>::MPIInputSpikeBuffer()
00290
00291 {
00292 guard_value = 0xFF;
00293 for (unsigned int i = 1 ; i < sizeof(T) ; ++i)
00294 guard_value = (guard_value << 8) + 0xFF;
00295
00296 len = 0;
00297 _buffer = NULL;
00298 }
00299
00300 template<typename T>
00301 MPIInputSpikeBuffer<T>::~MPIInputSpikeBuffer()
00302 {}
00303
00304 template<typename T>
00305 typename MPIInputSpikeBuffer<T>::const_iterator
00306 MPIInputSpikeBuffer<T>::begin()
00307 {
00308 MPIInputSpikeBufferIterator<T> it;
00309 len = *_buffer;
00310 it.pbuf = _buffer+2;
00311 it.elem.engine = *it.pbuf;
00312 if (len <= 5) {
00313 it.curr_pos = _buffer + len;
00314 return it;
00315 }
00316 it.elem.timestamp = *(it.pbuf+2);
00317 it.elem.oid = *(it.pbuf+3);
00318 it.curr_pos = it.pbuf+3;
00319 it.len = len;
00320 return it;
00321 }
00322
00323 template<typename T>
00324 typename MPIInputSpikeBuffer<T>::const_iterator
00325 MPIInputSpikeBuffer<T>::end()
00326 {
00327 MPIInputSpikeBufferIterator<T> it;
00328 it.pbuf = _buffer + 2;
00329 it.curr_pos = _buffer + len;
00330 return it;
00331 }
00332
00333 template<typename T>
00334 T * MPIInputSpikeBuffer<T>::getBuffer()
00335 {
00336 return _buffer;
00337 }
00338
00339 template<typename T>
00340 int & MPIInputSpikeBuffer<T>::getLength()
00341 {
00342 return len;
00343 }
00344
00345 template<typename T>
00346 bool MPIInputSpikeBuffer<T>::isLastReceivedBuffer()
00347 {
00348 return *(_buffer+1)!= 0;
00349 }
00350
00351 template<typename T>
00352 MPIInputSpikeBufferVector<T>::MPIInputSpikeBufferVector(int numBuffers, size_t buf_size)
00353 : nNodes(numBuffers), _buf_size(buf_size)
00354 {
00355 inputBuffersPool = new T[nNodes*buf_size];
00356 _buffers.resize(nNodes, MPIInputSpikeBuffer<T>());
00357 for (int i = 0 ; i < nNodes ; ++i) {
00358 _buffers[i]._buffer = inputBuffersPool + i*buf_size;
00359 *_buffers[i]._buffer = 2;
00360 *(_buffers[i]._buffer+1) = 1;
00361 }
00362 }
00363
00364 #endif