Annotation of parser3/src/include/pa_inline_hash.h, revision 1.3

1.1       moko        1: /** @file
                      2:        Parser: inline-storage hash decls.
                      3: 
1.3     ! moko        4:        Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
1.1       moko        5:        Authors: Konstantin Morshnev <moko@design.ru>
                      6: */
                      7: 
                      8: #ifndef PA_INLINE_HASH_H
                      9: #define PA_INLINE_HASH_H
                     10: 
1.3     ! moko       11: #define IDENT_PA_INLINE_HASH_H "$Id: pa_inline_hash.h,v 1.2 2026/04/25 02:28:31 moko Exp $"
1.1       moko       12: 
                     13: #include "pa_hash.h"
                     14: 
                     15: #define PA_HASH_INLINE_SIZE 4
                     16: 
                     17: /// Inline-storage "hash" stores up to PA_HASH_INLINE_SIZE entries without heap allocation.
                     18: /// Fallbacks to HashString for overflow.
                     19: 
1.2       moko       20: template<typename V> class InlineHashString: public PA_Object {
1.1       moko       21: public:
                     22: 
                     23:        struct Pair {
                     24:                String::Body key;
                     25:                V value;
                     26:        };
                     27: 
                     28:        InlineHashString() : fcount(0), foverflow(0) {}
                     29: 
1.2       moko       30: #ifdef USE_DESTRUCTORS
                     31:        ~InlineHashString() { if(foverflow) delete foverflow; }
                     32: #endif
                     33: 
1.1       moko       34:        V get(const String& name) const {
                     35:                const String::Body& nb = name;
                     36:                const uint code = nb.get_hash_code();
                     37:                for(int i = 0; i < fcount; i++) {
                     38:                        const String::Body& key = fpairs[i].key;
                     39:                        if(key.get_hash_code() == code && key == nb)
                     40:                                return fpairs[i].value;
                     41:                }
                     42:                return foverflow ? foverflow->get(name) : 0;
                     43:        }
                     44: 
                     45:        bool put(const String& name, V value) {
                     46:                const String::Body& nb = name;
                     47:                const uint code = nb.get_hash_code();
                     48:                for(int i = 0; i < fcount; i++) {
                     49:                        const String::Body& key = fpairs[i].key;
                     50:                        if(key.get_hash_code() == code && key == nb) {
                     51:                                fpairs[i].value = value;
                     52:                                return true;
                     53:                        }
                     54:                }
                     55:                if(fcount < PA_HASH_INLINE_SIZE) {
                     56:                        fpairs[fcount].key = name;
                     57:                        fpairs[fcount].value = value;
                     58:                        fcount++;
                     59:                        return false;
                     60:                }
                     61:                if(!foverflow)
                     62:                        foverflow = new HashString<V>();
                     63:                return foverflow->put(name, value);
                     64:        }
                     65: 
                     66:        bool put_replaced(const String& name, V value) {
                     67:                const String::Body& nb = name;
                     68:                const uint code = nb.get_hash_code();
                     69:                for(int i = 0; i < fcount; i++) {
                     70:                        const String::Body& key = fpairs[i].key;
                     71:                        if(key.get_hash_code() == code && key == nb) {
                     72:                                fpairs[i].value = value;
                     73:                                return true;
                     74:                        }
                     75:                }
                     76:                return foverflow ? foverflow->put_replaced(name, value) : false;
                     77:        }
                     78: 
                     79:        int count() const {
                     80:                return fcount + (foverflow ? foverflow->count() : 0);
                     81:        }
                     82: 
                     83:        template<typename I> void for_each(void callback(const String::Body&, V, I), I info) const {
                     84:                for(int i = 0; i < fcount; i++)
                     85:                        callback(fpairs[i].key, fpairs[i].value, info);
                     86:                if(foverflow)
                     87:                        foverflow->for_each(callback, info);
                     88:        }
                     89: 
                     90: private:
                     91:        int fcount;
                     92:        Pair fpairs[PA_HASH_INLINE_SIZE];
                     93:        HashString<V>* foverflow;
                     94: };
                     95: 
                     96: #endif // PA_INLINE_HASH_H

E-mail: