| /***************************************************************************** |
| |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or |
| more contributor license agreements. See the NOTICE file distributed |
| with this work for additional information regarding copyright ownership. |
| Accellera licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| implied. See the License for the specific language governing |
| permissions and limitations under the License. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| sc_hash.cpp -- Implementation of a chained hash table with MTF |
| (move-to-front). |
| |
| Original Author: Stan Y. Liao, Synopsys, Inc. |
| |
| CHANGE LOG AT END OF FILE |
| *****************************************************************************/ |
| |
| #ifndef SC_HASH_H |
| #define SC_HASH_H |
| |
| |
| namespace sc_core { |
| |
| extern unsigned default_int_hash_fn(const void*); |
| extern unsigned default_ptr_hash_fn(const void*); |
| extern unsigned default_str_hash_fn(const void*); |
| |
| class sc_phash_elem; |
| class sc_phash_base_iter; |
| template<class K, class C> //template class |
| class sc_pdhash_iter; //decl. -- Amit |
| |
| const int PHASH_DEFAULT_MAX_DENSITY = 5; |
| const int PHASH_DEFAULT_INIT_TABLE_SIZE = 11; |
| extern const double PHASH_DEFAULT_GROW_FACTOR; |
| const bool PHASH_DEFAULT_REORDER_FLAG = true; |
| |
| class sc_phash_base { |
| friend class sc_phash_base_iter; |
| |
| typedef sc_phash_base_iter iterator; |
| |
| public: |
| typedef unsigned (*hash_fn_t)(const void*); |
| typedef int (*cmpr_fn_t)(const void*, const void*); |
| |
| protected: |
| void* default_value; |
| int num_bins; |
| int num_entries; |
| int max_density; |
| int reorder_flag; |
| double grow_factor; |
| |
| sc_phash_elem** bins; |
| |
| hash_fn_t hash; |
| cmpr_fn_t cmpr; |
| |
| void rehash(); |
| unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; } |
| |
| sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val); |
| sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast); |
| sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast); |
| sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const |
| { |
| /* Got rid of member func. pointer and replaced with if-else */ |
| /* Amit (5/14/99) */ |
| if( cmpr == 0 ) |
| return ((sc_phash_base*)this)->find_entry_q( hv, k, plast ); |
| else |
| return ((sc_phash_base*)this)->find_entry_c( hv, k, plast ); |
| } |
| |
| public: |
| sc_phash_base( void* def = 0, |
| int size = PHASH_DEFAULT_INIT_TABLE_SIZE, |
| int density = PHASH_DEFAULT_MAX_DENSITY, |
| double grow = PHASH_DEFAULT_GROW_FACTOR, |
| bool reorder = PHASH_DEFAULT_REORDER_FLAG, |
| hash_fn_t hash_fn = default_ptr_hash_fn, |
| cmpr_fn_t cmpr_fn = 0 ); |
| ~sc_phash_base(); |
| |
| void set_cmpr_fn(cmpr_fn_t); |
| void set_hash_fn(hash_fn_t); |
| |
| bool empty() const { return (num_entries == 0); } |
| unsigned count() const { return num_entries; } |
| |
| void erase(); |
| void erase(void (*kfree)(void*)); |
| void copy( const sc_phash_base* ); |
| void copy( const sc_phash_base& b ) { copy(&b); } |
| void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*)); |
| int insert( void* k, void* c ); |
| int insert( void* k ) { return insert(k, default_value); } |
| int insert( void* k, void* c, void* (*kdup)(const void*) ); |
| int insert_if_not_exists(void* k, void* c); |
| int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); } |
| int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*)); |
| int remove(const void* k); |
| int remove(const void* k, void** pk, void** pc); |
| int remove(const void* k, void (*kfree)(void*)); |
| int remove_by_contents(const void* c); |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg); |
| int remove_by_contents(const void* c, void (*kfree)(void*)); |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)); |
| int lookup(const void* k, void** pc) const; |
| bool contains(const void* k) const { return (lookup(k, 0) != 0); } |
| void* operator[](const void* key) const; |
| }; |
| |
| class sc_phash_base_iter { |
| protected: |
| sc_phash_base* table; |
| sc_phash_elem* entry; |
| sc_phash_elem* next; |
| sc_phash_elem** last; |
| int index; |
| |
| public: |
| void reset(sc_phash_base* t); |
| void reset(sc_phash_base& t) { reset(&t); } |
| |
| sc_phash_base_iter(sc_phash_base* t) |
| : table(t), entry(0), next(0), last(0), index(0) |
| { reset(t); } |
| sc_phash_base_iter(sc_phash_base& t) |
| : table(&t), entry(0), next(0), last(0), index(0) |
| { reset(t); } |
| ~sc_phash_base_iter() { } |
| |
| bool empty() const; |
| void step(); |
| void operator++(int) { step(); } |
| void remove(); |
| void remove(void (*kfree)(void*)); |
| void* key() const; |
| void* contents() const; |
| void* set_contents(void* c); |
| }; |
| |
| template< class K, class C > |
| class sc_phash_iter; |
| |
| template< class K, class C > |
| class sc_phash : public sc_phash_base { |
| friend class sc_phash_iter<K,C>; |
| |
| public: |
| typedef sc_phash_iter<K,C> iterator; |
| |
| sc_phash( C def = (C) 0, |
| int size = PHASH_DEFAULT_INIT_TABLE_SIZE, |
| int density = PHASH_DEFAULT_MAX_DENSITY, |
| double grow = PHASH_DEFAULT_GROW_FACTOR, |
| bool reorder = PHASH_DEFAULT_REORDER_FLAG, |
| hash_fn_t hash_fn = default_ptr_hash_fn, |
| cmpr_fn_t cmpr_fn = 0 ) |
| : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { } |
| ~sc_phash() { } |
| |
| void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); } |
| void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); } |
| void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); } |
| |
| int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); } |
| int insert(K k) { return sc_phash_base::insert((void*) k, default_value); } |
| int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } |
| int insert_if_not_exists(K k, C c) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, (void*) c); |
| } |
| int insert_if_not_exists(K k) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, default_value); |
| } |
| int insert_if_not_exists(K k, C c, void* (*kdup)(const void*)) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); |
| } |
| int remove(K k) { return sc_phash_base::remove((const void*) k); } |
| int remove(K k, K* pk, C* pc) |
| { |
| return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); |
| } |
| int remove(K k, void (*kfree)(void*)) |
| { |
| return sc_phash_base::remove((const void*) k, kfree); |
| } |
| int remove_by_contents(C c) |
| { |
| return sc_phash_base::remove_by_contents((const void*) c); |
| } |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) |
| { |
| return sc_phash_base::remove_by_contents(predicate, arg); |
| } |
| int remove_by_contents(const void* c, void (*kfree)(void*)) |
| { |
| return sc_phash_base::remove_by_contents(c, kfree); |
| } |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)) |
| { |
| return sc_phash_base::remove_by_contents(predicate, arg, kfree); |
| } |
| int lookup(K k, C* pc) const |
| { |
| return sc_phash_base::lookup((const void*) k, (void**) pc); |
| } |
| bool contains(K k) const |
| { |
| return sc_phash_base::contains((const void*) k); |
| } |
| C operator[](K k) const |
| { |
| return (C) sc_phash_base::operator[]((const void*) k); |
| } |
| }; |
| |
| |
| template< class K, class C > |
| class sc_phash_iter : public sc_phash_base_iter { |
| public: |
| sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { } |
| sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { } |
| ~sc_phash_iter() { } |
| |
| void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); } |
| void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); } |
| |
| K key() const { return (K) sc_phash_base_iter::key(); } |
| C contents() const { return (C) sc_phash_base_iter::contents(); } |
| C set_contents(C c) |
| { |
| return (C) sc_phash_base_iter::set_contents((void*) c); |
| } |
| }; |
| |
| |
| |
| |
| |
| template< class K, class C > |
| class sc_pdhash : public sc_phash_base { |
| friend class sc_pdhash_iter<K,C>; |
| |
| private: |
| void* (*kdup)(const void*); //eliminated braces around void* -- Amit |
| void (*kfree)(void*); |
| |
| public: |
| typedef sc_pdhash_iter<K,C> iterator; |
| sc_pdhash( C def = (C) 0, |
| int size = PHASH_DEFAULT_INIT_TABLE_SIZE, |
| int density = PHASH_DEFAULT_MAX_DENSITY, |
| double grow = PHASH_DEFAULT_GROW_FACTOR, |
| bool reorder = PHASH_DEFAULT_REORDER_FLAG, |
| hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added -- |
| cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit |
| void* (*kdup_fn)(const void*) = 0, |
| void (*kfree_fn)(void*) = 0 ) |
| : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) |
| { |
| kdup = kdup_fn; |
| kfree = kfree_fn; |
| } |
| ~sc_pdhash() |
| { |
| erase(); |
| } |
| void erase() |
| { |
| sc_phash_base::erase(kfree); |
| } |
| void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); } |
| int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } |
| int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); } |
| int insert_if_not_exists(K k, C c) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); |
| } |
| int insert_if_not_exists(K k) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup); |
| } |
| int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); } |
| int remove(K k, K* pk, C* pc) |
| { |
| return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); |
| } |
| int remove_by_contents(C c) |
| { |
| return sc_phash_base::remove_by_contents((const void*) c, kfree); |
| } |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) |
| { |
| return sc_phash_base::remove_by_contents(predicate, arg, kfree); |
| } |
| int lookup(K k, C* pc) const |
| { |
| return sc_phash_base::lookup((const void*) k, (void**) pc); |
| } |
| bool contains(K k) const |
| { |
| return sc_phash_base::contains((const void*) k); |
| } |
| C operator[](K k) const |
| { |
| return (C) sc_phash_base::operator[]((const void*) k); |
| } |
| }; |
| |
| template< class K, class C > |
| class sc_pdhash_iter : public sc_phash_base_iter { |
| public: |
| sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { } |
| sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { } |
| ~sc_pdhash_iter() { } |
| |
| void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); } |
| void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); } |
| |
| void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); } |
| K key() const { return (K) sc_phash_base_iter::key(); } |
| C contents() const { return (C) sc_phash_base_iter::contents(); } |
| C set_contents(C c) |
| { |
| return (C) sc_phash_base_iter::set_contents((void*) c); |
| } |
| }; |
| |
| extern int sc_strhash_cmp( const void*, const void* ); |
| extern void sc_strhash_kfree(void*); |
| extern void* sc_strhash_kdup(const void*); |
| |
| template< class C > // template class decl. |
| class sc_strhash_iter; // --Amit |
| |
| template< class C > |
| class sc_strhash : public sc_phash_base { |
| friend class sc_strhash_iter<C>; |
| |
| public: |
| typedef sc_strhash_iter<C> iterator; |
| |
| sc_strhash( C def = (C) 0, |
| int size = PHASH_DEFAULT_INIT_TABLE_SIZE, |
| int density = PHASH_DEFAULT_MAX_DENSITY, |
| double grow = PHASH_DEFAULT_GROW_FACTOR, |
| bool reorder = PHASH_DEFAULT_REORDER_FLAG, |
| unsigned (*hash_fn)(const void*) = default_str_hash_fn, |
| int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp ) |
| : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) |
| { |
| |
| } |
| ~sc_strhash() |
| { |
| erase(); |
| } |
| |
| void erase() { sc_phash_base::erase(sc_strhash_kfree); } |
| void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); } |
| void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); } |
| |
| int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); } |
| int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); } |
| int insert_if_not_exists(char* k, C c) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup); |
| } |
| int insert_if_not_exists(char* k) |
| { |
| return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup); |
| } |
| int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); } |
| int remove(const char* k, char** pk, C* pc) |
| { |
| return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); |
| } |
| int remove_by_contents(C c) |
| { |
| return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree); |
| } |
| int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) |
| { |
| return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree); |
| } |
| int lookup(const char* k, C* pc) const |
| { |
| return sc_phash_base::lookup((const void*) k, (void** )pc); |
| } |
| bool contains(const char* k) const |
| { |
| return sc_phash_base::contains((const void*) k); |
| } |
| C operator[](const char* k) const |
| { |
| return (C) sc_phash_base::operator[]((const void*) k); |
| } |
| }; |
| |
| template<class C> |
| class sc_strhash_iter : public sc_phash_base_iter { |
| public: |
| sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { } |
| sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { } |
| ~sc_strhash_iter() { } |
| |
| void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); } |
| void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); } |
| |
| void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); } |
| const char* key() { return (const char*) sc_phash_base_iter::key(); } |
| C contents() { return (C) sc_phash_base_iter::contents(); } |
| C set_contents(C c) |
| { |
| return (C) sc_phash_base_iter::set_contents((void*) c); |
| } |
| }; |
| |
| } // namespace sc_core |
| |
| // $Log: sc_hash.h,v $ |
| // Revision 1.5 2011/08/29 18:04:32 acg |
| // Philipp A. Hartmann: miscellaneous clean ups. |
| // |
| // Revision 1.4 2011/08/26 20:46:16 acg |
| // Andy Goodrich: moved the modification log to the end of the file to |
| // eliminate source line number skew when check-ins are done. |
| // |
| // Revision 1.3 2011/08/24 22:05:56 acg |
| // Torsten Maehne: initialization changes to remove warnings. |
| // |
| // Revision 1.2 2011/02/18 20:38:43 acg |
| // Andy Goodrich: Updated Copyright notice. |
| // |
| // Revision 1.1.1.1 2006/12/15 20:20:06 acg |
| // SystemC 2.3 |
| // |
| // Revision 1.3 2006/01/13 18:53:10 acg |
| // Andy Goodrich: Added $Log command so that CVS comments are reproduced in |
| // the source. |
| |
| #endif |