00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_PKGS_MTX_DATABLOCK_CC_UTC20050626084022_DEFINED
00035 #define GROOVX_PKGS_MTX_DATABLOCK_CC_UTC20050626084022_DEFINED
00036
00037 #include "datablock.h"
00038
00039 #include "rutz/error.h"
00040
00041 #include <algorithm>
00042 #include <cstddef>
00043 #include <cstdlib>
00044 #include <cstring>
00045
00046 #include "rutz/debug.h"
00047 GVX_DBG_REGISTER
00048 #include "rutz/trace.h"
00049
00050 namespace
00051 {
00052 struct FreeNode
00053 {
00054 FreeNode* next;
00055 };
00056
00057 FreeNode* fs_free_list = 0;
00058
00059 class shared_data_block : public data_block
00060 {
00061 public:
00062 shared_data_block(int length);
00063 virtual ~shared_data_block();
00064
00065 virtual bool is_unique() const { return refcount() <= 1; }
00066 };
00067
00068 shared_data_block::shared_data_block(int length) :
00069 data_block(new double[length], length)
00070 {
00071 GVX_TRACE("shared_data_block::shared_data_block");
00072 dbg_eval(3, this); dbg_eval_nl(3, m_storage);
00073 }
00074
00075 shared_data_block::~shared_data_block()
00076 {
00077 GVX_TRACE("shared_data_block::~shared_data_block");
00078 dbg_eval(3, this); dbg_eval_nl(3, m_storage);
00079 delete [] m_storage;
00080 }
00081
00082 class borrowed_data_block : public data_block
00083 {
00084 public:
00085 borrowed_data_block(double* borrowed_data, unsigned int length) :
00086 data_block(borrowed_data, length)
00087 {}
00088
00089 virtual ~borrowed_data_block()
00090 { }
00091
00092
00093 virtual bool is_unique() const { return false; }
00094 };
00095
00096 class referred_data_block : public data_block
00097 {
00098 public:
00099 referred_data_block(double* referred_data, unsigned int length) :
00100 data_block(referred_data, length)
00101 {}
00102
00103 virtual ~referred_data_block()
00104 { }
00105
00106 virtual bool is_unique() const { return refcount() <= 1; }
00107 };
00108 }
00109
00110 void* data_block::operator new(size_t bytes)
00111 {
00112 GVX_TRACE("data_block::operator new");
00113
00114 GVX_ASSERT(bytes == sizeof(data_block));
00115 if (fs_free_list == 0)
00116 return ::operator new(bytes);
00117 FreeNode* node = fs_free_list;
00118 fs_free_list = fs_free_list->next;
00119 return (void*)node;
00120 }
00121
00122 void data_block::operator delete(void* space)
00123 {
00124 GVX_TRACE("data_block::operator delete");
00125
00126 ((FreeNode*)space)->next = fs_free_list;
00127 fs_free_list = (FreeNode*)space;
00128 }
00129
00130 data_block::data_block(double* data, unsigned int len) :
00131 m_refcount(0),
00132 m_storage(data),
00133 m_length(len)
00134 {
00135 GVX_TRACE("data_block::data_block");
00136 }
00137
00138 data_block::~data_block()
00139 {
00140 GVX_TRACE("data_block::~data_block");
00141 }
00142
00143 data_block* data_block::get_empty_data_block()
00144 {
00145 GVX_TRACE("data_block::get_empty_data_block");
00146 static data_block* empty_rep = 0;
00147 if (empty_rep == 0)
00148 {
00149 empty_rep = new shared_data_block(0);
00150 empty_rep->incr_refcount();
00151 }
00152
00153 return empty_rep;
00154 }
00155
00156 data_block* data_block::make_data_copy(const double* data, int data_length)
00157 {
00158 GVX_TRACE("data_block::make_data_copy");
00159 if (data == 0)
00160 return get_empty_data_block();
00161
00162 data_block* p = new shared_data_block(data_length);
00163
00164 memcpy(p->m_storage, data, data_length*sizeof(double));
00165
00166 return p;
00167 }
00168
00169 data_block* data_block::make_zeros(int length)
00170 {
00171 GVX_TRACE("data_block::make_zeros");
00172 if (length <= 0)
00173 return get_empty_data_block();
00174
00175 data_block* p = new shared_data_block(length);
00176 memset(p->m_storage, 0, length*sizeof(double));
00177
00178 return p;
00179 }
00180
00181 data_block* data_block::make_uninitialized(int length)
00182 {
00183 GVX_TRACE("data_block::make_uninitialized");
00184 if (length <= 0)
00185 return get_empty_data_block();
00186
00187 return new shared_data_block(length);
00188 }
00189
00190 data_block* data_block::make_borrowed(double* data, int data_length)
00191 {
00192 GVX_TRACE("data_block::make_borrowed");
00193 return new borrowed_data_block(data, data_length);
00194 }
00195
00196 data_block* data_block::make_referred(double* data, int data_length)
00197 {
00198 GVX_TRACE("data_block::make_referred");
00199 return new referred_data_block(data, data_length);
00200 }
00201
00202 data_block* data_block::make(double* data,
00203 int mrows, int ncols,
00204 mtx_policies::storage_policy s)
00205 {
00206 switch (s)
00207 {
00208 case mtx_policies::BORROW:
00209 return data_block::make_borrowed(data, mrows*ncols);
00210
00211 case mtx_policies::REFER:
00212 return data_block::make_referred(data, mrows*ncols);
00213
00214 case mtx_policies::COPY:
00215 default:
00216 break;
00217 }
00218
00219 return data_block::make_data_copy(data, mrows*ncols);
00220 }
00221
00222 data_block* data_block::make(int mrows, int ncols,
00223 mtx_policies::init_policy p)
00224 {
00225 if (p == mtx_policies::ZEROS)
00226 return data_block::make_zeros(mrows*ncols);
00227
00228 return data_block::make_uninitialized(mrows*ncols);
00229 }
00230
00231 void data_block::make_unique(data_block*& rep)
00232 {
00233 if (rep->is_unique()) return;
00234
00235 {
00236 GVX_TRACE("data_block::make_unique");
00237
00238 data_block* rep_copy = make_data_copy(rep->m_storage, rep->m_length);
00239
00240
00241
00242 rep->decr_refcount();
00243 rep_copy->incr_refcount();
00244
00245 rep = rep_copy;
00246
00247 GVX_POSTCONDITION(rep->m_refcount == 1);
00248 }
00249 }
00250
00252
00253
00254
00256
00257 data_holder::data_holder(double* data, int mrows, int ncols, storage_policy s) :
00258 m_data(data_block::make(data, mrows, ncols, s))
00259 {
00260 m_data->incr_refcount();
00261 }
00262
00263 data_holder::data_holder(int mrows, int ncols, init_policy p) :
00264 m_data(data_block::make(mrows, ncols, p))
00265 {
00266 m_data->incr_refcount();
00267 }
00268
00269 data_holder::data_holder(data_block* d) :
00270 m_data(d)
00271 {
00272 m_data->incr_refcount();
00273 }
00274
00275 data_holder::data_holder(const data_holder& other) :
00276 m_data(other.m_data)
00277 {
00278 m_data->incr_refcount();
00279 }
00280
00281 data_holder::~data_holder()
00282 {
00283 m_data->decr_refcount();
00284 }
00285
00286 void data_holder::swap(data_holder& other)
00287 {
00288 std::swap(m_data, other.m_data);
00289 }
00290
00292
00293
00294
00296
00297 void data_ref_holder::swap(data_ref_holder& other)
00298 {
00299 std::swap(m_ref, other.m_ref);
00300 }
00301
00302 static const char __attribute__((used)) vcid_groovx_pkgs_mtx_datablock_cc_utc20050626084022[] = "$Id: datablock.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00303 #endif // !GROOVX_PKGS_MTX_DATABLOCK_CC_UTC20050626084022_DEFINED