Annotation of parser3/src/include/pa_hash.h, revision 1.56

1.28      paf         1: /** @file
1.29      paf         2:        Parser: hash class decl.
                      3: 
1.53      paf         4:        Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.29      paf         5: 
1.54      paf         6:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         7: */
                      8: 
                      9: #ifndef PA_HASH_H
                     10: #define PA_HASH_H
1.56    ! paf        11: 
        !            12: static const char* IDENT_HASH_H="$Id: zzz $";
1.1       paf        13: 
1.14      paf        14: #include "pa_pool.h"
1.1       paf        15: #include "pa_types.h"
                     16: #include "pa_string.h"
                     17: 
1.29      paf        18: /** 
                     19:        Pooled hash.
                     20: 
                     21:        Automatically rehashed when almost full.
1.51      paf        22:        Contains no 0 values. 
                     23:                get returning 0 means there were no such.
                     24:                "put value 0" means "remove"
1.29      paf        25: */
1.23      paf        26: class Hash : public Pooled {
1.1       paf        27: public:
                     28: 
1.29      paf        29:        typedef String Key; ///< hash Key type. longing for templates
1.30      paf        30:        typedef void Val; ///< hash Val type. longing for templates
1.3       paf        31: 
1.31      paf        32:        /// for_each iterator function type
                     33:        typedef void (*For_each_func)(const Key& key, Val *value, void *info);
1.25      paf        34: 
1.45      paf        35:        /// for_each iterator function type
                     36:        typedef void (*For_each_func_refed)(const Key& key, Val *& value, void *info);
                     37: 
1.38      paf        38:        /// first_that iterator function type
1.42      parser     39:        typedef void *(*First_that_func)(const Key& key, Val *value, void *info);
1.38      paf        40: 
1.8       paf        41: public:
                     42: 
1.35      paf        43:        Hash(Pool& apool) : Pooled(apool) { 
1.43      parser     44:                construct_new(); 
                     45:        }
                     46: 
                     47:        Hash(const Hash& source) : Pooled(source.pool()){
                     48:                construct_copy(source);
1.24      paf        49:        }
1.10      paf        50: 
1.29      paf        51:        /// useful generic hash function
1.19      paf        52:        static uint generic_code(uint aresult, const char *start, uint allocated);
1.8       paf        53: 
1.51      paf        54:        /// put a [value] under the [key] @returns existed or not
1.40      parser     55:        bool put(const Key& key, Val *value);
1.48      paf        56: 
1.51      paf        57:        /// remove the [key] @returns existed or not
                     58:        bool remove(const Key& key);
1.33      paf        59: /*
                     60:        /// dirty hack to allow constant items storage. I long for Hash<const Val*>
1.40      parser     61:        bool put(const Key& key, const Val *value) {
1.33      paf        62:                return put(key, const_cast<Val *>(value)); 
                     63:        }
                     64: */
1.29      paf        65:        /// get associated [value] by the [key]
1.40      parser     66:        Val *get(const Key& key) const;
1.17      paf        67: 
1.51      paf        68:        /// put a [value] under the [key] if that [key] existed @returns existed or not
1.40      parser     69:        bool put_replace(const Key& key, Val *value);
1.18      paf        70: 
1.51      paf        71:        /// put a [value] under the [key] if that [key] NOT existed @returns existed or not
1.40      parser     72:        bool put_dont_replace(const Key& key, Val *value);
1.18      paf        73: 
1.29      paf        74:        /// put all 'src' values if NO with same key existed
1.40      parser     75:        void merge_dont_replace(const Hash& src);
1.11      paf        76: 
1.30      paf        77:        void put(const Key& key, int     value) { put(key, reinterpret_cast<Val *>(value)); }
1.36      paf        78:        void put(const Key& key, const String *value) { 
                     79:                put(key, static_cast<Val *>(const_cast<String *>(value))); 
                     80:        }
1.11      paf        81: 
1.29      paf        82:        //@{
                     83:        /// handy get, longing for Hash<int>, Hash<String *>
1.32      paf        84:        int get_int(const Key& key) const { return reinterpret_cast<int>(get(key)); }
                     85:        const String *get_string(const Key& key) const { return static_cast<String *>(get(key)); }
1.29      paf        86:        //@}
1.10      paf        87: 
1.29      paf        88:        /// number of elements in hash
1.44      parser     89:        int size() const { return count; }
1.25      paf        90: 
1.29      paf        91:        /// iterate over all not zero elements
1.36      paf        92:        void for_each(For_each_func func, void *info=0) const;
1.45      paf        93: 
                     94:        /// iterate over all not zero elements, passing references
                     95:        void for_each(For_each_func_refed func, void *info=0) const;
1.38      paf        96: 
                     97:        /// iterate over all elements until condition
1.42      parser     98:        void *first_that(First_that_func func, void *info=0) const;
1.27      paf        99: 
1.29      paf       100:        /// remove all elements
1.27      paf       101:        void clear();
1.19      paf       102: 
1.15      paf       103: protected:
                    104: 
1.43      parser    105:        void construct_new();
                    106:        void construct_copy(const Hash& source);
1.15      paf       107: 
1.1       paf       108: private:
                    109: 
1.39      paf       110:        /// expand when these %% of allocated exausted
1.1       paf       111:        enum {
                    112:                THRESHOLD_PERCENT=75
                    113:        };
1.9       paf       114: 
1.39      paf       115:        /// the index of [allocated] in [allocates]
1.19      paf       116:        int allocates_index;
1.1       paf       117: 
1.39      paf       118:        /// possible [allocates]. prime numbers
1.19      paf       119:        static uint allocates[];
                    120:        static int allocates_count;
1.1       paf       121: 
1.39      paf       122:        /// number of allocated pairs
1.19      paf       123:        int allocated;
1.1       paf       124: 
1.39      paf       125:        /// helper: expanding when used == threshold
1.1       paf       126:        int threshold;
                    127: 
1.39      paf       128:        /// used pairs
1.1       paf       129:        int used;
1.44      parser    130: 
                    131:        /// stored pairs total (including those by links)
                    132:        int count;
1.1       paf       133: 
1.39      paf       134:        /// pair storage
1.1       paf       135:        class Pair {
1.46      paf       136:                friend class Hash;
1.2       paf       137: 
1.1       paf       138:                uint code;
1.47      paf       139:                const Key& key;
1.30      paf       140:                Val *value;
1.1       paf       141:                Pair *link;
1.2       paf       142:                
1.19      paf       143:                void *operator new(size_t allocated, Pool& apool);
1.2       paf       144: 
1.30      paf       145:                Pair(uint acode, const Key& akey, Val *avalue, Pair *alink) :
1.1       paf       146:                        code(acode),
                    147:                        key(akey),
                    148:                        value(avalue),
1.2       paf       149:                        link(alink) {}
                    150:        } **refs;
1.1       paf       151: 
1.39      paf       152:        /// filled to threshold: needs expanding
1.5       paf       153:        bool full() { return used==threshold; }
                    154: 
1.39      paf       155:        /// allocate larger buffer & rehash
1.1       paf       156:        void expand();
1.4       paf       157: 
                    158: private: //disabled
                    159: 
1.12      paf       160:        Hash& operator = (const Hash&) { return *this; }
1.1       paf       161: };
1.49      paf       162: 
1.55      paf       163: ///    Auto-object used for temporarily substituting/removing hash values
                    164: class Temp_hash_value {
                    165:        Hash& fhash;
                    166:        const Hash::Key& fname;
                    167:        Hash::Val *saved_value;
                    168: public:
                    169:        Temp_hash_value(Hash& ahash, const Hash::Key& aname, Hash::Val *avalue) : 
                    170:                fhash(ahash),
                    171:                fname(aname),
                    172:                saved_value(ahash.get(aname)) {
                    173:                fhash.put(aname, avalue);
                    174:        }
                    175:        ~Temp_hash_value() { 
                    176:                fhash.put(fname, saved_value);
                    177:        }
                    178: };
1.1       paf       179: 
                    180: #endif

E-mail: