1 /*****************************************************************************\
4 * Author : Chris Koeritz *
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 \*****************************************************************************/
15 #include "ini_roller.h"
17 #include <basis/astring.h>
18 #include <basis/functions.h>
19 #include <basis/mutex.h>
20 ///#include <structures/configurator.h>
22 using namespace basis;
23 using namespace structures;
25 namespace configuration {
27 //#define DEBUG_ID_GRANTING
28 // uncomment if you want verbose granting of unique ids.
30 const int ID_FACTOR = 28;
31 // this many ids are grabbed at once for eventual issuance.
33 ini_roller::ini_roller(configurator &config, const astring §ion,
34 const astring &entry, int min, int max)
36 _ids(new int_roller(min, max)),
37 _section(new astring(section)),
38 _entry(new astring(entry)),
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);
48 ini_roller::~ini_roller()
50 // force the id to be past what we've allocated, but not too far past.
51 _ini.store(*_section, *_entry, _ids->current() + 1);
58 int ini_roller::current_id() const
60 auto_synchronizer l(*_lock);
61 return _ids->current();
64 int ini_roller::next_id()
66 #ifdef DEBUG_ID_GRANTING
69 auto_synchronizer l(*_lock);
70 int to_return = _ids->current();
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.
77 if ( (_ids->current() < _ids->maximum() - 2)
78 && (_ids->current() % ID_FACTOR) ) {
79 // no id range grabbing needed yet and no rollover.
81 #ifdef DEBUG_ID_GRANTING
82 LOG(astring(astring::SPRINTF, "standard id issue: %d.", to_return));
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));
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.",
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));