Bayeux  3.4.1
Core Foundation library for SuperNEMO
handle_pool.h
Go to the documentation of this file.
1 /* Author(s) : Francois Mauger <mauger@lpccaen.in2p3.fr>
3  * Creation date : 2011-05-10
4  * Last modified : 2013-04-22
5  *
6  * Copyright (C) 2011-2013 Francois Mauger <mauger@lpccaen.in2p3.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  * Description:
24  *
25  * A pool of handles.
26  *
27  */
28 
29 #ifndef DATATOOLS_HANDLE_POOL_H
30 #define DATATOOLS_HANDLE_POOL_H
31 
32 // Standard Library:
33 #include <iostream>
34 #include <string>
35 #include <stdexcept>
36 #include <vector>
37 
38 // This Project:
39 #include <datatools/handle.h>
40 
41 namespace datatools {
42 
44  template <class T>
46  {
47  public:
48 
49  typedef T element_type;
51 
53  handle_pool();
54 
56  explicit handle_pool(size_t size_);
57 
59  virtual ~handle_pool();
60 
62  void clear();
63 
65  size_t get_capacity() const;
66 
68  size_t get_number_of_used_item() const;
69 
71  void reset();
72 
74  void resize(size_t size_);
75 
77  const handle_type& create();
78 
80  void dump(std::ostream & out_ = std::clog,
81  const std::string & title_ = "",
82  const std::string & indent_ = "",
83  bool abridged_ = true) const;
84 
86  void resize_impl(size_t size_);
87 
88  protected:
89 
90  std::vector<handle_type> _buffer_; //<! Collection of handles held in the pool
91  size_t _number_of_used_item_; //<! Number of pool handles currently in use
92 
93  };
94 
95  //----------------------------------------------------------------------
96  // Implementation of handle_pool methods
97 
98  template <typename T>
100  {
101 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
103 #endif
104  _number_of_used_item_ = 0;
105 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
107 #endif
108  }
109 
110 
111  template <typename T>
113  {
114 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
116 #endif
117  _number_of_used_item_ = 0;
118  this->resize_impl(size_);
119 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
121 #endif
122  }
123 
124 
125  template <typename T>
127  {
128 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
130  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "buffer size is " << _buffer_.size());
131  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "number of used element " << _number_of_used_item);
132 #endif
133  _number_of_used_item_ = 0;
134  _buffer_.clear();
135 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
137 #endif
138  return;
139  }
140 
141 
142  template <typename T>
144  {
145  _buffer_.clear();
146  return;
147  }
148 
149 
150  template <typename T>
152  {
153  return _buffer_.size();
154  }
155 
156 
157  template <typename T>
159  {
160  return _number_of_used_item_;
161  }
162 
163 
164  template <typename T>
166  {
167  _number_of_used_item_ = 0;
168  return;
169  }
170 
171 
172  template <typename T>
173  void handle_pool<T>::resize(size_t size_)
174  {
175  DT_THROW_IF (_number_of_used_item_ > 0,
176  std::logic_error,
177  "Cannot resize pool with items in use");
178  this->resize_impl(size_);
179  return;
180  }
181 
182 
183  template <typename T>
185  {
186 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
188  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "buffer size is " << _buffer_.size());
189  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "number of used element " << _number_of_used_item_);
190 #endif
191 
192  if (_number_of_used_item_ < _buffer_.size()) {
193 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
194  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "Use a pre-allocated element @ position "
195  << _number_of_used_item_);
197 #endif
198  return _buffer_[_number_of_used_item_++];
199  }
200 
201  element_type *ptr = new element_type;
202  _buffer_.push_back(handle_type(ptr));
203  _number_of_used_item_++;
204 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
205  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "Use a newly allocated element @ position "
206  << (_number_of_used_item_ - 1));
208 #endif
209  return _buffer_.back();
210  }
211 
212 
213  template <typename T>
214  void handle_pool<T>::dump(std::ostream & out_,
215  const std::string & title_,
216  const std::string & indent_,
217  bool abridged_) const {
218  if (!title_.empty()) {
219  out_ << indent_ << title_ << " : " << std::endl;
220  }
221  out_ << indent_ << "|-- " << "Capacity : " << this->get_capacity() << std::endl;
222  out_ << indent_ << "|-- " << "# Used items : " << _number_of_used_item_ << std::endl;
223  out_ << indent_ << "`-- " << "Items @ " << std::endl;
224  for (size_t i = 0; i < _buffer_.size(); ++i) {
225  if (abridged_) {
226  if (i >= 10) continue;
227  }
228  out_ << indent_ << " ";
229  const handle_type& h = _buffer_[i];
230  if (i < _buffer_.size() - 1) {
231  out_ << "|-- ";
232  } else {
233  out_ << "`-- ";
234  }
235  out_ << "index " << i << " : ";
236  if (!h) {
237  out_ << "No element!" << std::endl;
238  } else {
239  out_ << "@ " << &h.get() << " [unique=" << h.unique() << "]"<< std::endl;
240  }
241  }
242  return;
243  }
244 
245 
246  template <typename T>
247  void handle_pool<T>::resize_impl(size_t size_) {
248 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
250 #endif
251 
252  size_t current_size = _buffer_.size();
253 
254 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
255  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "current_size = " << current_size);
256 #endif
257 
258  if (size_ <= current_size) {
259 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
260  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "Capacity is enough for " << size_);
261 #endif
262  return;
263  }
264 
265  _buffer_.reserve(size_);
266  for (size_t i = current_size; i < size_; ++i) {
267 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
268  DT_LOG_TRACE(datatools::logger::PRIO_ALWAYS, "Add a handle with a new element...");
269 #endif
270  _buffer_.push_back(handle_type(new element_type));
271  }
272 
273  _number_of_used_item_ = 0;
274 
275 #ifdef DATATOOLS_HANDLE_POOL_DEVEL
277 #endif
278 
279  return;
280  }
281 
282 } // namespace datatools
283 
284 #endif // DATATOOLS_HANDLE_POOL_H
285 
286 // Local Variables: --
287 // mode: c++ --
288 // c-file-style: "gnu" --
289 // tab-width: 2 --
290 // End: --
#define DT_LOG_TRACE_EXITING(Priority)
Log a fonction exiting message if Priority is greater or equal to PRIO_TRACE.
Definition: logger_macros.h:267
size_t get_number_of_used_item() const
Return the number of handles currently in use.
Definition: handle_pool.h:158
bool unique() const
Check if the current handle holds an uniquely referenced object.
Definition: handle.h:188
void resize(size_t size_)
Change number of handles pool can contain.
Definition: handle_pool.h:173
void resize_impl(size_t size_)
Implementation for public resize method.
Definition: handle_pool.h:247
void dump(std::ostream &out_=std::clog, const std::string &title_="", const std::string &indent_="", bool abridged_=true) const
Input pool capacity and used handles to an output stream.
Definition: handle_pool.h:214
void clear()
Empty the pool.
Definition: handle_pool.h:143
datatools::handle< element_type > handle_type
Definition: handle_pool.h:50
Always print the message.
Definition: logger.h:83
handle_pool()
Construct an empty pool.
Definition: handle_pool.h:99
T element_type
Definition: handle_pool.h:49
const T & get() const
Definition: handle.h:214
Templatized handle class that wraps a Boost shared pointer and behaves like a reference.
Definition: handle.h:114
#define DT_THROW_IF(Condition, ExceptionType, Message)
Definition: exception.h:76
size_t _number_of_used_item_
Definition: handle_pool.h:91
#define DT_LOG_TRACE(Priority, Message)
Log Message if Priority is greater or equal to PRIO_TRACE.
Definition: logger_macros.h:227
The Bayeux/datatools library top-level namespace.
Definition: algo.h:13
A pool of handles on a given class.
Definition: handle_pool.h:45
virtual ~handle_pool()
Destructor.
Definition: handle_pool.h:126
const handle_type & create()
Return a const reference to a new handle.
Definition: handle_pool.h:184
size_t get_capacity() const
Return the number of handles the pool can contain.
Definition: handle_pool.h:151
#define DT_LOG_TRACE_ENTERING(Priority)
Log a fonction entering message if Priority is greater or equal to PRIO_TRACE.
Definition: logger_macros.h:261
std::vector< handle_type > _buffer_
Definition: handle_pool.h:90
void reset()
Set the number of used handles in the pool to zero.
Definition: handle_pool.h:165