ini_roller.cpp

Go to the documentation of this file.
00001 #ifndef INI_ROLLER_IMPLEMENTATION_FILE
00002 #define INI_ROLLER_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : ini_roller                                                        *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 2001-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "ini_roller.h"
00019 #include "roller.cpp"
00020 
00021 #include <basis/function.h>
00022 #include <basis/istring.h>
00023 #include <basis/mutex.h>
00024 #include <data_struct/configurator.h>
00025 
00026 //#define DEBUG_ID_GRANTING
00027   // uncomment if you want verbose granting of unique ids.
00028 
00029 const int ID_FACTOR = 28;
00030   // this many ids are grabbed at once for eventual issuance.
00031 
00032 ini_roller::ini_roller(configurator &config, const istring &section,
00033       const istring &entry, int min, int max)
00034 : _ini(config),
00035   _ids(new int_roller(min, max)),
00036   _section(new istring(section)),
00037   _entry(new istring(entry)),
00038   _lock(new mutex)
00039 {
00040   int current = _ini.load(section, entry, min);
00041   _ids->set_current(current);
00042   // make our first requisition of ids.  we start here rather than playing
00043   // games with the next_id function.
00044   _ini.store(section, entry, _ids->current() + ID_FACTOR);
00045 }
00046 
00047 ini_roller::~ini_roller()
00048 {
00049   // force the id to be past what we've allocated, but not too far past.
00050   _ini.store(*_section, *_entry, _ids->current() + 1);
00051   WHACK(_ids);
00052   WHACK(_section);
00053   WHACK(_entry);
00054   WHACK(_lock);
00055 }
00056 
00057 int ini_roller::current_id() const
00058 {
00059   auto_synchronizer l(*_lock);
00060   return _ids->current();
00061 }
00062 
00063 int ini_roller::next_id()
00064 {
00065   FUNCDEF("next_id");
00066   auto_synchronizer l(*_lock);
00067   int to_return = _ids->current();
00068 
00069   // this uses a relaxed id issuance policy; the id that's in the INI
00070   // file is only updated when we run out of the range that we allocate for it.
00071   // the roller's current value is used whenever issuing an id, but next_id()
00072   // is always called before that id is actually issued.
00073 
00074   if ( (_ids->current() < _ids->maximum() - 2) 
00075       && (_ids->current() % ID_FACTOR) ) {
00076     // no id range grabbing needed yet and no rollover.
00077     _ids->next_id();
00078 #ifdef DEBUG_ID_GRANTING
00079     LOG(istring(istring::SPRINTF, "standard id issue: %d.", to_return));
00080 #endif
00081     return to_return;
00082   }
00083 
00084   // now we need to allocate a new range of ids...  and store in ini.
00085   int new_range = to_return + ID_FACTOR;
00086 #ifdef DEBUG_ID_GRANTING
00087   LOG(istring(istring::SPRINTF, "finding next range, new start in ini "
00088       "is: %d.", new_range));
00089 #endif
00090   // if the id wraps around, reset it.
00091   if ( (new_range < 0) || (new_range >= _ids->maximum()) )
00092     new_range = ID_FACTOR;
00093 #ifdef DEBUG_ID_GRANTING
00094   LOG(istring(istring::SPRINTF, "after check, new ini id is: %d.",
00095       new_range));
00096 #endif
00097   _ini.store(*_section, *_entry, new_range);
00098     // set the next stored id to the block above where we're using.
00099   _ids->next_id();  // jump to the next one in the range.
00100 #ifdef DEBUG_ID_GRANTING
00101   LOG(istring(istring::SPRINTF, "after store, id is: %d.", to_return));
00102 #endif
00103   return to_return;
00104 }
00105 
00106 
00107 
00108 #endif //INI_ROLLER_IMPLEMENTATION_FILE
00109 

Generated on Fri Nov 28 04:29:16 2008 for HOOPLE Libraries by  doxygen 1.5.1