SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SGReferencedData.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Copyright (C) 2012 Soeren Sonnenburg
8  */
9 #ifndef __SGREFERENCED_DATA_H__
10 #define __SGREFERENCED_DATA_H__
11 
12 #include <shogun/io/SGIO.h>
13 #include <shogun/base/Parallel.h>
14 
15 #ifdef HAVE_PTHREAD
16 #include <pthread.h>
17 #endif
18 
20 struct refcount_t
21 {
23  int32_t rc;
24 #ifdef HAVE_PTHREAD
25 
26  PTHREAD_LOCK_T lock;
27 #endif
28 };
29 
30 namespace shogun
31 {
34 {
35  public:
37  SGReferencedData(bool ref_counting=true) : m_refcount(NULL)
38  {
39  if (ref_counting)
40  {
41  m_refcount = SG_CALLOC(refcount_t, 1);
42  PTHREAD_LOCK_INIT(&m_refcount->lock);
43  }
44 
45  ref();
46  }
47 
50  : m_refcount(orig.m_refcount)
51  {
52  ref();
53  }
54 
57  {
58  if (this == &orig)
59  return *this;
60 
61  unref();
62  copy_data(orig);
63  copy_refcount(orig);
64  ref();
65  return *this;
66  }
67 
74  {
75  }
76 
81  int32_t ref_count()
82  {
83  if (m_refcount == NULL)
84  return -1;
85 
86 #ifdef HAVE_PTHREAD
87  PTHREAD_LOCK(&m_refcount->lock);
88 #endif
89  int32_t c = m_refcount->rc;
90 #ifdef HAVE_PTHREAD
91  PTHREAD_UNLOCK(&m_refcount->lock);
92 #endif
93 
94 #ifdef DEBUG_SGVECTOR
95  SG_SGCDEBUG("ref_count(): refcount %d, data %p\n", c, this);
96 #endif
97  return c;
98  }
99 
100  protected:
102  void copy_refcount(const SGReferencedData &orig)
103  {
104  m_refcount=orig.m_refcount;
105  }
106 
111  int32_t ref()
112  {
113  if (m_refcount == NULL)
114  {
115  return -1;
116  }
117 
118 #ifdef HAVE_PTHREAD
119  PTHREAD_LOCK(&m_refcount->lock);
120 #endif
121  int32_t c = ++(m_refcount->rc);
122 #ifdef HAVE_PTHREAD
123  PTHREAD_UNLOCK(&m_refcount->lock);
124 #endif
125 #ifdef DEBUG_SGVECTOR
126  SG_SGCDEBUG("ref() refcount %ld data %p increased\n", c, this);
127 #endif
128  return c;
129  }
130 
136  int32_t unref()
137  {
138  if (m_refcount == NULL)
139  {
140  init_data();
141  m_refcount=NULL;
142  return -1;
143  }
144 
145 #ifdef HAVE_PTHREAD
146  PTHREAD_LOCK(&m_refcount->lock);
147 #endif
148  int32_t c = --(m_refcount->rc);
149 #ifdef HAVE_PTHREAD
150  PTHREAD_UNLOCK(&m_refcount->lock);
151 #endif
152  if (c<=0)
153  {
154 #ifdef DEBUG_SGVECTOR
155  SG_SGCDEBUG("unref() refcount %d data %p destroying\n", c, this);
156 #endif
157  free_data();
158 #ifdef HAVE_PTHREAD
159  PTHREAD_LOCK_DESTROY(&m_refcount->lock);
160 #endif
161  SG_FREE(m_refcount);
162  m_refcount=NULL;
163  return 0;
164  }
165  else
166  {
167 #ifdef DEBUG_SGVECTOR
168  SG_SGCDEBUG("unref() refcount %d data %p decreased\n", c, this);
169 #endif
170  init_data();
171  m_refcount=NULL;
172  return c;
173  }
174  }
175 
177  virtual void copy_data(const SGReferencedData &orig)=0;
178 
180  virtual void init_data()=0;
181 
183  virtual void free_data()=0;
184 
185  private:
186 
188  refcount_t* m_refcount;
189 };
190 }
191 #endif // __SGREFERENCED_DATA_H__

SHOGUN Machine Learning Toolbox - Documentation