Psyllid  v1.12.4
Project 8 Data Acquisisition Software
persistent_store.hh
Go to the documentation of this file.
1 /*
2  * persistent_store.hh
3  *
4  * Created on: Jan 27, 2016
5  * Author: nsoblath
6  */
7 
8 #ifndef PSYLLID_PERSISTENT_STORE_HH_
9 #define PSYLLID_PERSISTENT_STORE_HH_
10 
11 #include "psyllid_error.hh"
12 
13 #include <map>
14 #include <memory>
15 #include <mutex>
16 #include <string>
17 
18 namespace psyllid
19 {
20 
22  {
23  public:
24  class label_in_use : public error
25  {
26  public:
27  label_in_use( const std::string& a_label ) { f_message = "The label <" + a_label + "> is already in use"; }
28  virtual ~label_in_use() {}
29  };
30 
31  class label_not_found : public error
32  {
33  public:
34  label_not_found( const std::string& a_label ) { f_message = "The label <" + a_label + "> was not found"; }
35  };
36 
37  class wrong_type : public error
38  {
39  public:
40  wrong_type() { f_message = "Incorrect type requested"; }
41  virtual ~wrong_type() {}
42  };
43 
44  public:
46  virtual ~persistent_store();
47 
48  public:
49  template< typename x_type >
50  void store( const std::string& a_label, std::shared_ptr< x_type > an_item ); // will throw label_in_use if the label is already in use
51 
52  template< typename x_type >
53  std::shared_ptr< x_type > retrieve( const std::string& a_label ); // will throw label_not_found if the label isn't present, and wrong_type if the type supplied is wrong for the given label
54 
55  void dump( const std::string& a_label ); // does not throw
56 
57  bool has( const std::string& a_label ) const; // does not throw
58 
59  private:
60  class storable
61  {
62  public:
63  storable() {}
64  storable( const storable& ) = delete;
65 
66  virtual ~storable() {}
67 
68  template< typename x_type >
69  std::shared_ptr< x_type > retrieve() const
70  {
71  _storable< x_type >* t_derived_storable = dynamic_cast< _storable< x_type >* >( this );
72  if( t_derived_storable == nullptr )
73  {
74  throw wrong_type();
75  }
76  return t_derived_storable->_retrieve();
77  }
78  };
79 
80  template< typename x_type >
81  class _storable : public storable
82  {
83  public:
84  typedef std::shared_ptr< x_type > stored_ptr_t;
85 
86  public:
87  _storable() = delete;
88  _storable( stored_ptr_t an_item ) :
89  storable(),
90  f_stored( an_item )
91  {}
92  _storable( const _storable& ) = delete;
93 
94  virtual ~_storable() {}
95 
96  virtual stored_ptr_t _retrieve() const
97  {
98  return f_stored;
99  }
100 
101  private:
102  stored_ptr_t f_stored;
103  };
104 
105  typedef std::map< std::string, std::unique_ptr< storable > > storage_t;
106  typedef storage_t::const_iterator storage_cit_t;
107  typedef storage_t::iterator storage_it_t;
108 
109  storage_t f_storage;
110  mutable std::mutex f_storage_mutex;
111  };
112 
113  template< typename x_type >
114  void persistent_store::store( const std::string& a_label, std::shared_ptr< x_type > an_item )
115  {
116  std::unique_lock< std::mutex > t_lock( f_storage_mutex );
117 
118  storage_it_t t_item_it = f_storage.find( a_label );
119  if( t_item_it != f_storage.end() )
120  {
121  throw label_in_use( a_label );
122  }
123 
124  f_storage.emplace( a_label, new _storable< x_type >( an_item ) );
125  return;
126  }
127 
128  template< typename x_type >
129  std::shared_ptr< x_type > persistent_store::retrieve( const std::string& a_label )
130  {
131  std::unique_lock< std::mutex > t_lock( f_storage_mutex );
132 
133  storage_it_t t_item_it = f_storage.find( a_label );
134  if( t_item_it == f_storage.end() )
135  {
136  throw label_not_found( a_label );
137  }
138 
139  try
140  {
141  std::shared_ptr< x_type > t_item = t_item_it->second->retrieve< x_type >();
142  f_storage.erase( t_item_it );
143  return t_item;
144  }
145  catch(...)
146  {
147  throw;
148  }
149  }
150 
151  inline bool persistent_store::has( const std::string& a_label ) const
152  {
153  std::unique_lock< std::mutex > t_lock( f_storage_mutex );
154  return f_storage.find( a_label ) != f_storage.end();
155  }
156 
157 } /* namespace psyllid */
158 
159 #endif /* PSYLLID_PERSISTENT_STORE_HH_ */
std::shared_ptr< x_type > stored_ptr_t
virtual stored_ptr_t _retrieve() const
label_not_found(const std::string &a_label)
bool has(const std::string &a_label) const
void store(const std::string &a_label, std::shared_ptr< x_type > an_item)
std::shared_ptr< x_type > retrieve(const std::string &a_label)
std::map< std::string, std::unique_ptr< storable > > storage_t
storage_t::iterator storage_it_t
void dump(const std::string &a_label)
std::string f_message
label_in_use(const std::string &a_label)
storage_t::const_iterator storage_cit_t
std::shared_ptr< x_type > retrieve() const