feisty meow concerns codebase  2.140
ini_roller.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : ini_roller *
4 * Author : Chris Koeritz *
5 * *
6 *******************************************************************************
7 * Copyright (c) 2001-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
14 
15 #include "ini_roller.h"
16 
17 #include <basis/astring.h>
18 #include <basis/functions.h>
19 #include <basis/mutex.h>
21 
22 using namespace basis;
23 using namespace structures;
24 
25 namespace configuration {
26 
27 //#define DEBUG_ID_GRANTING
28  // uncomment if you want verbose granting of unique ids.
29 
30 const int ID_FACTOR = 28;
31  // this many ids are grabbed at once for eventual issuance.
32 
33 ini_roller::ini_roller(configurator &config, const astring &section,
34  const astring &entry, int min, int max)
35 : _ini(config),
36  _ids(new int_roller(min, max)),
37  _section(new astring(section)),
38  _entry(new astring(entry)),
39  _lock(new mutex)
40 {
41  int current = _ini.load(section, entry, min);
42  _ids->set_current(current);
43  // make our first requisition of ids. we start here rather than playing
44  // games with the next_id function.
45  _ini.store(section, entry, _ids->current() + ID_FACTOR);
46 }
47 
49 {
50  // force the id to be past what we've allocated, but not too far past.
51  _ini.store(*_section, *_entry, _ids->current() + 1);
52  WHACK(_ids);
53  WHACK(_section);
54  WHACK(_entry);
55  WHACK(_lock);
56 }
57 
59 {
60  auto_synchronizer l(*_lock);
61  return _ids->current();
62 }
63 
65 {
66 #ifdef DEBUG_ID_GRANTING
67  FUNCDEF("next_id");
68 #endif
69  auto_synchronizer l(*_lock);
70  int to_return = _ids->current();
71 
72  // this uses a relaxed id issuance policy; the id that's in the INI
73  // file is only updated when we run out of the range that we allocate for it.
74  // the roller's current value is used whenever issuing an id, but next_id()
75  // is always called before that id is actually issued.
76 
77  if ( (_ids->current() < _ids->maximum() - 2)
78  && (_ids->current() % ID_FACTOR) ) {
79  // no id range grabbing needed yet and no rollover.
80  _ids->next_id();
81 #ifdef DEBUG_ID_GRANTING
82  LOG(astring(astring::SPRINTF, "standard id issue: %d.", to_return));
83 #endif
84  return to_return;
85  }
86 
87  // now we need to allocate a new range of ids... and store in ini.
88  int new_range = to_return + ID_FACTOR;
89 #ifdef DEBUG_ID_GRANTING
90  LOG(astring(astring::SPRINTF, "finding next range, new start in ini "
91  "is: %d.", new_range));
92 #endif
93  // if the id wraps around, reset it.
94  if ( (new_range < 0) || (new_range >= _ids->maximum()) )
95  new_range = ID_FACTOR;
96 #ifdef DEBUG_ID_GRANTING
97  LOG(astring(astring::SPRINTF, "after check, new ini id is: %d.",
98  new_range));
99 #endif
100  _ini.store(*_section, *_entry, new_range);
101  // set the next stored id to the block above where we're using.
102  _ids->next_id(); // jump to the next one in the range.
103 #ifdef DEBUG_ID_GRANTING
104  LOG(astring(astring::SPRINTF, "after store, id is: %d.", to_return));
105 #endif
106  return to_return;
107 }
108 
109 } //namespace.
110 
#define LOG(s)
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
auto_synchronizer simplifies concurrent code by automatically unlocking.
Definition: mutex.h:113
Provides a base class for configuration repositories.
Definition: configurator.h:34
bool store(const basis::astring &section, const basis::astring &entry, const basis::astring &to_store)
a synonym for put.
basis::astring load(const basis::astring &section, const basis::astring &entry, const basis::astring &default_value)
a synonym for get that implements the auto-store behavior.
int current_id() const
returns the current id; this is the one that was last issued.
Definition: ini_roller.cpp:58
int next_id()
returns the next number to be issued.
Definition: ini_roller.cpp:64
A roller that's based on integers. This is the most common type so far.
Definition: roller.h:79
contents current() const
returns the current id to be used; be careful!
Definition: roller.h:102
contents maximum()
the outer limit of the roller; it should never reach this.
Definition: roller.h:51
void set_current(contents new_current)
allows the current id to be manipulated.
Definition: roller.h:94
contents next_id()
returns a unique (per instance of this type) id.
Definition: roller.h:105
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition: functions.h:121
const int ID_FACTOR
Definition: ini_roller.cpp:30
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55