Annotation of fam/fam/SmallTable.h, Revision 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>