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-2006 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 // $Log: sc_hash.h,v $
00038 // Revision 1.1.1.1  2006/12/15 20:31:39  acg
00039 // SystemC 2.2
00040 //
00041 // Revision 1.3  2006/01/13 18:53:10  acg
00042 // Andy Goodrich: Added $Log command so that CVS comments are reproduced in
00043 // the source.
00044 //
00045 
00046 #ifndef SC_HASH_H
00047 #define SC_HASH_H
00048 
00049 
00050 namespace sc_core {
00051 
00052 extern unsigned default_int_hash_fn(const void*);
00053 extern unsigned default_ptr_hash_fn(const void*);
00054 extern unsigned default_str_hash_fn(const void*);
00055 
00056 class sc_phash_elem;
00057 class sc_phash_base_iter;
00058 template<class K, class C>  //template class 
00059 class sc_pdhash_iter;       //decl. -- Amit
00060 
00061 const int    PHASH_DEFAULT_MAX_DENSITY     = 5;
00062 const int    PHASH_DEFAULT_INIT_TABLE_SIZE = 11;
00063 extern const double PHASH_DEFAULT_GROW_FACTOR;
00064 const bool   PHASH_DEFAULT_REORDER_FLAG    = true;
00065 
00066 class sc_phash_base {
00067     friend class sc_phash_base_iter;
00068 
00069     typedef sc_phash_base_iter iterator;
00070 
00071 public:
00072     typedef unsigned (*hash_fn_t)(const void*);
00073     typedef int (*cmpr_fn_t)(const void*, const void*);
00074 
00075 protected:
00076     void*    default_value;
00077     int      num_bins;
00078     int      num_entries;
00079     int      max_density;
00080     int      reorder_flag;
00081     double   grow_factor;
00082 
00083     sc_phash_elem** bins;
00084 
00085     hash_fn_t hash;
00086     cmpr_fn_t cmpr;
00087 
00088     void rehash();
00089     unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; }
00090 
00091     sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val);
00092     sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast);
00093     sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast);
00094     sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const
00095     {
00096       /* Got rid of member func. pointer and replaced with if-else  */
00097       /* Amit (5/14/99)                                             */
00098       if( cmpr == 0 )
00099         return ((sc_phash_base*)this)->find_entry_q( hv, k, plast );
00100       else 
00101     return ((sc_phash_base*)this)->find_entry_c( hv, k, plast );
00102     }
00103 
00104 public:
00105     sc_phash_base( void* def       = 0,
00106                    int    size     = PHASH_DEFAULT_INIT_TABLE_SIZE,
00107                    int    density  = PHASH_DEFAULT_MAX_DENSITY,
00108                    double grow     = PHASH_DEFAULT_GROW_FACTOR,
00109                    bool   reorder  = PHASH_DEFAULT_REORDER_FLAG,    
00110                    hash_fn_t hash_fn = default_ptr_hash_fn,
00111                    cmpr_fn_t cmpr_fn = 0                             );
00112     ~sc_phash_base();
00113 
00114     void set_cmpr_fn(cmpr_fn_t);
00115     void set_hash_fn(hash_fn_t);
00116 
00117     bool empty() const { return (num_entries == 0); }
00118     unsigned count() const { return num_entries; }
00119 
00120     void erase();
00121     void erase(void (*kfree)(void*));
00122     void copy( const sc_phash_base* );
00123     void copy( const sc_phash_base& b ) { copy(&b); }
00124     void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*));
00125     int insert( void* k, void* c );
00126     int insert( void* k ) { return insert(k, default_value); }
00127     int insert( void* k, void* c, void* (*kdup)(const void*) );
00128     int insert_if_not_exists(void* k, void* c);
00129     int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); }
00130     int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*));
00131     int remove(const void* k);
00132     int remove(const void* k, void** pk, void** pc);
00133     int remove(const void* k, void (*kfree)(void*));
00134     int remove_by_contents(const void* c);
00135     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg);
00136     int remove_by_contents(const void* c, void (*kfree)(void*));
00137     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*));
00138     int lookup(const void* k, void** pc) const;
00139     bool contains(const void* k) const { return (lookup(k, 0) != 0); }
00140     void* operator[](const void* key) const;
00141 };
00142 
00143 class sc_phash_base_iter {
00144 protected:
00145     sc_phash_base*  table;
00146     sc_phash_elem*  entry;
00147     sc_phash_elem*  next;
00148     sc_phash_elem** last;
00149     int             index;
00150 
00151 public:
00152     void reset(sc_phash_base* t);
00153     void reset(sc_phash_base& t) { reset(&t); }
00154 
00155     sc_phash_base_iter(sc_phash_base* t) { reset(t); }
00156     sc_phash_base_iter(sc_phash_base& t) { reset(t); }
00157     ~sc_phash_base_iter() { }
00158 
00159     bool empty() const;
00160     void step();
00161     void operator++(int) { step(); }
00162     void remove();
00163     void remove(void (*kfree)(void*));
00164     void* key() const;
00165     void* contents() const;
00166     void* set_contents(void* c);
00167 };
00168 
00169 template< class K, class C >
00170 class sc_phash_iter;
00171 
00172 template< class K, class C >
00173 class sc_phash : public sc_phash_base {
00174     friend class sc_phash_iter<K,C>;
00175 
00176 public:
00177     typedef sc_phash_iter<K,C> iterator;
00178 
00179     sc_phash( C def = (C) 0,
00180               int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00181               int density = PHASH_DEFAULT_MAX_DENSITY,
00182               double grow = PHASH_DEFAULT_GROW_FACTOR,
00183               bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00184               hash_fn_t hash_fn = default_ptr_hash_fn,
00185               cmpr_fn_t cmpr_fn = 0                          )
00186         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { }
00187     ~sc_phash() { }
00188 
00189     void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); }
00190     void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); }
00191     void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); }
00192 
00193     int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); }
00194     int insert(K k) { return sc_phash_base::insert((void*) k, default_value); }
00195     int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
00196     int insert_if_not_exists(K k, C c)
00197     {
00198         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c);
00199     }
00200     int insert_if_not_exists(K k)
00201     {
00202         return sc_phash_base::insert_if_not_exists((void*) k, default_value);
00203     }
00204     int insert_if_not_exists(K k, C c, void* (*kdup)(const void*))
00205     {
00206         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
00207     }
00208     int remove(K k) { return sc_phash_base::remove((const void*) k); }
00209     int remove(K k, K* pk, C* pc)
00210     {
00211         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00212     }
00213     int remove(K k, void (*kfree)(void*))
00214     {
00215         return sc_phash_base::remove((const void*) k, kfree);
00216     }
00217     int remove_by_contents(C c)
00218     {
00219         return sc_phash_base::remove_by_contents((const void*) c);
00220     }
00221     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00222     {
00223         return sc_phash_base::remove_by_contents(predicate, arg);
00224     }
00225     int remove_by_contents(const void* c, void (*kfree)(void*))
00226     {
00227         return sc_phash_base::remove_by_contents(c, kfree);
00228     }
00229     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*))
00230     {
00231         return sc_phash_base::remove_by_contents(predicate, arg, kfree);
00232     }
00233     int lookup(K k, C* pc) const
00234     {
00235         return sc_phash_base::lookup((const void*) k, (void**) pc);
00236     }
00237     bool contains(K k) const
00238     {
00239         return sc_phash_base::contains((const void*) k);
00240     }
00241     C operator[](K k) const
00242     {
00243         return (C) sc_phash_base::operator[]((const void*) k);
00244     }
00245 };
00246 
00247 
00248 template< class K, class C >
00249 class sc_phash_iter : public sc_phash_base_iter {
00250 public:
00251     sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { }
00252     sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { }
00253     ~sc_phash_iter() { }
00254 
00255     void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); }
00256     void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); }
00257 
00258     K key()      const { return (K) sc_phash_base_iter::key();      }
00259     C contents() const { return (C) sc_phash_base_iter::contents(); }
00260     C set_contents(C c)
00261     {
00262         return (C) sc_phash_base_iter::set_contents((void*) c);
00263     }
00264 };
00265 
00266 
00267 
00268 
00269 
00270 template< class K, class C >
00271 class sc_pdhash : public sc_phash_base {
00272     friend class sc_pdhash_iter<K,C>;
00273 
00274 private:
00275     void* (*kdup)(const void*); //eliminated braces around void* -- Amit
00276     void (*kfree)(void*);
00277 
00278 public:
00279     typedef sc_pdhash_iter<K,C> iterator;
00280     sc_pdhash( C def = (C) 0,
00281               int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00282               int density = PHASH_DEFAULT_MAX_DENSITY,
00283               double grow = PHASH_DEFAULT_GROW_FACTOR,
00284               bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00285               hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added --
00286               cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit
00287               void* (*kdup_fn)(const void*) = 0,
00288               void (*kfree_fn)(void*)  = 0 )
00289         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
00290     {
00291         kdup = kdup_fn;
00292         kfree = kfree_fn;
00293     }
00294     ~sc_pdhash()
00295     {
00296         erase();
00297     }
00298     void erase()
00299     {
00300         sc_phash_base::erase(kfree);
00301     }
00302     void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); }
00303     int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
00304     int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); }
00305     int insert_if_not_exists(K k, C c)
00306     {
00307         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
00308     }
00309     int insert_if_not_exists(K k)
00310     {
00311         return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup);
00312     }
00313     int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); }
00314     int remove(K k, K* pk, C* pc)
00315     {
00316         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00317     }
00318     int remove_by_contents(C c)
00319     {
00320         return sc_phash_base::remove_by_contents((const void*) c, kfree);
00321     }
00322     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00323     {
00324         return sc_phash_base::remove_by_contents(predicate, arg, kfree);
00325     }
00326     int lookup(K k, C* pc) const
00327     {
00328         return sc_phash_base::lookup((const void*) k, (void**) pc);
00329     }
00330     bool contains(K k) const
00331     {
00332         return sc_phash_base::contains((const void*) k);
00333     }
00334     C operator[](K k) const
00335     {
00336         return (C) sc_phash_base::operator[]((const void*) k);
00337     }
00338 };
00339 
00340 template< class K, class C >
00341 class sc_pdhash_iter : public sc_phash_base_iter {
00342 public:
00343     sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { }
00344     sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { }
00345     ~sc_pdhash_iter() { }
00346 
00347     void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); }
00348     void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); }
00349 
00350     void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); }
00351     K key()      const { return (K) sc_phash_base_iter::key();      }
00352     C contents() const { return (C) sc_phash_base_iter::contents(); }
00353     C set_contents(C c)
00354     {
00355         return (C) sc_phash_base_iter::set_contents((void*) c);
00356     }
00357 };
00358 
00359 extern int sc_strhash_cmp( const void*, const void* );
00360 extern void sc_strhash_kfree(void*);
00361 extern void* sc_strhash_kdup(const void*);
00362 
00363 template< class C >      // template class decl.
00364 class sc_strhash_iter;   // --Amit
00365 
00366 template< class C >
00367 class sc_strhash : public sc_phash_base {
00368     friend class sc_strhash_iter<C>;
00369 
00370 public:
00371     typedef sc_strhash_iter<C> iterator;
00372 
00373     sc_strhash( C def = (C) 0,
00374                 int size    = PHASH_DEFAULT_INIT_TABLE_SIZE,
00375                 int density = PHASH_DEFAULT_MAX_DENSITY,
00376                 double grow = PHASH_DEFAULT_GROW_FACTOR,
00377                 bool reorder = PHASH_DEFAULT_REORDER_FLAG,
00378                 unsigned (*hash_fn)(const void*) = default_str_hash_fn,
00379                 int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp )
00380         : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
00381     {
00382 
00383     }
00384     ~sc_strhash()
00385     {
00386         erase();
00387     }
00388 
00389     void erase() { sc_phash_base::erase(sc_strhash_kfree); }
00390     void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); }
00391     void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); }
00392 
00393     int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); }
00394     int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); }
00395     int insert_if_not_exists(char* k, C c)
00396     {
00397         return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup);
00398     }
00399     int insert_if_not_exists(char* k)
00400     {
00401         return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup);
00402     }
00403     int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); }
00404     int remove(const char* k, char** pk, C* pc)
00405     {
00406         return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
00407     }
00408     int remove_by_contents(C c)
00409     {
00410         return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree);
00411     }
00412     int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
00413     {
00414         return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree);
00415     }
00416     int lookup(const char* k, C* pc) const
00417     {
00418         return sc_phash_base::lookup((const void*) k, (void** )pc);
00419     }
00420     bool contains(const char* k) const
00421     {
00422         return sc_phash_base::contains((const void*) k);
00423     }
00424     C operator[](const char* k) const
00425     {
00426         return (C) sc_phash_base::operator[]((const void*) k);
00427     }
00428 };
00429 
00430 template<class C>
00431 class sc_strhash_iter : public sc_phash_base_iter {
00432 public:
00433     sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { }
00434     sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { }
00435     ~sc_strhash_iter() { }
00436 
00437     void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); }
00438     void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); }
00439 
00440     void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); }
00441     const char* key()   { return (const char*) sc_phash_base_iter::key(); }
00442     C contents()  { return (C) sc_phash_base_iter::contents(); }
00443     C set_contents(C c)
00444     {
00445         return (C) sc_phash_base_iter::set_contents((void*) c);
00446     }
00447 };
00448 
00449 } // namespace sc_core
00450 
00451 #endif

Generated on Wed Jan 21 15:32:10 2009 for SystemC by  doxygen 1.5.5