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
22using namespace basis;
23using namespace structures;
24
25namespace configuration {
26
27//#define DEBUG_ID_GRANTING
28 // uncomment if you want verbose granting of unique ids.
29
30const int ID_FACTOR = 28;
31 // this many ids are grabbed at once for eventual issuance.
32
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.
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.
ini_roller(configurator &config, const basis::astring &section, const basis::astring &entry, int min, int max)
creates a roller that updates "config" with the current id value.
int current_id() const
returns the current id; this is the one that was last issued.
int next_id()
returns the next number to be issued.
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:54
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
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55