dune-fem  2.8-git
persistencemanager.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
2 #define DUNE_FEM_PERSISTENCEMANAGER_HH
3 
4 #include <fstream>
5 #include <iostream>
6 #include <list>
7 #include <sstream>
8 #include <string>
9 #include <type_traits>
10 #include <utility>
11 
13 #include <dune/fem/io/parameter.hh>
17 
18 namespace Dune
19 {
20 
21  namespace Fem
22  {
23 
94  class PersistenceManager;
95 
101  {
102  typedef PersistentObject ThisType;
103 
104  friend class PersistenceManager;
105 
106  public:
107  virtual ~PersistentObject() {}
109  virtual void backup () const = 0;
111  virtual void restore () = 0;
112 
113  protected:
115  virtual void insertSubData() {}
117  virtual void removeSubData() {}
118 
119  virtual void *pointer ()
120  {
121  return this;
122  }
123  };
124 
125 
126 
127  template< class ObjectType >
129  {
130  static const bool value = std::is_convertible< ObjectType *, PersistentObject * >::value;
131  };
132 
133 
134 
141  {
143  template <class ObjectType,bool isPersistent>
144  struct WrapObject;
145 
146  public:
147  // make backup and restore streams exchangeable
148 #ifdef FEM_PERSISTENCEMANAGERSTREAMTRAITS
149  typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: BackupStreamType BackupStreamType;
150  typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: RestoreStreamType RestoreStreamType;
151  static const bool singleBackupRestoreFile = FEM_PERSISTENCEMANAGERSTREAMTRAITS ::
152  singleBackupRestoreFile ;
153 #else
154  typedef Fem :: BinaryFileOutStream BackupStreamType ;
155  typedef Fem :: BinaryFileInStream RestoreStreamType ;
156  static const bool singleBackupRestoreFile = false ;
157 #endif
158 
159  private:
160  typedef std::list< std::pair< PersistentObject *, unsigned int > > PersistentType;
161  typedef PersistentType::iterator IteratorType;
162 
163  PersistentType objects_;
164  int fileCounter_,lineNo_;
165  std::string path_;
166  std::ifstream inAsciStream_;
167  std::ofstream outAsciStream_;
168  bool closed_,invalid_;
169 
170  BackupStreamType* backupStream_;
171  RestoreStreamType* restoreStream_;
172 
174  : fileCounter_( 0 ),
175  lineNo_(),
176  path_(),
177  closed_( false ),
178  invalid_( false ),
179  backupStream_( 0 ),
180  restoreStream_( 0 )
181  {}
182 
183  PersistenceManager ( const ThisType & );
184  ThisType &operator= ( const ThisType & );
185 
186  BackupStreamType& backupStreamObj ()
187  {
188  assert( backupStream_ );
189  return *backupStream_ ;
190  }
191 
192  RestoreStreamType& restoreStreamObj ()
193  {
194  assert( restoreStream_ );
195  return *restoreStream_ ;
196  }
197 
198  public:
199  template< class ObjectType >
200  void insertObject( ObjectType &object, const bool pushFront = false )
201  {
202  IteratorType end = objects_.end();
203  for( IteratorType it = objects_.begin(); it != end; ++it )
204  {
205  if( it->first->pointer() != &object )
206  continue;
207  ++it->second;
208  return;
209  }
210 
211  // for objects like the grid
212  // we need to allow to add this later
213  if ( closed_ && ! pushFront )
214  {
215 #ifndef NDEBUG
216  std::cerr << "WARNING: new object added to PersistenceManager "
217  << "although backup/restore has been called - "
218  << "Object will be ignored!" << std::endl;
219 #endif
220  return;
221  }
222 
223  PersistentObject *obj =
224  WrapObject< ObjectType, IsPersistent< ObjectType > :: value >
225  :: apply( object );
226 
227  // insert possible sub data
228  obj->insertSubData();
229 
230  if( pushFront )
231  objects_.push_front( std :: make_pair( obj, 1 ) );
232  else
233  objects_.push_back( std :: make_pair( obj, 1 ) );
234  }
235 
236  template< class ObjectType >
237  void removeObject ( ObjectType &object )
238  {
239  IteratorType end = objects_.end();
240  for( IteratorType it = objects_.begin(); it != end; ++it )
241  {
242  if( it->first->pointer() != &object )
243  continue;
244 
245  --it->second;
246  if( it->second == 0 )
247  {
248  if (closed_) invalid_=true;
249  PersistentObject *obj = it->first;
250  // remove possible sub data
251  obj->removeSubData();
252  objects_.erase( it );
254  delete obj;
255  }
256  return;
257  }
258  }
259 
260  void backupObjects ( const std::string& path )
261  {
262  if( invalid_ )
263  {
264 #ifndef NDEBUG
265  std::cerr << "WARNING: backup called although objects "
266  << "have been removed from the PersistenceManager! "
267  << "Backup ignored!" << std::endl;
268 #endif
269  return;
270  }
271  closed_ = true;
272  startBackup( path );
273  typedef PersistentType::iterator IteratorType;
274 
275  for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
276  it->first->backup();
277 
278  closeStreams();
279  }
280 
281  void restoreObjects ( const std::string &path )
282  {
283  if (invalid_) {
284 #ifndef NDEBUG
285  std::cerr << "WARNING: restore called although objects "
286  << "have been removed from the PersistenceManager! "
287  << "Restore ignored!" << std::endl;
288 #endif
289  return;
290  }
291  closed_ = true;
292  startRestoreImpl( path );
293  typedef PersistentType :: iterator IteratorType;
294 
295  for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
296  it->first->restore( );
297 
298  closeStreams();
299  }
300 
301  std::string getUniqueFileName ( const std::string &tag )
302  {
303  return generateFilename( path_ + "/" + tag, ++fileCounter_ );
304  }
305 
306  std::string getUniqueTag ( const std::string &tag )
307  {
308  return generateFilename( tag, ++fileCounter_ );
309  }
310 
311  template< class T >
312  void backup ( const std::string &token, const T &value )
313  {
314  backupStreamObj() << token;
315  backupStreamObj() << value;
316  }
317 
318  template< class T >
319  void restore ( const std::string &token, T &value )
320  {
321  std::string readToken ;
322  restoreStreamObj() >> readToken;
323  restoreStreamObj() >> value;
324  if( token != readToken )
325  {
326  DUNE_THROW(InvalidStateException,"wrong object restored in PersistenceManager" << token << " " << readToken );
327  }
328  }
329 
331  void reset()
332  {
333  closeStreams(); // flush and close streams
334  objects_.clear(); // clear all objects
335  path_.clear();
336  lineNo_ = 0;
337  closed_ = false;
338  invalid_ = false;
339  }
340 
341  public:
343 
345  {
347  }
348 
350  {
351  return instance ().backupStreamObj();
352  }
353 
355  {
356  return instance ().restoreStreamObj();
357  }
358 
359  static void insert ( PersistentObject &object, const bool pushFront = false )
360  {
361  instance().insertObject( object, pushFront );
362  }
363 
364  static void remove ( PersistentObject &object )
365  {
366  instance().removeObject( object );
367  }
368 
369  static void backup ( const std::string& path )
370  {
372  }
373 
374  static void restore ( const std::string& path )
375  {
377  }
378 
379  static void startRestore ( const std::string& path )
380  {
381  instance().startRestoreImpl( path );
382  }
383 
384  static std::string uniqueFileName(const std::string& tag = "" )
385  {
386  return instance().getUniqueFileName( tag );
387  }
388 
389  static std::string uniqueTag(const std::string& tag = "" )
390  {
391  return instance().getUniqueTag( tag );
392  }
393 
394  template< class T >
395  static void backupValue ( const std::string &token, const T &value )
396  {
397  instance().backup( token, value );
398  }
399 
400  template< class T >
401  static void restoreValue ( const std::string &token, T &value )
402  {
403  instance().restore( token, value );
404  }
405 
406  private:
407  const char* myTag() const { return "persistentobjects"; }
408 
409  // create filename for persistent objects
410  std::string createFilename( const std::string& path,
411  const int rank,
412  const int size ) const
413  {
414  std::stringstream s;
415  const int number = ( singleBackupRestoreFile ) ? size : rank ;
416  s << path << myTag() << "." << number ;
417  return s.str();
418  }
419 
420  void startBackup ( const std::string &path )
421  {
422  path_ = path + "/";
423 
424  if( createDirectory( path_ ) )
425  {
426  const int rank = MPIManager :: rank() ;
427  const int size = MPIManager :: size() ;
428  std::string filename( createFilename( path_, rank, size ) );
429 
430  assert( backupStream_ == 0 );
431  backupStream_ = Fem :: StreamFactory<BackupStreamType> :: create( filename );
432 
433  if( rank == 0 )
434  {
435  std::ofstream paramfile( (path_ + "parameter").c_str() );
436  if( paramfile )
437  {
438  // write parameters on rank 0
439  Parameter::write( paramfile, true );
440  }
441  }
442  }
443  else
444  std::cerr << "Error: Unable to create '" << path_ << "'" << std::endl;
445  }
446 
447  void startRestoreImpl ( const std::string &path )
448  {
449  if( restoreStream_ == 0 )
450  {
451  path_ = path + "/";
452  const int rank = MPIManager :: rank();
453  const int size = MPIManager :: size();
454  std::string filename( createFilename( path_, rank, size ) );
455  // create strema with stream factory
456  restoreStream_ = Fem :: StreamFactory<RestoreStreamType> :: create( filename );
457 
458  if( Parameter :: verbose () )
459  std::cout << "Restore from " << filename << std::endl;
460 
461  if( ! restoreStream_ )
462  {
463  std::cout << "Error opening global stream: " << path_+myTag()
464  << std::endl;
465  abort();
466  }
467 
468  // restore parameter
470  Parameter::append(path_ + "parameter");
471  }
472  }
473 
474  void closeStreams ()
475  {
476  if( backupStream_ )
477  {
478  backupStream_->flush();
479  delete backupStream_;
480  backupStream_ = 0;
481  }
482 
483  if( restoreStream_ )
484  {
485  delete restoreStream_;
486  restoreStream_ = 0;
487  }
488  }
489  };
490 
491 
492  // !!!! not accessable outside namespace Dune::Fem ?!?!?!
493  namespace
494  {
495  PersistenceManager &persistenceManager __attribute__((unused)) = PersistenceManager::instance();
496  }
497 
498 
499  template< class ObjectType >
501  operator<< ( PersistenceManager &pm, ObjectType &object )
502  {
503  static_assert( !std::is_pointer< ObjectType >::value, "Do not add pointers to PersistenceManager." );
504  pm.insertObject( object );
505  return pm;
506  }
507 
508 
509  template< class ObjectType >
510  inline PersistenceManager &
511  operator>> ( PersistenceManager &pm, ObjectType &object )
512  {
513  pm.removeObject( object );
514  return pm;
515  }
516 
517 
518  template< class ObjectType >
519  struct PersistenceManager::WrapObject< ObjectType, true >
520  {
521  static PersistentObject *apply( ObjectType &obj )
522  {
523  return &obj;
524  }
525  };
526 
527 
528  template< class ObjectType >
529  struct PersistenceManager::WrapObject< ObjectType, false >
530  : public PersistentObject
531  {
534 
535  protected:
536  ObjectType& obj_;
537  std::string token_;
538 
539  WrapObject( ObjectType &obj )
540  : obj_( obj ),
541  // store unique token of this object
542  token_( "_token"+PersistenceManager::uniqueTag() )
543  {}
544 
545  public:
546  virtual ~WrapObject ()
547  {}
548 
549  virtual void backup () const
550  {
551  PersistenceManager::backupValue( token_, obj_ );
552  }
553 
554  virtual void restore ()
555  {
556  PersistenceManager::restoreValue( token_, obj_ );
557  }
558 
559  protected:
560  virtual void *pointer ()
561  {
562  return &obj_;
563  }
564 
565  public:
566  static PersistentObject *apply ( ObjectType &obj )
567  {
568  return new ThisType( obj );
569  }
570  };
571 
572 
573 
579  : public PersistentObject
580  {
582  typedef PersistentObject BaseType;
583 
584  protected:
586  {
588  }
589 
591  {
593  }
594 
596  {
598  }
599  };
600 
601  } // end namespace Fem
602 
603 } // end namespace Dune
604 
605 #endif // #ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
std::string path
Definition: readioparams.cc:156
Definition: bindguard.hh:11
OutStreamInterface< StreamTraits > & operator<<(OutStreamInterface< StreamTraits > &out, const DiscreteFunctionInterface< Impl > &df)
write a discrete function into an output stream
Definition: discretefunction_inline.hh:397
bool createDirectory(const std::string &inName)
create a directory
Definition: io.cc:19
std::string generateFilename(const std::string &fn, int ntime, int precision=6)
Definition: iointerface.hh:47
InStreamInterface< StreamTraits > & operator>>(InStreamInterface< StreamTraits > &in, DiscreteFunctionInterface< Impl > &df)
read a discrete function from an input stream
Definition: discretefunction_inline.hh:417
base class for persistent objects
Definition: persistencemanager.hh:101
virtual void insertSubData()
insert possible sub data of object
Definition: persistencemanager.hh:115
virtual ~PersistentObject()
Definition: persistencemanager.hh:107
virtual void backup() const =0
backup persistent object
virtual void * pointer()
Definition: persistencemanager.hh:119
virtual void restore()=0
restore persistent object
virtual void removeSubData()
remove possible sub data of object
Definition: persistencemanager.hh:117
Definition: persistencemanager.hh:129
static const bool value
Definition: persistencemanager.hh:130
class with singleton instance managing all persistent objects
Definition: persistencemanager.hh:141
void removeObject(ObjectType &object)
Definition: persistencemanager.hh:237
static void remove(PersistentObject &object)
Definition: persistencemanager.hh:364
std::string getUniqueTag(const std::string &tag)
Definition: persistencemanager.hh:306
Fem ::BinaryFileOutStream BackupStreamType
Definition: persistencemanager.hh:144
static PersistenceManager & instance()
Definition: persistencemanager.hh:344
void backup(const std::string &token, const T &value)
Definition: persistencemanager.hh:312
void restore(const std::string &token, T &value)
Definition: persistencemanager.hh:319
static std::string uniqueFileName(const std::string &tag="")
Definition: persistencemanager.hh:384
static const bool singleBackupRestoreFile
Definition: persistencemanager.hh:156
std::string getUniqueFileName(const std::string &tag)
Definition: persistencemanager.hh:301
void restoreObjects(const std::string &path)
Definition: persistencemanager.hh:281
static void insert(PersistentObject &object, const bool pushFront=false)
Definition: persistencemanager.hh:359
static void backupValue(const std::string &token, const T &value)
Definition: persistencemanager.hh:395
static std::string uniqueTag(const std::string &tag="")
Definition: persistencemanager.hh:389
static void backup(const std::string &path)
Definition: persistencemanager.hh:369
static void restore(const std::string &path)
Definition: persistencemanager.hh:374
static void restoreValue(const std::string &token, T &value)
Definition: persistencemanager.hh:401
static void startRestore(const std::string &path)
Definition: persistencemanager.hh:379
void reset()
clear all objects registered to PersistenceManager
Definition: persistencemanager.hh:331
void insertObject(ObjectType &object, const bool pushFront=false)
Definition: persistencemanager.hh:200
static RestoreStreamType & restoreStream()
Definition: persistencemanager.hh:354
static BackupStreamType & backupStream()
Definition: persistencemanager.hh:349
Fem ::BinaryFileInStream RestoreStreamType
Definition: persistencemanager.hh:155
void backupObjects(const std::string &path)
Definition: persistencemanager.hh:260
static PersistentObject * apply(ObjectType &obj)
Definition: persistencemanager.hh:521
virtual void * pointer()
Definition: persistencemanager.hh:560
static PersistentObject * apply(ObjectType &obj)
Definition: persistencemanager.hh:566
WrapObject< ObjectType, false > ThisType
Definition: persistencemanager.hh:532
virtual ~WrapObject()
Definition: persistencemanager.hh:546
virtual void backup() const
backup persistent object
Definition: persistencemanager.hh:549
virtual void restore()
restore persistent object
Definition: persistencemanager.hh:554
std::string token_
Definition: persistencemanager.hh:537
WrapObject(ObjectType &obj)
Definition: persistencemanager.hh:539
ObjectType & obj_
Definition: persistencemanager.hh:536
PersistentObject BaseType
Definition: persistencemanager.hh:533
base class for auto persistent objects
Definition: persistencemanager.hh:580
AutoPersistentObject()
Definition: persistencemanager.hh:585
virtual ~AutoPersistentObject()
Definition: persistencemanager.hh:595
AutoPersistentObject(const ThisType &)
Definition: persistencemanager.hh:590
void clear()
clear all parameters
Definition: container.hh:174
static bool verbose()
obtain the cached value for fem.verbose
Definition: io/parameter.hh:445
static void append(int &argc, char **argv)
add parameters from the command line RangeType gRight;
Definition: io/parameter.hh:208
static ParameterContainer & container()
Definition: io/parameter.hh:193
static void write(const std::string &filename, const std::string &fileextension="", bool writeAll=true)
write the parameter database to a file
Definition: io/parameter.hh:516
static int size()
Definition: mpimanager.hh:160
static int rank()
Definition: mpimanager.hh:155
return singleton instance of given Object type.
Definition: singleton.hh:71
static Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:101