00001 #include "PropagatedSpikeBuffer.h"
00002
00003 #include <iostream>
00004
00005 using std::cout;
00006 using std::endl;
00007
00008
00009 PropagatedSpikeBuffer::PropagatedSpikeBuffer(int minDelay, int maxDelay, int chunkSize ):
00010 currIdx(0),
00011 ringBufferFront(maxDelay+1),
00012 ringBufferBack(maxDelay+1),
00013 chunkBuffer(0),
00014 currentFreeChunk(NULL),
00015 nextFreeSrgNodeIdx(0),
00016 nextFreeChunkIdx(0),
00017 recycledNodes(NULL),
00018 chunkSize(chunkSize)
00019 {
00020
00021
00022
00023
00024
00025 reset( minDelay, maxDelay );
00026
00027 currT = 0;
00028 }
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 PropagatedSpikeBuffer::~PropagatedSpikeBuffer()
00039 {
00040 for(size_t i=0; i<chunkBuffer.size(); i++) {
00041 delete[] chunkBuffer[i];
00042 }
00043 }
00044
00045 void PropagatedSpikeBuffer::init(size_t maxDelaySteps)
00046 {
00048
00049
00050 if( ringBufferFront.size() != maxDelaySteps + 1 ) {
00051 ringBufferFront.resize( maxDelaySteps + 1 );
00052 ringBufferBack.resize( maxDelaySteps + 1 );
00053 }
00054 if( chunkBuffer.size() < 1 ) {
00055 chunkBuffer.reserve( 10 );
00056 chunkBuffer.resize( 0 );
00057 chunkBuffer.push_back( new StgNode[ chunkSize ] );
00058 }
00059 }
00060
00061 void PropagatedSpikeBuffer::reset(int minDelay, int maxDelay)
00062 {
00063
00064
00065
00066
00067 init( maxDelay + minDelay );
00068
00069 for(size_t i=0; i<ringBufferFront.size(); i++) {
00070 ringBufferFront[i] = ringBufferBack[i] = NULL;
00071 }
00072
00073 currentFreeChunk = chunkBuffer[0];
00074 nextFreeChunkIdx = 1;
00075
00076 nextFreeSrgNodeIdx = 0;
00077
00078 recycledNodes = NULL;
00079
00080 currIdx = 0;
00081 }
00082
00083 PropagatedSpikeBuffer::StgNode *PropagatedSpikeBuffer::getFreeNode(void)
00084 {
00085 StgNode *n;
00086 if (recycledNodes != NULL) {
00087
00088 n = recycledNodes;
00089 recycledNodes = recycledNodes->next;
00090 } else if ( nextFreeSrgNodeIdx < chunkSize ) {
00091
00092 n = &(currentFreeChunk[nextFreeSrgNodeIdx++]);
00093 } else if (nextFreeChunkIdx < chunkBuffer.size() ) {
00094
00095 currentFreeChunk = chunkBuffer[nextFreeChunkIdx++];
00096 n = &(currentFreeChunk[0]);
00097 nextFreeSrgNodeIdx = 1;
00098 } else {
00099
00100 currentFreeChunk = new StgNode[chunkSize];
00101 chunkBuffer.push_back( currentFreeChunk );
00102 nextFreeChunkIdx++;
00103 n = &(currentFreeChunk[0]);
00104 nextFreeSrgNodeIdx = 1;
00105 }
00106 return n;
00107 }
00108
00109 void PropagatedSpikeBuffer::scheduleSpikeTargetGroup(spikegroupid_t stg, delaystep_t delay, float offsetFraction)
00110 {
00111
00112
00113
00114 StgNode *n = getFreeNode();
00115
00116
00117
00118 int writeIdx = ( currIdx + delay ) % ringBufferFront.size();
00119
00120 n->stg = stg;
00121 n->offsetFraction = offsetFraction;
00122 n->next = NULL;
00123 if( ringBufferFront[writeIdx] == NULL ) {
00124 ringBufferBack[writeIdx] = ringBufferFront[writeIdx] = n;
00125 } else {
00126 ringBufferBack[writeIdx]->next = n;
00127 ringBufferBack[writeIdx] = n;
00128 }
00129 }
00130
00131 void PropagatedSpikeBuffer::nextTimeStep()
00132 {
00133
00134
00135 if( ringBufferFront[ currIdx ] != NULL ) {
00136 ringBufferBack[ currIdx ]->next = recycledNodes;
00137 recycledNodes = ringBufferFront[ currIdx ];
00138 }
00139
00140
00141 ringBufferBack[ currIdx ] = ringBufferFront[ currIdx ] = NULL;
00142 currIdx = ( currIdx + 1 ) % ringBufferFront.size();
00143 currT ++;
00144 }
00145
00146