src/sysc/utils/sc_hash.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2005 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_hash.cpp -- Implementation of a chained hash table with MTF
00021                  (move-to-front).
00022 
00023   Original Author: Stan Y. Liao, Synopsys, Inc.
00024 
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028 
00029   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00030   changes you are making here.
00031 
00032       Name, Affiliation, Date:
00033   Description of Modification:
00034 
00035  *****************************************************************************/
00036 
00037 #ifndef SC_HASH_H
00038 #define SC_HASH_H
00039 
00040 
00041 namespace sc_core {
00042 
00043 extern unsigned default_int_hash_fn(const void*);
00044 extern unsigned default_ptr_hash_fn(const void*);
00045 extern unsigned default_str_hash_fn(const void*);
00046 
00047 class sc_phash_elem;
00048 class sc_phash_base_iter;
00049 template<class K, class C>  //template class 
00050 class sc_pdhash_iter;       //decl. -- Amit
00051 
00052 const int    PHASH_DEFAULT_MAX_DENSITY     = 5;
00053 const int    PHASH_DEFAULT_INIT_TABLE_SIZE = 11;
00054 extern const double PHASH_DEFAULT_GROW_FACTOR;
00055 const bool   PHASH_DEFAULT_REORDER_FLAG    = true;
00056 
00057 class sc_phash_base {
00058     friend class sc_phash_base_iter;
00059 
00060     typedef sc_phash_base_iter iterator;
00061 
00062 public:
00063     typedef unsigned (*hash_fn_t)(const void*);
00064     typedef int (*cmpr_fn_t)(const void*, const void*);
00065 
00066 protected:
00067     void*    default_value;
00068     int      num_bins;
00069     int      num_entries;
00070     int      max_density;
00071     int      reorder_flag;
00072     double   grow_factor;
00073 
00074     sc_phash_elem** bins;
00075 
00076     hash_fn_t hash;
00077     cmpr_fn_t cmpr;
00078 
00079     void rehash();
00080     unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; }
00081 
00082     sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val);
00083     sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast);
00084     sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast);
00085     sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const
00086     {
00087       /* Got rid of member func. pointer and replaced with if-else  */
00088       /* Amit (5/14/99)                                             */
00089       if( cmpr == 0 )
00090         return ((sc_phash_base*)this)->find_entry_q( hv, k, plast );
00091       else 
00092         return ((sc_phash_base*)this)->find_entry_c( hv, k, plast );
00093     }
00094 
00095 public:
00096     sc_phash_base( void* def       = 0,
00097                    int    size     = PHASH_DEFAULT_INIT_TABLE_SIZE,
00098                    int    density  = PHASH_DEFAULT_MAX_DENSITY,
00099                    double grow     = PHASH_DEFAULT_GROW_FACTOR,
00100                    bool   reorder  = PHASH_DEFAULT_REORDER_FLAG,    
00101                    hash_fn_t hash_fn = default_ptr_hash_fn,
00102                    cmpr_fn_t cmpr_fn = 0                             );
00103     ~sc_phash_base();
00104 
00105     void set_cmpr_fn(cmpr_fn_t);
00106     void set_hash_fn(hash_fn_t);
00107 
00108     bool empty() const { return (num_entries == 0); }
00109     unsigned count() const { return num_entries; }
00110 
00111     void erase();
00112     void erase(void (*kfree)(void*));
00113     void copy( const sc_phash_base* );
00114     void copy( const sc_phash_base& b ) { copy(&b); }
00115     void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*));
00116     int insert( void* k, void* c );
00117     int insert( void* k ) { return insert(k, default_value); }
00118     int insert( void* k, void* c, void* (*kdup)(const void*) );
00119     int insert_if_not_exists(void* k, void* c);
00120     int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); }
00121     int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*));
00122     int remove(const void* k);
00123     int remove(const void* k, void** pk, void** pc);
00124     int remove(const void* k, void (*kfree)(void*));
00125     int remove_by_contents(const void* c);
00126     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg);
00127     int remove_by_contents(const void* c, void (*kfree)(void*));
00128     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*));
00129     int lookup(const void* k, void** pc) const;
00130     bool contains(const void* k) const { return (lookup(k, 0) != 0); }
00131     void* operator[](const void* key) const;
00132 };
00133 
00134 class sc_phash_base_iter {
00135 protected:
00136     sc_phash_base*  table;
00137     sc_phash_elem*  entry;
00138     sc_phash_elem*  next;
00139     sc_phash_elem** last;
00140     int             index;
00141 
00142 public:
00143     void reset(sc_phash_base* t);
00144     void reset(sc_phash_base& t) { reset(&t); }
00145 
00146     sc_phash_base_iter(sc_phash_base* t) { reset(t); }
00147     sc_phash_base_iter(sc_phash_base& t) { reset(t); }
00148     ~sc_phash_base_iter() { }
00149 
00150     bool empty() const;
00151     void step();
00152     void operator++(int) { step(); }
00153     void remove();
00154     void remove(void (*kfree)(void*));
00155     void* key() const;
00156     void* contents() const;
00157     void* set_contents(void* c);
00158 };
00159 
00160 template< class K, class C >
00161 class sc_phash_iter;
00162 
00163 template< class K, class C >
00164 class sc_phash : public sc_phash_base {
00165     friend class sc_phash_iter<K,C>;
00166 
00167 public:
00168     typedef sc_phash_iter<K,C> iterator;
00169 
00170     sc_phash( C def = (C) 0,
00171               int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00172               int density = PHASH_DEFAULT_MAX_DENSITY,
00173               double grow = PHASH_DEFAULT_GROW_FACTOR,
00174               bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00175               hash_fn_t hash_fn = default_ptr_hash_fn,
00176               cmpr_fn_t cmpr_fn = 0                          )
00177         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { }
00178     ~sc_phash() { }
00179 
00180     void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); }
00181     void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); }
00182     void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); }
00183 
00184     int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); }
00185     int insert(K k) { return sc_phash_base::insert((void*) k, default_value); }
00186     int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
00187     int insert_if_not_exists(K k, C c)
00188     {
00189         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c);
00190     }
00191     int insert_if_not_exists(K k)
00192     {
00193         return sc_phash_base::insert_if_not_exists((void*) k, default_value);
00194     }
00195     int insert_if_not_exists(K k, C c, void* (*kdup)(const void*))
00196     {
00197         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
00198     }
00199     int remove(K k) { return sc_phash_base::remove((const void*) k); }
00200     int remove(K k, K* pk, C* pc)
00201     {
00202         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00203     }
00204     int remove(K k, void (*kfree)(void*))
00205     {
00206         return sc_phash_base::remove((const void*) k, kfree);
00207     }
00208     int remove_by_contents(C c)
00209     {
00210         return sc_phash_base::remove_by_contents((const void*) c);
00211     }
00212     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00213     {
00214         return sc_phash_base::remove_by_contents(predicate, arg);
00215     }
00216     int remove_by_contents(const void* c, void (*kfree)(void*))
00217     {
00218         return sc_phash_base::remove_by_contents(c, kfree);
00219     }
00220     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*))
00221     {
00222         return sc_phash_base::remove_by_contents(predicate, arg, kfree);
00223     }
00224     int lookup(K k, C* pc) const
00225     {
00226         return sc_phash_base::lookup((const void*) k, (void**) pc);
00227     }
00228     bool contains(K k) const
00229     {
00230         return sc_phash_base::contains((const void*) k);
00231     }
00232     C operator[](K k) const
00233     {
00234         return (C) sc_phash_base::operator[]((const void*) k);
00235     }
00236 };
00237 
00238 
00239 template< class K, class C >
00240 class sc_phash_iter : public sc_phash_base_iter {
00241 public:
00242     sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { }
00243     sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { }
00244     ~sc_phash_iter() { }
00245 
00246     void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); }
00247     void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); }
00248 
00249     K key()      const { return (K) sc_phash_base_iter::key();      }
00250     C contents() const { return (C) sc_phash_base_iter::contents(); }
00251     C set_contents(C c)
00252     {
00253         return (C) sc_phash_base_iter::set_contents((void*) c);
00254     }
00255 };
00256 
00257 
00258 
00259 
00260 
00261 template< class K, class C >
00262 class sc_pdhash : public sc_phash_base {
00263     friend class sc_pdhash_iter<K,C>;
00264 
00265 private:
00266     void* (*kdup)(const void*); //eliminated braces around void* -- Amit
00267     void (*kfree)(void*);
00268 
00269 public:
00270     typedef sc_pdhash_iter<K,C> iterator;
00271     sc_pdhash( C def = (C) 0,
00272               int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00273               int density = PHASH_DEFAULT_MAX_DENSITY,
00274               double grow = PHASH_DEFAULT_GROW_FACTOR,
00275               bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00276               hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added --
00277               cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit
00278               void* (*kdup_fn)(const void*) = 0,
00279               void (*kfree_fn)(void*)  = 0 )
00280         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
00281     {
00282         kdup = kdup_fn;
00283         kfree = kfree_fn;
00284     }
00285     ~sc_pdhash()
00286     {
00287         erase();
00288     }
00289     void erase()
00290     {
00291         sc_phash_base::erase(kfree);
00292     }
00293     void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); }
00294     int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
00295     int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); }
00296     int insert_if_not_exists(K k, C c)
00297     {
00298         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
00299     }
00300     int insert_if_not_exists(K k)
00301     {
00302         return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup);
00303     }
00304     int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); }
00305     int remove(K k, K* pk, C* pc)
00306     {
00307         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00308     }
00309     int remove_by_contents(C c)
00310     {
00311         return sc_phash_base::remove_by_contents((const void*) c, kfree);
00312     }
00313     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00314     {
00315         return sc_phash_base::remove_by_contents(predicate, arg, kfree);
00316     }
00317     int lookup(K k, C* pc) const
00318     {
00319         return sc_phash_base::lookup((const void*) k, (void**) pc);
00320     }
00321     bool contains(K k) const
00322     {
00323         return sc_phash_base::contains((const void*) k);
00324     }
00325     C operator[](K k) const
00326     {
00327         return (C) sc_phash_base::operator[]((const void*) k);
00328     }
00329 };
00330 
00331 template< class K, class C >
00332 class sc_pdhash_iter : public sc_phash_base_iter {
00333 public:
00334     sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { }
00335     sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { }
00336     ~sc_pdhash_iter() { }
00337 
00338     void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); }
00339     void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); }
00340 
00341     void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); }
00342     K key()      const { return (K) sc_phash_base_iter::key();      }
00343     C contents() const { return (C) sc_phash_base_iter::contents(); }
00344     C set_contents(C c)
00345     {
00346         return (C) sc_phash_base_iter::set_contents((void*) c);
00347     }
00348 };
00349 
00350 extern int sc_strhash_cmp( const void*, const void* );
00351 extern void sc_strhash_kfree(void*);
00352 extern void* sc_strhash_kdup(const void*);
00353 
00354 template< class C >      // template class decl.
00355 class sc_strhash_iter;   // --Amit
00356 
00357 template< class C >
00358 class sc_strhash : public sc_phash_base {
00359     friend class sc_strhash_iter<C>;
00360 
00361 public:
00362     typedef sc_strhash_iter<C> iterator;
00363 
00364     sc_strhash( C def = (C) 0,
00365                 int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00366                 int density = PHASH_DEFAULT_MAX_DENSITY,
00367                 double grow = PHASH_DEFAULT_GROW_FACTOR,
00368                 bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00369                 unsigned (*hash_fn)(const void*) = default_str_hash_fn,
00370                 int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp )
00371         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
00372     {
00373 
00374     }
00375     ~sc_strhash()
00376     {
00377         erase();
00378     }
00379 
00380     void erase() { sc_phash_base::erase(sc_strhash_kfree); }
00381     void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); }
00382     void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); }
00383 
00384     int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); }
00385     int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); }
00386     int insert_if_not_exists(char* k, C c)
00387     {
00388         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup);
00389     }
00390     int insert_if_not_exists(char* k)
00391     {
00392         return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup);
00393     }
00394     int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); }
00395     int remove(const char* k, char** pk, C* pc)
00396     {
00397         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00398     }
00399     int remove_by_contents(C c)
00400     {
00401         return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree);
00402     }
00403     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00404     {
00405         return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree);
00406     }
00407     int lookup(const char* k, C* pc) const
00408     {
00409         return sc_phash_base::lookup((const void*) k, (void** )pc);
00410     }
00411     bool contains(const char* k) const
00412     {
00413         return sc_phash_base::contains((const void*) k);
00414     }
00415     C operator[](const char* k) const
00416     {
00417         return (C) sc_phash_base::operator[]((const void*) k);
00418     }
00419 };
00420 
00421 template<class C>
00422 class sc_strhash_iter : public sc_phash_base_iter {
00423 public:
00424     sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { }
00425     sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { }
00426     ~sc_strhash_iter() { }
00427 
00428     void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); }
00429     void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); }
00430 
00431     void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); }
00432     const char* key()   { return (const char*) sc_phash_base_iter::key(); }
00433     C contents()  { return (C) sc_phash_base_iter::contents(); }
00434     C set_contents(C c)
00435     {
00436         return (C) sc_phash_base_iter::set_contents((void*) c);
00437     }
00438 };
00439 
00440 } // namespace sc_core
00441 
00442 #endif

Generated on Wed Apr 25 13:53:28 2007 for SystemC by  doxygen 1.5.1