[BACK]Return to SmallTable.h CVS log [TXT][DIR] Up to [Development] / fam / fam

Annotation of fam/fam/SmallTable.h, Revision 1.1.1.1

1.1       trev        1: //  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.
                      2: //
                      3: //  This program is free software; you can redistribute it and/or modify it
                      4: //  under the terms of version 2 of the GNU General Public License as
                      5: //  published by the Free Software Foundation.
                      6: //
                      7: //  This program is distributed in the hope that it would be useful, but
                      8: //  WITHOUT ANY WARRANTY; without even the implied warranty of
                      9: //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any
                     10: //  license provided herein, whether implied or otherwise, is limited to
                     11: //  this program in accordance with the express provisions of the GNU
                     12: //  General Public License.  Patent licenses, if any, provided herein do not
                     13: //  apply to combinations of this program with other product or programs, or
                     14: //  any other product whatsoever.  This program is distributed without any
                     15: //  warranty that the program is delivered free of the rightful claim of any
                     16: //  third person by way of infringement or the like.  See the GNU General
                     17: //  Public License for more details.
                     18: //
                     19: //  You should have received a copy of the GNU General Public License along
                     20: //  with this program; if not, write the Free Software Foundation, Inc., 59
                     21: //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
                     22:
                     23: #ifndef SmallTable_included
                     24: #define SmallTable_included
                     25:
                     26: #include <assert.h>
                     27:
                     28: //  A SmallTable holds key-value mappings.  Its implementation is
                     29: //  cheap and dirty, so it should not be used for tables with lots of
                     30: //  entries.  Lookups are faster than insertions/removals.
                     31: //
                     32: // class TKey and Tvalue must define < and > operators, and must
                     33: //  be able to be assigned a value of 0 and be compared
                     34: //  with 0.
                     35: //
                     36: //  Operations:
                     37: //		insert()	puts a new entry in table.
                     38: //		remove()	removes an entry.
                     39: //		find()		returns the value for a key.
                     40: //		size()		returns number of entries.
                     41: //              first()         returns the first key
                     42:
                     43:
                     44: template <class Tkey, class Tvalue> class SmallTable {
                     45:
                     46: public:
                     47:
                     48:     SmallTable()			: n(0), nalloc(0), table(0) { }
                     49:     virtual ~SmallTable();
                     50:
                     51:     void insert(const Tkey&, const Tvalue&);
                     52:     void remove(const Tkey&);
                     53:     void removeAll();
                     54:     inline Tvalue find(const Tkey& k) const;
                     55:     Tkey first() const			{ return n ? table[0].key : 0; }
                     56:     unsigned size() const		{ return n; }
                     57:
                     58: private:
                     59:
                     60:     struct Closure {
                     61: 	const enum Presence { PRESENT, ABSENT } presence;
                     62: 	const unsigned index;
                     63: 	Closure(Presence p, unsigned i)	: presence(p), index(i) { }
                     64:     };
                     65:
                     66:     struct Pair {
                     67: 	Tkey key;
                     68: 	Tvalue value;
                     69:     };
                     70:
                     71:     unsigned n, nalloc;
                     72:     Pair *table;
                     73:
                     74:     virtual Closure position(const Tkey&) const;
                     75:
                     76:     SmallTable(const SmallTable&);	// Do not copy
                     77:     SmallTable & operator = (const SmallTable&);	//  or assign.
                     78:
                     79: };
                     80:
                     81:
                     82: //
                     83: //  Template member implementations
                     84: //
                     85:
                     86: template <class Tkey, class Tvalue>
                     87: inline Tvalue
                     88: SmallTable<Tkey, Tvalue>::find(const Tkey& k) const
                     89: {
                     90:     Closure c = position(k);
                     91:     return c.presence == Closure::PRESENT ? table[c.index].value : 0;
                     92: }
                     93:
                     94: template <class Tkey, class Tvalue>
                     95: SmallTable<Tkey, Tvalue>::~SmallTable()
                     96: {
                     97:     delete [] table;
                     98: }
                     99:
                    100: template <class Tkey, class Tvalue>
                    101: SmallTable<Tkey, Tvalue>::Closure
                    102: SmallTable<Tkey, Tvalue>::position(const Tkey& key) const
                    103: {
                    104:     unsigned l = 0, r = n;
                    105:     while (l < r)
                    106:     {
                    107: 	unsigned mid = (l + r) / 2;
                    108: 	if (key < table[mid].key)
                    109: 	    r = mid;
                    110: 	else if (key > table[mid].key)
                    111: 	    l = mid + 1;
                    112: 	else // (key == table[mid].key)
                    113: 	    return Closure(Closure::PRESENT, mid);
                    114:     }
                    115:     return Closure(Closure::ABSENT, l);
                    116: }
                    117:
                    118: template <class Tkey, class Tvalue>
                    119: void
                    120: SmallTable<Tkey, Tvalue>::insert(const Tkey& key, const Tvalue& value)
                    121: {
                    122:     Closure c = position(key);
                    123:
                    124:     if (c.presence == Closure::PRESENT)
                    125:     {   table[c.index].value = value;
                    126: 	return;
                    127:     }
                    128:
                    129:     if (n >= nalloc)
                    130:     {
                    131: 	//  Grow the table.
                    132:
                    133: 	nalloc = 3 * n / 2 + 10;
                    134: 	Pair *nt = new Pair[nalloc];
                    135: 	unsigned i;
                    136: 	for (i = 0; i < c.index; i++)
                    137: 	    nt[i] = table[i];
                    138: 	for ( ; i < n; i++)
                    139: 	    nt[i + 1] = table[i];
                    140: 	delete [] table;
                    141: 	table = nt;
                    142:     }
                    143:     else
                    144:     {
                    145: 	// Shift following entries right.
                    146:
                    147: 	for (unsigned i = n; i > c.index; --i)
                    148: 	    table[i] = table[i - 1];
                    149:     }
                    150:     table[c.index].key = key;
                    151:     table[c.index].value = value;
                    152:     n++;
                    153: }
                    154:
                    155: template <class Tkey, class Tvalue>
                    156: void
                    157: SmallTable<Tkey, Tvalue>::remove(const Tkey& key)
                    158: {
                    159:     Closure c = position(key);
                    160:     assert(c.presence == Closure::PRESENT);
                    161:
                    162:     // Shift following entries left.
                    163:
                    164:     for (unsigned i = c.index + 1; i < n; i++)
                    165: 	table[i - 1] = table[i];
                    166:     --n;
                    167:
                    168:     // Shrink the table.
                    169:
                    170:     if (2 * n < nalloc && n < nalloc - 10)
                    171:     {
                    172: 	nalloc = n;
                    173: 	Pair *nt = new Pair[nalloc];
                    174: 	for (unsigned i = 0; i < n; i++)
                    175: 	    nt[i] = table[i];
                    176: 	delete [] table;
                    177: 	table = nt;
                    178:     }
                    179: }
                    180:
                    181: template <class Tkey, class Tvalue>
                    182: void
                    183: SmallTable<Tkey, Tvalue>::removeAll()
                    184: {
                    185:     n = 0;
                    186:     nalloc = 0;
                    187:     if (table != NULL) delete [] table;
                    188:     table = NULL;
                    189: }
                    190:
                    191: #endif /* !SmallTable_included */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>