soma-io  5.1.2
allocator.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef SOMAIO_ALLOCATOR_ALLOCATOR_H
35 #define SOMAIO_ALLOCATOR_ALLOCATOR_H
36 //--- soma-io ----------------------------------------------------------------
40 //--- cartobase --------------------------------------------------------------
42 #include <cartobase/smart/rcptr.h>
43 //--- system -----------------------------------------------------------------
44 #include <memory>
45 #include <string>
46 //----------------------------------------------------------------------------
47 
48 namespace soma
49 {
50 
51  //==========================================================================
52  // L O W L E V E L A L L O C A T O R
53  //==========================================================================
63  {
64  public:
65  virtual ~LowLevelAllocator();
66 
67  virtual char *allocate( size_t n, size_t elemsize,
68  DataSource* datasource ) const = 0;
69  virtual void deallocate( char *ptr, size_t n, size_t elemsize ) const = 0;
70 
71  virtual bool canDuplicate() const { return true; }
72 
73  protected:
75  };
76 
77 
78  //==========================================================================
79  // M E M O R Y A L L O C A T O R
80  //==========================================================================
83  {
84  public:
85  virtual ~MemoryAllocator();
86 
87  virtual char *allocate( size_t n, size_t elemsize,
88  DataSource* datasource ) const;
89  virtual void deallocate( char *ptr, size_t n, size_t sz ) const;
90 
91  static const MemoryAllocator & singleton();
92 
93  private:
95  MemoryAllocator() : LowLevelAllocator() { _allocptr() = this; }
96 
97  static MemoryAllocator *& _allocptr();
98  };
99 
100 
101  //==========================================================================
102  // N U L L A L L O C A T O R
103  //==========================================================================
109  {
110  public:
111  virtual ~NullAllocator();
112 
113  virtual char *allocate( size_t n, size_t elemsize,
114  DataSource* datasource ) const;
115  virtual void deallocate( char *ptr, size_t n, size_t sz ) const;
116 
117  static const NullAllocator & singleton();
118 
119  private:
121  NullAllocator() : LowLevelAllocator() { _allocptr() = this; }
122 
123  static NullAllocator *& _allocptr();
124  };
125 
126 
127  std::ostream& operator << ( std::ostream& os,
128  const MemoryAllocator& thing );
129 
130  class AllocatorContext;
131 
132  //==========================================================================
133  // A L L O C A T O R S T R A T E G Y
134  //==========================================================================
151  {
152  public:
156  {
171  };
172 
174  {
175  // No memory mapping : loading on ram
178  // Memory mapping
180  // Memory mapping of a copy of the input file
183  // Memory mapping with reading only
186  // Memory mapping with reading and writing
189  // No allocation needed : data source is a buffer
191  };
192 
206  offset_t buflen,
207  const DataSource* datasource,
208  bool isDiskformatOK,
209  float usefactor = 1 );
210 
212  static bool isMMapCompatible( bool ascii, int byteorder,
213  bool scalefactored = false,
214  int border = 0 );
216  //static bool isMMapCompatible( const carto::AttributedObject & hdr );
217 
224  static void memSizes( offset_t & ram,
225  offset_t & freeram,
226  offset_t & swap );
227 
230 
232  };
233 
234 
235  //==========================================================================
236  // A L L O C A T O R C O N T E X T
237  //==========================================================================
261  {
262  public:
265 
269  bool isDiskformatOK = false,
270  float usefactor = 1 );
273  carto::rc_ptr<DataSourceInfo> datasourceinfo,
274  float usefactor = 1 );
277  const std::string & filename,
278  offset_t offset = 0,
279  bool isDiskformatOK = false,
280  float usefactor = 1 );
282  AllocatorContext( DataAccess mode, float usefactor );
289 
291  template<typename T> T* allocate( T*& ptr, size_t n ) const;
292  template<typename T> void deallocate( T* ptr, size_t n ) const;
293  bool canDuplicate() const;
295 
296  DataAccess accessMode() const { return _access; }
297  void setAccessMode( DataAccess mode );
298 
301  const carto::rc_ptr<DataSource> dataSource() const { return _datasource; }
302  carto::rc_ptr<DataSource> dataSource() { return _datasource; }
305  const carto::rc_ptr<DataSourceInfo> dataSourceInfo() const { return _dsi; }
307 
308  bool isAllocated() const { return _allocated; }
309  float useFactor() const;
310  void setUseFactor( float x );
311  bool allowsMemoryMapping() const;
312  void setAllowsMemoryMapping( bool x );
313 
314  // a static shared context for fast memory allocation
315  static const AllocatorContext & fast();
316 
317  private:
318  mutable const LowLevelAllocator *_alloc;
319  mutable carto::rc_ptr<DataSource> _datasource;
320  mutable carto::rc_ptr<DataSourceInfo> _dsi;
321  DataAccess _access;
322  bool _diskcompat;
323  float _usefact;
324  mutable bool _allocated;
325  mutable bool _forced;
326  };
327 
328  //==========================================================================
329  // A L L O C A T O R C O N T E X T : I N L I N E
330  //==========================================================================
331 
332  template<typename T>
333  inline T* AllocatorContext::allocate( T*& ptr, size_t n ) const
334  {
335  if( _allocated )
336  return ptr; // maybe throw an exception ?
337  _allocated = true;
338 
339  if( !_alloc || !_forced ) {
340  _forced = false;
342  = AllocatorStrategy::mappingMode( _access,
343  offset_t( n ) * sizeof( T ),
344  _datasource.get(),
345  _diskcompat,
346  _usefact );
348  }
349 
350  ptr = reinterpret_cast<T*>( _alloc->allocate( n, sizeof( T ), _datasource.get() ) );
351  #ifdef _MSC_VER
352  #warning uninitialized_fill_n not present in Microsoft standard includes
353  #else
354  // Don't initialize in mem'mapped allocators!
355  if( _alloc == &MemoryAllocator::singleton() )
356  std::uninitialized_fill_n( ptr, n, T() );
357  #endif
358  return ptr;
359  }
360 
361 
362  template<typename T>
363  inline void AllocatorContext::deallocate( T* ptr, size_t n ) const
364  {
365  if( !_allocated )
366  return;
367  _allocated = false;
368  if( _alloc == &MemoryAllocator::singleton() )
369  {
370 #if __cplusplus >= 201100
371  T* p = ptr;
372  std::allocator<T> a;
373  for( size_t i=0; i<n; ++i )
374  a.destroy( p++ );
375 #else
376  std::_Destroy( ptr, ptr + n );
377 #endif
378  }
379  _alloc->deallocate( reinterpret_cast<char*>( ptr ), n, sizeof( T ) );
380  }
381 
382 
384  {
385  return _diskcompat;
386  }
387 
388 
390  {
391  _diskcompat = x;
392  }
393 
394 }
395 
396 
397 #endif
Allocation context.
Definition: allocator.h:261
bool allowsMemoryMapping() const
Definition: allocator.h:383
void deallocate(T *ptr, size_t n) const
Definition: allocator.h:363
AllocatorContext(DataAccess mode, const std::string &filename, offset_t offset=0, bool isDiskformatOK=false, float usefactor=1)
Constructor from a filename.
float useFactor() const
AllocatorStrategy::DataAccess DataAccess
Definition: allocator.h:263
AllocatorContext & operator=(const AllocatorContext &)
MappingMode allocatorType() const
void setAllowsMemoryMapping(bool x)
Definition: allocator.h:389
carto::rc_ptr< DataSourceInfo > dataSourceInfo()
Definition: allocator.h:306
DataAccess accessMode() const
Definition: allocator.h:296
const carto::rc_ptr< DataSource > dataSource() const
Definition: allocator.h:301
T * allocate(T *&ptr, size_t n) const
return value is the same as modifiable input param ptr
Definition: allocator.h:333
void setDataSourceInfo(carto::rc_ptr< DataSourceInfo > dsi)
AllocatorContext becomes owner od datasourceinfo.
AllocatorContext(const AllocatorContext &)
Constructor by copy.
void setDataSource(carto::rc_ptr< DataSource > datasource)
AllocatorContext becomes owner of datasource.
bool isAllocated() const
Definition: allocator.h:308
AllocatorContext(const LowLevelAllocator *alloc)
Constructor from a LLA.
bool canDuplicate() const
static const AllocatorContext & fast()
AllocatorContext(DataAccess mode, float usefactor)
Constructor without pre-existing DataSource.
AllocatorContext(DataAccess mode, carto::rc_ptr< DataSourceInfo > datasourceinfo, float usefactor=1)
Constructor from a DataSourceInfo.
void setAccessMode(DataAccess mode)
AllocatorContext(DataAccess mode=AllocatorStrategy::InternalModif, carto::rc_ptr< DataSource > datasource=DataSource::none(), bool isDiskformatOK=false, float usefactor=1)
Constructor from a DataSource.
carto::rc_ptr< DataSource > dataSource()
Definition: allocator.h:302
AllocatorStrategy::MappingMode MappingMode
Definition: allocator.h:264
const carto::rc_ptr< DataSourceInfo > dataSourceInfo() const
Definition: allocator.h:305
void setUseFactor(float x)
Determination of the allocation type depending of the buffer size to allocate and the disk format of ...
Definition: allocator.h:151
static bool isMMapCompatible(bool ascii, int byteorder, bool scalefactored=false, int border=0)
helper function, tells if memory mapping is directly possible
static const LowLevelAllocator & lowLevelAllocator(MappingMode m)
static AllocatorContext allocator(MappingMode mode, carto::rc_ptr< DataSource > ds)
static void memSizes(offset_t &ram, offset_t &freeram, offset_t &swap)
same as above but uses a Header attributed object
DataAccess
Data access modes, they describe what you intend to do with data to be read.
Definition: allocator.h:156
@ ReadWrite
Mode for read/write access, the input file will be modified and needs read/write permissions.
Definition: allocator.h:167
@ NotOwner
This value is used for sub-volumes or fake volumes using data that are already allocated by another s...
Definition: allocator.h:170
@ InternalModif
Mode for internal modification.
Definition: allocator.h:162
@ ReadOnly
Mode for read-only access.
Definition: allocator.h:164
static MappingMode mappingMode(DataAccess mode, offset_t buflen, const DataSource *datasource, bool isDiskformatOK, float usefactor=1)
Determines optimal allocator for a data file.
Abstraction layer for various data sources (file, buffer, socket...).
Definition: datasource.h:65
static const carto::rc_ptr< DataSource > none()
An empty ref-counter that is more convenient than calling a constructor of rc_ptr<DataSource> (useful...
Abstract base class for actual allocators types.
Definition: allocator.h:63
virtual char * allocate(size_t n, size_t elemsize, DataSource *datasource) const =0
virtual bool canDuplicate() const
Definition: allocator.h:71
virtual void deallocate(char *ptr, size_t n, size_t elemsize) const =0
Normal allocation mode: allocation in main memory.
Definition: allocator.h:83
virtual char * allocate(size_t n, size_t elemsize, DataSource *datasource) const
static const MemoryAllocator & singleton()
virtual ~MemoryAllocator()
virtual void deallocate(char *ptr, size_t n, size_t sz) const
This allocator doesn't allocate anything.
Definition: allocator.h:109
virtual void deallocate(char *ptr, size_t n, size_t sz) const
virtual char * allocate(size_t n, size_t elemsize, DataSource *datasource) const
virtual ~NullAllocator()
static const NullAllocator & singleton()
Definition: allocator.h:49
std::ostream & operator<<(std::ostream &os, const MemoryAllocator &thing)
unsigned long long offset_t
Offsets are 64 bits if supported.
Definition: datasource.h:51