10 #ifndef __PARSEBUFFER_H__
11 #define __PARSEBUFFER_H__
26 enum E_IS_EXAMPLE_USED
69 template <
class T>
class CParseBuffer:
public CSGObject
77 CParseBuffer(int32_t size = 1024);
91 Example<T>* get_free_example()
93 pthread_mutex_lock(write_lock);
94 pthread_mutex_lock(&ex_in_use_mutex[ex_write_index]);
95 while (ex_used[ex_write_index] == E_NOT_USED)
96 pthread_cond_wait(&ex_in_use_cond[ex_write_index], &ex_in_use_mutex[ex_write_index]);
97 Example<T>* ex=&ex_ring[ex_write_index];
98 pthread_mutex_unlock(&ex_in_use_mutex[ex_write_index]);
99 pthread_mutex_unlock(write_lock);
112 int32_t write_example(Example<T>* ex);
119 Example<T>* return_example_to_read();
126 Example<T>* get_unused_example();
136 int32_t copy_example(Example<T>* ex);
145 void finalize_example(
bool free_after_release);
156 void set_free_vectors_on_destruct(
bool destroy)
158 free_vectors_on_destruct = destroy;
165 bool get_free_vectors_on_destruct()
167 return free_vectors_on_destruct;
175 virtual const char* get_name()
const {
return "ParseBuffer"; }
187 virtual void inc_read_index()
189 ex_read_index=(ex_read_index + 1) % ring_size;
196 virtual void inc_write_index()
198 ex_write_index=(ex_write_index + 1) % ring_size;
209 E_IS_EXAMPLE_USED* ex_used;
211 pthread_mutex_t* ex_in_use_mutex;
213 pthread_cond_t* ex_in_use_cond;
215 pthread_mutex_t* read_lock;
217 pthread_mutex_t* write_lock;
220 int32_t ex_write_index;
222 int32_t ex_read_index;
225 bool free_vectors_on_destruct;
229 template <
class T>
void CParseBuffer<T>::init_vector()
231 if (!free_vectors_on_destruct)
233 for (int32_t i=0; i<ring_size; i++)
235 if(ex_ring[i].fv==NULL)
236 ex_ring[i].fv =
new T();
240 template <
class T> CParseBuffer<T>::CParseBuffer(int32_t size)
243 ex_ring = SG_CALLOC(Example<T>, ring_size);
244 ex_used = SG_MALLOC(E_IS_EXAMPLE_USED, ring_size);
245 ex_in_use_mutex = SG_MALLOC(pthread_mutex_t, ring_size);
246 ex_in_use_cond = SG_MALLOC(pthread_cond_t, ring_size);
247 read_lock = SG_MALLOC(pthread_mutex_t, 1);
248 write_lock = SG_MALLOC(pthread_mutex_t, 1);
250 SG_SINFO(
"Initialized with ring size: %d.\n", ring_size)
255 for (int32_t i=0; i<ring_size; i++)
257 ex_used[i] = E_EMPTY;
259 ex_ring[i].fv = NULL;
260 ex_ring[i].length = 1;
261 ex_ring[i].label = FLT_MAX;
263 pthread_cond_init(&ex_in_use_cond[i], NULL);
264 pthread_mutex_init(&ex_in_use_mutex[i], NULL);
266 pthread_mutex_init(read_lock, NULL);
267 pthread_mutex_init(write_lock, NULL);
269 free_vectors_on_destruct =
true;
272 template <
class T> CParseBuffer<T>::~CParseBuffer()
274 for (int32_t i=0; i<ring_size; i++)
276 if (ex_ring[i].fv != NULL && free_vectors_on_destruct)
278 SG_DEBUG(
"%s::~%s(): destroying examples ring vector %d at %p\n",
279 get_name(), get_name(), i, ex_ring[i].fv);
280 delete ex_ring[i].fv;
282 pthread_mutex_destroy(&ex_in_use_mutex[i]);
283 pthread_cond_destroy(&ex_in_use_cond[i]);
287 SG_FREE(ex_in_use_mutex);
288 SG_FREE(ex_in_use_cond);
295 int32_t CParseBuffer<T>::write_example(Example<T> *ex)
297 ex_ring[ex_write_index].label = ex->label;
298 ex_ring[ex_write_index].fv = ex->fv;
299 ex_ring[ex_write_index].length = ex->length;
300 ex_used[ex_write_index] = E_NOT_USED;
307 Example<T>* CParseBuffer<T>::return_example_to_read()
309 if (ex_read_index >= 0)
310 return &ex_ring[ex_read_index];
316 Example<T>* CParseBuffer<T>::get_unused_example()
318 pthread_mutex_lock(read_lock);
321 int32_t current_index = ex_read_index;
324 pthread_mutex_lock(&ex_in_use_mutex[current_index]);
326 if (ex_used[current_index] == E_NOT_USED)
327 ex = return_example_to_read();
331 pthread_mutex_unlock(&ex_in_use_mutex[current_index]);
333 pthread_mutex_unlock(read_lock);
338 int32_t CParseBuffer<T>::copy_example(Example<T> *ex)
340 pthread_mutex_lock(write_lock);
342 int32_t current_index = ex_write_index;
344 pthread_mutex_lock(&ex_in_use_mutex[current_index]);
345 while (ex_used[ex_write_index] == E_NOT_USED)
347 pthread_cond_wait(&ex_in_use_cond[ex_write_index], &ex_in_use_mutex[ex_write_index]);
350 ret = write_example(ex);
352 pthread_mutex_unlock(&ex_in_use_mutex[current_index]);
353 pthread_mutex_unlock(write_lock);
359 void CParseBuffer<T>::finalize_example(
bool free_after_release)
361 pthread_mutex_lock(read_lock);
362 pthread_mutex_lock(&ex_in_use_mutex[ex_read_index]);
363 ex_used[ex_read_index] = E_USED;
365 if (free_after_release)
367 SG_DEBUG(
"Freeing object in ring at index %d and address: %p.\n",
368 ex_read_index, ex_ring[ex_read_index].fv);
370 SG_FREE(ex_ring[ex_read_index].fv);
371 ex_ring[ex_read_index].fv=NULL;
374 pthread_cond_signal(&ex_in_use_cond[ex_read_index]);
375 pthread_mutex_unlock(&ex_in_use_mutex[ex_read_index]);
378 pthread_mutex_unlock(read_lock);
382 #endif // HAVE_PTHREAD
383 #endif // __PARSEBUFFER_H__
all of classes and functions are contained in the shogun namespace