SGReferencedData.h

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Copyright (C) 2012 Soeren Sonnenburg
00008  */
00009 #ifndef __SGREFERENCED_DATA_H__
00010 #define __SGREFERENCED_DATA_H__
00011 
00012 #include <shogun/io/SGIO.h>
00013 #include <shogun/base/Parallel.h>
00014 
00015 #ifdef HAVE_PTHREAD
00016 #include <pthread.h>
00017 #endif
00018 
00020 struct refcount_t 
00021 {
00023     int32_t rc;
00024 #ifdef HAVE_PTHREAD
00025 
00026     PTHREAD_LOCK_T lock;
00027 #endif
00028 };
00029 
00030 namespace shogun
00031 {
00033 class SGReferencedData
00034 {
00035     public:
00037         SGReferencedData(bool ref_counting=true) : m_refcount(NULL)
00038         { 
00039             if (ref_counting)
00040             {
00041                 m_refcount = SG_CALLOC(refcount_t, 1);
00042                 PTHREAD_LOCK_INIT(&m_refcount->lock);
00043             }
00044 
00045             ref();
00046         }
00047 
00049         SGReferencedData(const SGReferencedData &orig)
00050             : m_refcount(orig.m_refcount)
00051         {
00052             ref();
00053         }
00054 
00056         SGReferencedData& operator= (const SGReferencedData &orig)
00057         {
00058             if (this == &orig)
00059                 return *this;
00060 
00061             unref();
00062             copy_data(orig);
00063             copy_refcount(orig);
00064             ref();
00065             return *this;
00066         }
00067 
00073         virtual ~SGReferencedData()
00074         {
00075         }
00076 
00081         int32_t ref_count()
00082         {
00083             if (m_refcount == NULL)
00084                 return -1;
00085 
00086 #ifdef HAVE_PTHREAD
00087             PTHREAD_LOCK(&m_refcount->lock);
00088 #endif
00089             int32_t c = m_refcount->rc;
00090 #ifdef HAVE_PTHREAD
00091             PTHREAD_UNLOCK(&m_refcount->lock);
00092 #endif 
00093 
00094 #ifdef DEBUG_SGVECTOR
00095             SG_SGCDEBUG("ref_count(): refcount %d, data %p\n", c, this);
00096 #endif
00097             return c;
00098         }
00099 
00100     protected:
00102         void copy_refcount(const SGReferencedData &orig)
00103         {
00104             m_refcount=orig.m_refcount;
00105         }
00106 
00111         int32_t ref()
00112         {
00113             if (m_refcount == NULL)
00114             {
00115                 return -1;
00116             }
00117 
00118 #ifdef HAVE_PTHREAD
00119             PTHREAD_LOCK(&m_refcount->lock);
00120 #endif
00121             int32_t c = ++(m_refcount->rc);
00122 #ifdef HAVE_PTHREAD
00123             PTHREAD_UNLOCK(&m_refcount->lock);
00124 #endif 
00125 #ifdef DEBUG_SGVECTOR
00126             SG_SGCDEBUG("ref() refcount %ld data %p increased\n", c, this);
00127 #endif
00128             return c;
00129         }
00130 
00136         int32_t unref()
00137         {
00138             if (m_refcount == NULL)
00139             {
00140                 init_data();
00141                 m_refcount=NULL;
00142                 return -1;
00143             }
00144 
00145 #ifdef HAVE_PTHREAD
00146             PTHREAD_LOCK(&m_refcount->lock);
00147 #endif
00148             int32_t c = --(m_refcount->rc);
00149 #ifdef HAVE_PTHREAD
00150             PTHREAD_UNLOCK(&m_refcount->lock);
00151 #endif 
00152             if (c<=0)
00153             {
00154 #ifdef DEBUG_SGVECTOR
00155                 SG_SGCDEBUG("unref() refcount %d data %p destroying\n", c, this);
00156 #endif
00157                 free_data();
00158 #ifdef HAVE_PTHREAD
00159             PTHREAD_LOCK_DESTROY(&m_refcount->lock);
00160 #endif
00161                 SG_FREE(m_refcount);
00162                 m_refcount=NULL;
00163                 return 0;
00164             }
00165             else
00166             {
00167 #ifdef DEBUG_SGVECTOR
00168                 SG_SGCDEBUG("unref() refcount %d data %p decreased\n", c, this);
00169 #endif
00170                 init_data();
00171                 m_refcount=NULL;
00172                 return c;
00173             }
00174         }
00175 
00177         virtual void copy_data(const SGReferencedData &orig)=0;
00178 
00180         virtual void init_data()=0;
00181 
00183         virtual void free_data()=0;
00184 
00185     private:
00186 
00188         refcount_t* m_refcount;
00189 };
00190 }
00191 #endif // __SGREFERENCED_DATA_H__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation