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

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: 
1.57.4.1! paf        12: static const char* IDENT_HASH_H="$Date: 2002/08/01 11:41:15 $";
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.57.4.1! paf        57:        /// put a [value] under the [key] @returns existed or not
        !            58:        bool put_case_insensitive(const Key& key, Val *value);
        !            59: 
1.51      paf        60:        /// remove the [key] @returns existed or not
                     61:        bool remove(const Key& key);
1.33      paf        62: /*
                     63:        /// dirty hack to allow constant items storage. I long for Hash<const Val*>
1.40      parser     64:        bool put(const Key& key, const Val *value) {
1.33      paf        65:                return put(key, const_cast<Val *>(value)); 
                     66:        }
                     67: */
1.29      paf        68:        /// get associated [value] by the [key]
1.40      parser     69:        Val *get(const Key& key) const;
1.17      paf        70: 
1.57.4.1! paf        71:        /// get associated [value] by they [key], ignoring case
        !            72:        Val *get_case_insensitive(const Key& key) const;
        !            73: 
1.51      paf        74:        /// put a [value] under the [key] if that [key] existed @returns existed or not
1.40      parser     75:        bool put_replace(const Key& key, Val *value);
1.18      paf        76: 
1.51      paf        77:        /// put a [value] under the [key] if that [key] NOT existed @returns existed or not
1.40      parser     78:        bool put_dont_replace(const Key& key, Val *value);
1.18      paf        79: 
1.57.4.1! paf        80:        /// put a [value] under the [key_lower] if that [key] NOT existed, ignoring case @returns existed or not
        !            81:        bool put_dont_replace_case_insensitive(const Key& key, Val *value);
        !            82: 
1.29      paf        83:        /// put all 'src' values if NO with same key existed
1.40      parser     84:        void merge_dont_replace(const Hash& src);
1.11      paf        85: 
1.30      paf        86:        void put(const Key& key, int     value) { put(key, reinterpret_cast<Val *>(value)); }
1.36      paf        87:        void put(const Key& key, const String *value) { 
                     88:                put(key, static_cast<Val *>(const_cast<String *>(value))); 
                     89:        }
1.11      paf        90: 
1.29      paf        91:        //@{
                     92:        /// handy get, longing for Hash<int>, Hash<String *>
1.32      paf        93:        int get_int(const Key& key) const { return reinterpret_cast<int>(get(key)); }
                     94:        const String *get_string(const Key& key) const { return static_cast<String *>(get(key)); }
1.29      paf        95:        //@}
1.10      paf        96: 
1.29      paf        97:        /// number of elements in hash
1.44      parser     98:        int size() const { return count; }
1.25      paf        99: 
1.29      paf       100:        /// iterate over all not zero elements
1.36      paf       101:        void for_each(For_each_func func, void *info=0) const;
1.45      paf       102: 
                    103:        /// iterate over all not zero elements, passing references
                    104:        void for_each(For_each_func_refed func, void *info=0) const;
1.38      paf       105: 
                    106:        /// iterate over all elements until condition
1.42      parser    107:        void *first_that(First_that_func func, void *info=0) const;
1.27      paf       108: 
1.29      paf       109:        /// remove all elements
1.27      paf       110:        void clear();
1.19      paf       111: 
1.15      paf       112: protected:
                    113: 
1.43      parser    114:        void construct_new();
                    115:        void construct_copy(const Hash& source);
1.15      paf       116: 
1.1       paf       117: private:
                    118: 
1.39      paf       119:        /// expand when these %% of allocated exausted
1.1       paf       120:        enum {
                    121:                THRESHOLD_PERCENT=75
                    122:        };
1.9       paf       123: 
1.39      paf       124:        /// the index of [allocated] in [allocates]
1.19      paf       125:        int allocates_index;
1.1       paf       126: 
1.39      paf       127:        /// possible [allocates]. prime numbers
1.19      paf       128:        static uint allocates[];
                    129:        static int allocates_count;
1.1       paf       130: 
1.39      paf       131:        /// number of allocated pairs
1.19      paf       132:        int allocated;
1.1       paf       133: 
1.39      paf       134:        /// helper: expanding when used == threshold
1.1       paf       135:        int threshold;
                    136: 
1.39      paf       137:        /// used pairs
1.1       paf       138:        int used;
1.44      parser    139: 
                    140:        /// stored pairs total (including those by links)
                    141:        int count;
1.1       paf       142: 
1.39      paf       143:        /// pair storage
1.1       paf       144:        class Pair {
1.46      paf       145:                friend class Hash;
1.2       paf       146: 
1.1       paf       147:                uint code;
1.47      paf       148:                const Key& key;
1.30      paf       149:                Val *value;
1.1       paf       150:                Pair *link;
1.2       paf       151:                
1.19      paf       152:                void *operator new(size_t allocated, Pool& apool);
1.2       paf       153: 
1.30      paf       154:                Pair(uint acode, const Key& akey, Val *avalue, Pair *alink) :
1.1       paf       155:                        code(acode),
                    156:                        key(akey),
                    157:                        value(avalue),
1.2       paf       158:                        link(alink) {}
                    159:        } **refs;
1.1       paf       160: 
1.39      paf       161:        /// filled to threshold: needs expanding
1.5       paf       162:        bool full() { return used==threshold; }
                    163: 
1.39      paf       164:        /// allocate larger buffer & rehash
1.1       paf       165:        void expand();
1.57.4.1! paf       166: 
        !           167: private: // internals
        !           168: 
        !           169:        /// get associated [value] by they [key], ignoring case
        !           170:        Val *get_case_insensitive_internal(const Key& key_lower) const;
        !           171: 
        !           172: 
1.4       paf       173: 
                    174: private: //disabled
                    175: 
1.12      paf       176:        Hash& operator = (const Hash&) { return *this; }
1.1       paf       177: };
1.49      paf       178: 
1.55      paf       179: ///    Auto-object used for temporarily substituting/removing hash values
                    180: class Temp_hash_value {
                    181:        Hash& fhash;
                    182:        const Hash::Key& fname;
                    183:        Hash::Val *saved_value;
                    184: public:
                    185:        Temp_hash_value(Hash& ahash, const Hash::Key& aname, Hash::Val *avalue) : 
                    186:                fhash(ahash),
                    187:                fname(aname),
                    188:                saved_value(ahash.get(aname)) {
                    189:                fhash.put(aname, avalue);
                    190:        }
                    191:        ~Temp_hash_value() { 
                    192:                fhash.put(fname, saved_value);
                    193:        }
                    194: };
1.1       paf       195: 
                    196: #endif

E-mail: