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

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

E-mail: