Salome HOME
Some factorization before integration of ParaMEDMEM into medcoupling python module
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingRefCountObject.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingRefCountObject.hxx"
22 #include "MEDCoupling_version.h"
23
24 #include "InterpKernelException.hxx"
25
26 #include <sstream>
27 #include <algorithm>
28
29 using namespace MEDCoupling;
30
31 GlobalDict *GlobalDict::UNIQUE_INSTANCE=0;
32
33 const char *MEDCoupling::MEDCouplingVersionStr()
34 {
35   return MEDCOUPLING_VERSION_STR;
36 }
37
38 int MEDCoupling::MEDCouplingVersion()
39 {
40   return MEDCOUPLING_VERSION;
41 }
42
43 void MEDCoupling::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas)
44 {
45   int ver=MEDCOUPLING_VERSION;
46   maj=(ver & 0xFF0000) >> 16;
47   minor=(ver & 0xFF00) >> 8;
48   releas=(ver & 0xFF);
49 }
50
51 int MEDCoupling::MEDCouplingSizeOfVoidStar()
52 {
53   return 8*sizeof(std::size_t);
54 }
55
56 /*!
57  * If true is returned it is a LittleEndian machine.
58  * If false it is a BigEndian machine.
59  * \return the coding mode of integers of the machine.
60  */
61 bool MEDCoupling::MEDCouplingByteOrder()
62 {
63   unsigned int x(1);
64   unsigned char *xc(reinterpret_cast<unsigned char *>(&x));
65   return xc[0]==1;
66 }
67
68 const char *MEDCoupling::MEDCouplingByteOrderStr()
69 {
70   static const char LITTLEENDIAN_STR[]="LittleEndian";
71   static const char BIGENDIAN_STR[]="BigEndian";
72   if(MEDCouplingByteOrder())
73     return LITTLEENDIAN_STR;
74   else
75     return BIGENDIAN_STR;
76 }
77
78 //=
79
80 std::size_t BigMemoryObject::getHeapMemorySize() const
81 {
82   std::size_t ret(getHeapMemorySizeWithoutChildren());
83   std::vector<const BigMemoryObject *> v(getDirectChildren());
84   std::set<const BigMemoryObject *> s1,s2(v.begin(),v.end());
85   return ret+GetHeapMemoryOfSet(s1,s2);
86 }
87
88 /*!
89  * This method returns all the progeny of \a this (this is \b not included in returned vector).
90  * All the progeny means all the subobjects (children), subsubobjects (little children), ... of \a this.
91  * The elements in returned array are reported only once even if they appear several times in the progeny of \a this.
92  */
93 std::vector<const BigMemoryObject *> BigMemoryObject::getAllTheProgeny() const
94 {
95   std::vector<const BigMemoryObject *> s1(getDirectChildren());
96   std::vector<const BigMemoryObject *> ret;
97   while(!s1.empty())
98     {
99       ret.insert(ret.end(),s1.begin(),s1.end());
100       std::vector<const BigMemoryObject *> s3;
101       for(std::vector<const BigMemoryObject *>::const_iterator it0=s1.begin();it0!=s1.end();it0++)
102         {
103           std::vector<const BigMemoryObject *> s2;
104           if(*it0)
105             s2=(*it0)->getDirectChildren();
106           for(std::vector<const BigMemoryObject *>::const_iterator it1=s2.begin();it1!=s2.end();it1++)
107             {
108               if(*it1)
109                 if(std::find(ret.begin(),ret.end(),*it1)==ret.end())
110                   s3.push_back(*it1);
111             }
112         }
113       s1=s3;
114     }
115   return ret;
116 }
117
118 /*!
119  * This method scan all the progeny of \a this (\a this excluded) to see if \a obj is part of it.
120  * If obj is NULL false is returned.
121  * \sa BigMemoryObject::getAllTheProgeny
122  */
123 bool BigMemoryObject::isObjectInTheProgeny(const BigMemoryObject *obj) const
124 {
125   if(!obj)
126     return false;
127   std::vector<const BigMemoryObject *> objs(getAllTheProgeny());
128   return std::find(objs.begin(),objs.end(),obj)!=objs.end();
129 }
130
131 std::size_t BigMemoryObject::GetHeapMemorySizeOfObjs(const std::vector<const BigMemoryObject *>& objs)
132 {
133   std::size_t ret(0);
134   std::set<const BigMemoryObject *> s1,s2;
135   for(std::vector<const BigMemoryObject *>::const_iterator it0=objs.begin();it0!=objs.end();it0++)
136     {
137       if(*it0)
138         if(s1.find(*it0)==s1.end())
139           {
140             std::vector<const BigMemoryObject *> vTmp((*it0)->getDirectChildren());
141             s2.insert(vTmp.begin(),vTmp.end());
142             ret+=(*it0)->getHeapMemorySizeWithoutChildren();
143             s1.insert(*it0);
144           }
145     }
146   return ret+GetHeapMemoryOfSet(s1,s2);
147 }
148
149 std::size_t BigMemoryObject::GetHeapMemoryOfSet(std::set<const BigMemoryObject *>& s1, std::set<const BigMemoryObject *>& s2)
150 {
151   std::size_t ret(0);
152   while(!s2.empty())
153     {
154       std::set<const BigMemoryObject *> s3;
155       for(std::set<const BigMemoryObject *>::const_iterator it=s2.begin();it!=s2.end();it++)
156         {
157           if(s1.find(*it)==s1.end())
158             {
159               ret+=(*it)->getHeapMemorySizeWithoutChildren();
160               s1.insert(*it);
161               std::vector<const BigMemoryObject *> v2((*it)->getDirectChildren());
162               for(std::vector<const BigMemoryObject *>::const_iterator it2=v2.begin();it2!=v2.end();it2++)
163                 if(s1.find(*it2)==s1.end())
164                   s3.insert(*it2);
165             }
166         }
167       s2=s3;
168     }
169   return ret;
170 }
171
172 std::string BigMemoryObject::getHeapMemorySizeStr() const
173 {
174   static const char *UNITS[4]={"B","kB","MB","GB"};
175   std::size_t m(getHeapMemorySize());
176   std::ostringstream oss; oss.precision(3);
177   std::size_t remain(0);
178   int i(0);
179   for(;i<4;i++)
180     {
181       if(m<1024)
182         {
183           oss << m;
184           if(remain!=0)
185             {
186               std::ostringstream oss2; oss2 << std::fixed << ((double)remain)/1024.;
187               std::string s(oss2.str());
188               s=s.substr(1,4);
189               std::size_t pos(s.find_last_not_of('0'));
190               if(pos==4)
191                 oss << s;
192               else
193                 oss << s.substr(0,pos+1);
194             }
195           oss << " " << UNITS[i];
196           break;
197         }
198       else
199         {
200           if(i!=3)
201             {
202               remain=(m%1024);
203               m/=1024;
204             }
205         }
206     }
207   if(i==4)
208     oss << m << " " << UNITS[3];
209   return oss.str();
210 }
211
212 std::vector<const BigMemoryObject *> BigMemoryObject::getDirectChildren() const
213 {
214   std::vector<const BigMemoryObject *> ret;
215   std::vector<const BigMemoryObject *> retWithNull(getDirectChildrenWithNull());
216   for(std::vector<const BigMemoryObject *>::const_iterator it=retWithNull.begin();it!=retWithNull.end();it++)
217     if(*it)
218       ret.push_back(*it);
219   return ret;
220 }
221
222 BigMemoryObject::~BigMemoryObject()
223 {
224 }
225
226 //=
227
228 RefCountObjectOnly::RefCountObjectOnly():_cnt(1)
229 {
230 }
231
232 RefCountObjectOnly::RefCountObjectOnly(const RefCountObjectOnly& other):_cnt(1)
233 {
234 }
235
236 bool RefCountObjectOnly::decrRef() const
237 {
238   bool ret=((--_cnt)==0);
239   if(ret)
240     delete this;
241   return ret;
242 }
243
244 void RefCountObjectOnly::incrRef() const
245 {
246   _cnt++;
247 }
248
249 int RefCountObjectOnly::getRCValue() const
250 {
251   return _cnt;
252 }
253
254 RefCountObjectOnly::~RefCountObjectOnly()
255 {
256 }
257
258 /*!
259  * Do nothing here ! It is not a bug ( I hope :) ) because all subclasses that
260  * copies using operator= should not copy the ref counter of \a other !
261  */
262 RefCountObjectOnly& RefCountObjectOnly::operator=(const RefCountObjectOnly& other)
263 {
264   return *this;
265 }
266
267 //=
268
269 RefCountObject::RefCountObject()
270 {
271 }
272
273 RefCountObject::RefCountObject(const RefCountObject& other):RefCountObjectOnly(other)
274 {
275 }
276
277 RefCountObject::~RefCountObject()
278 {
279 }
280
281 //=
282
283 GlobalDict *GlobalDict::GetInstance()
284 {
285   if(!UNIQUE_INSTANCE)
286     UNIQUE_INSTANCE=new GlobalDict;
287   return UNIQUE_INSTANCE;
288 }
289
290 bool GlobalDict::hasKey(const std::string& key) const
291 {
292   std::map<std::string, std::string>::const_iterator it(_my_map.find(key));
293   return it!=_my_map.end();
294 }
295
296 std::string GlobalDict::value(const std::string& key) const
297 {
298   std::map<std::string, std::string>::const_iterator it(_my_map.find(key));
299   if(it==_my_map.end())
300     {
301       std::ostringstream oss;
302       oss << "GlobalDict::value : key \"" << key << "\" is not in map !";
303       throw INTERP_KERNEL::Exception(oss.str().c_str());
304     }
305   return (*it).second;
306 }
307
308 std::vector<std::string> GlobalDict::keys() const
309 {
310   std::vector<std::string> ret;
311   for(std::map<std::string, std::string>::const_iterator it=_my_map.begin();it!=_my_map.end();it++)
312     ret.push_back((*it).first);
313   return ret;
314 }
315
316 void GlobalDict::erase(const std::string& key)
317 {
318   std::map<std::string, std::string>::iterator it(_my_map.find(key));
319   if(it==_my_map.end())
320     {
321       std::ostringstream oss;
322       oss << "GlobalDict::erase : key \"" << key << "\" is not in map !";
323       throw INTERP_KERNEL::Exception(oss.str().c_str());
324     }
325   _my_map.erase(it);
326 }
327
328 void GlobalDict::clear()
329 {
330   _my_map.clear();
331 }
332
333 void GlobalDict::setKeyValue(const std::string& key, const std::string& val)
334 {
335   std::map<std::string, std::string>::const_iterator it(_my_map.find(key));
336   if(it!=_my_map.end())
337     {
338       std::ostringstream oss;
339       oss << "GlobalDict::setKeyValue : key \"" << key << "\" already exists !";
340       throw INTERP_KERNEL::Exception(oss.str().c_str());
341     }
342   _my_map[key]=val;
343 }
344
345 void GlobalDict::setKeyValueForce(const std::string& key, const std::string& val)
346 {
347   _my_map[key]=val;
348 }
349
350 std::string GlobalDict::printSelf() const
351 {
352   std::ostringstream oss;
353   for(std::map<std::string, std::string>::const_iterator it=_my_map.begin();it!=_my_map.end();it++)
354     {
355       oss << "(" << (*it).first << "," << (*it).second << ")" << std::endl;
356     }
357   return oss.str();
358 }