bes  Updated for version 3.20.10
BESContainerStorageList.cc
1 // BESContainerStorageList.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include "config.h"
34 
35 #include <iostream>
36 #include <mutex>
37 
38 #include "BESContainerStorageList.h"
39 #include "BESContainerStorage.h"
40 #include "BESSyntaxUserError.h"
41 #include "BESContainer.h"
42 #include "TheBESKeys.h"
43 #include "BESLog.h"
44 #include "BESInfo.h"
45 
46 #include "BESDebug.h"
47 
48 using std::endl;
49 using std::string;
50 using std::ostream;
51 
52 BESContainerStorageList *BESContainerStorageList::d_instance = nullptr;
53 static std::once_flag d_euc_init_once;
54 
55 BESContainerStorageList::BESContainerStorageList() :
56  _first(0)
57 {
58 }
59 
60 BESContainerStorageList::~BESContainerStorageList()
61 {
62  BESContainerStorageList::persistence_list *pl = _first;
63  while (pl) {
64  if (pl->_persistence_obj) {
65  delete pl->_persistence_obj;
66  }
67  BESContainerStorageList::persistence_list *next = pl->_next;
68  delete pl;
69  pl = next;
70  }
71 }
72 
86 {
87  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
88 
89  bool ret = false;
90  if (!_first) {
91  _first = new BESContainerStorageList::persistence_list;
92  _first->_persistence_obj = cp;
93  _first->_reference = 1;
94  _first->_next = 0;
95  ret = true;
96  }
97  else {
98  BESContainerStorageList::persistence_list *pl = _first;
99  bool done = false;
100  while (done == false) {
101  if (pl->_persistence_obj->get_name() != cp->get_name()) {
102  if (pl->_next) {
103  pl = pl->_next;
104  }
105  else {
106  pl->_next = new BESContainerStorageList::persistence_list;
107  pl->_next->_reference = 1;
108  pl->_next->_persistence_obj = cp;
109  pl->_next->_next = 0;
110  done = true;
111  ret = true;
112  }
113  }
114  else {
115  done = true;
116  ret = false;
117  }
118  }
119  }
120  return ret;
121 }
122 
133 bool BESContainerStorageList::ref_persistence(const string &persist_name)
134 {
135  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
136 
137  bool ret = false;
138  BESContainerStorageList::persistence_list *pl = _first;
139 
140  bool done = false;
141  while (done == false) {
142  if (pl) {
143  if (pl->_persistence_obj && pl->_persistence_obj->get_name() == persist_name) {
144  done = true;
145  ret = true;
146  pl->_reference++;
147  }
148  else {
149  pl = pl->_next;
150  }
151  }
152  else {
153  done = true;
154  }
155  }
156  return ret;
157 }
158 
171 bool BESContainerStorageList::deref_persistence(const string &persist_name)
172 {
173  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
174 
175  bool ret = false;
176  BESContainerStorageList::persistence_list *pl = _first;
177  BESContainerStorageList::persistence_list *last = 0;
178 
179  bool done = false;
180  while (done == false) {
181  if (pl) {
182  if (pl->_persistence_obj && pl->_persistence_obj->get_name() == persist_name) {
183  ret = true;
184  done = true;
185  pl->_reference--;
186  if (!pl->_reference) {
187  if (pl == _first) {
188  _first = _first->_next;
189  }
190  else {
191  if (!last)
192  throw BESInternalError("ContainerStorageList last is null", __FILE__, __LINE__);
193  last->_next = pl->_next;
194  }
195  delete pl->_persistence_obj;
196  delete pl;
197  pl = 0;
198  }
199  }
200  else {
201  last = pl;
202  pl = pl->_next;
203  }
204  }
205  else {
206  done = true;
207  }
208  }
209 
210  return ret;
211 }
212 
222 BESContainerStorageList::find_persistence(const string &persist_name)
223 {
224  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
225 
226  BESContainerStorage *ret = NULL;
227  BESContainerStorageList::persistence_list *pl = _first;
228  bool done = false;
229  while (done == false) {
230  if (pl) {
231  if (persist_name == pl->_persistence_obj->get_name()) {
232  ret = pl->_persistence_obj;
233  done = true;
234  }
235  else {
236  pl = pl->_next;
237  }
238  }
239  else {
240  done = true;
241  }
242  }
243  return ret;
244 }
245 
246 bool BESContainerStorageList::isnice()
247 {
248  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
249 
250  bool ret = false;
251  string key = "BES.Container.Persistence";
252  bool found = false;
253  string isnice;
254  TheBESKeys::TheKeys()->get_value(key, isnice, found);
255  if (isnice == "Nice" || isnice == "nice" || isnice == "NICE")
256  ret = true;
257  else
258  ret = false;
259  return ret;
260 }
261 
285 BESContainer *
286 BESContainerStorageList::look_for(const string &sym_name)
287 {
288  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
289 
290  BESContainer *ret_container = 0;
291  BESContainerStorageList::persistence_list *pl = _first;
292  bool done = false;
293  while (done == false) {
294  if (pl) {
295  ret_container = pl->_persistence_obj->look_for(sym_name);
296  if (ret_container) {
297  done = true;
298  }
299  else {
300  pl = pl->_next;
301  }
302  }
303  else {
304  done = true;
305  }
306  }
307  if (!ret_container) {
308  string msg = (string) "Could not find the symbolic name " + sym_name;
309  ERROR_LOG(msg << endl);
310  if (!isnice()) {
311  throw BESSyntaxUserError(msg, __FILE__, __LINE__);
312  }
313  }
314 
315  return ret_container;
316 }
317 
332 void
333 BESContainerStorageList::delete_container(const std::string &sym_name)
334 {
335  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
336 
337  BESContainerStorageList::persistence_list *pl = _first;
338  while (pl) {
339  (void) pl->_persistence_obj->del_container(sym_name);
340 
341  pl = pl->_next;
342  }
343 }
344 
358 {
359  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
360 
361  BESContainerStorageList::persistence_list *pl = _first;
362  while (pl) {
363  std::map<string, string> props;
364  props["name"] = pl->_persistence_obj->get_name();
365  info.begin_tag("store", &props);
366  pl->_persistence_obj->show_containers(info);
367  info.end_tag("store");
368  pl = pl->_next;
369  }
370 }
371 
379 void BESContainerStorageList::dump(ostream &strm) const
380 {
381  std::lock_guard<std::recursive_mutex> lock_me(d_cache_lock_mutex);
382 
383  strm << BESIndent::LMarg << "BESContainerStorageList::dump - (" << (void *) this << ")" << endl;
384  BESIndent::Indent();
385  BESContainerStorageList::persistence_list *pl = _first;
386  if (pl) {
387  strm << BESIndent::LMarg << "container storage:" << endl;
388  BESIndent::Indent();
389  while (pl) {
390  pl->_persistence_obj->dump(strm);
391  pl = pl->_next;
392  }
393  BESIndent::UnIndent();
394  }
395  else {
396  strm << BESIndent::LMarg << "container storage: empty" << endl;
397  }
398  BESIndent::UnIndent();
399 }
400 
402 BESContainerStorageList::TheList()
403 {
404  std::call_once(d_euc_init_once,BESContainerStorageList::initialize_instance);
405  return d_instance;
406 }
407 
408 void BESContainerStorageList::initialize_instance() {
409  d_instance = new BESContainerStorageList;
410 #ifdef HAVE_ATEXIT
411  atexit(delete_instance);
412 #endif
413 }
414 
415 void BESContainerStorageList::delete_instance() {
416  delete d_instance;
417  d_instance = 0;
418 }
419 
Provides a mechanism for accessing container information from different container stores registered w...
virtual bool ref_persistence(const std::string &persist_name)
refence the specified persistent store if in the list
virtual void show_containers(BESInfo &info)
show information for each container in each persistence store
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual bool add_persistence(BESContainerStorage *p)
Add a persistent store to the list.
virtual BESContainer * look_for(const std::string &sym_name)
look for the specified container information in the list of persistent stores.
virtual void delete_container(const std::string &sym_name)
scan all of the container stores and remove any containers called
virtual bool deref_persistence(const std::string &persist_name)
dereference a persistent store in the list.
virtual BESContainerStorage * find_persistence(const std::string &persist_name)
find the persistence store with the given name
provides persistent storage for data storage information represented by a container.
virtual const std::string & get_name() const
retrieve the name of this persistent store
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
informational response object
Definition: BESInfo.h:63
exception thrown if internal error encountered
error thrown if there is a user syntax error in the request or any other user error
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:340
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:71