--- parser3/src/include/pa_hash.h 2001/03/28 08:01:41 1.32 +++ parser3/src/include/pa_hash.h 2001/11/01 15:45:27 1.49 @@ -5,26 +5,21 @@ Author: Alexander Petrosyan (http://design.ru/paf) - $Id: pa_hash.h,v 1.32 2001/03/28 08:01:41 paf Exp $ + $Id: pa_hash.h,v 1.49 2001/11/01 15:45:27 paf Exp $ */ #ifndef PA_HASH_H #define PA_HASH_H -#include - +#include "pa_config_includes.h" #include "pa_pool.h" #include "pa_types.h" #include "pa_string.h" - /** Pooled hash. Automatically rehashed when almost full. - - The only object that can be thread safe, wich is specified in constructor, - default 'not safe'. */ class Hash : public Pooled { public: @@ -35,32 +30,52 @@ public: /// for_each iterator function type typedef void (*For_each_func)(const Key& key, Val *value, void *info); + /// for_each iterator function type + typedef void (*For_each_func_refed)(const Key& key, Val *& value, void *info); + + /// first_that iterator function type + typedef void *(*First_that_func)(const Key& key, Val *value, void *info); + public: - Hash(Pool& apool,bool athread_safe=false) : Pooled(apool) { - construct(apool, athread_safe); + Hash(Pool& apool) : Pooled(apool) { + construct_new(); + } + + Hash(const Hash& source) : Pooled(source.pool()){ + construct_copy(source); } /// useful generic hash function static uint generic_code(uint aresult, const char *start, uint allocated); /// put a [value] under the [key], return existed or not - /*SYNCHRONIZED*/ bool put(const Key& key, Val *value); + bool put(const Key& key, Val *value); + /// remove the [key] + void remove(const Key& key); +/* + /// dirty hack to allow constant items storage. I long for Hash + bool put(const Key& key, const Val *value) { + return put(key, const_cast(value)); + } +*/ /// get associated [value] by the [key] - /*SYNCHRONIZED*/ Val *get(const Key& key) const; + Val *get(const Key& key) const; /// put a [value] under the [key] if that [key] existed, return existed or not - /*SYNCHRONIZED*/ bool put_replace(const Key& key, Val *value); + bool put_replace(const Key& key, Val *value); /// put a [value] under the [key] if that [key] NOT existed, return existed or not - /*SYNCHRONIZED*/ bool put_dont_replace(const Key& key, Val *value); + bool put_dont_replace(const Key& key, Val *value); /// put all 'src' values if NO with same key existed - /*SYNCHRONIZED*/ void merge_dont_replace(const Hash& src); + void merge_dont_replace(const Hash& src); void put(const Key& key, int value) { put(key, reinterpret_cast(value)); } - void put(const Key& key, String *value) { put(key, static_cast(value)); } + void put(const Key& key, const String *value) { + put(key, static_cast(const_cast(value))); + } //@{ /// handy get, longing for Hash, Hash @@ -69,50 +84,57 @@ public: //@} /// number of elements in hash - int size() { return used; } + int size() const { return count; } /// iterate over all not zero elements - void for_each(For_each_func func, void *info=0); + void for_each(For_each_func func, void *info=0) const; + + /// iterate over all not zero elements, passing references + void for_each(For_each_func_refed func, void *info=0) const; + + /// iterate over all elements until condition + void *first_that(First_that_func func, void *info=0) const; /// remove all elements void clear(); protected: - void construct(Pool& apool, bool athread_safe); + void construct_new(); + void construct_copy(const Hash& source); private: - // expand when these %% of allocated exausted + /// expand when these %% of allocated exausted enum { THRESHOLD_PERCENT=75 }; - // am I thread-safe? - bool thread_safe; - - // the index of [allocated] in [allocates] + /// the index of [allocated] in [allocates] int allocates_index; - // possible [allocates]. prime numbers + /// possible [allocates]. prime numbers static uint allocates[]; static int allocates_count; - // number of allocated pairs + /// number of allocated pairs int allocated; - // helper: expanding when used == threshold + /// helper: expanding when used == threshold int threshold; - // used pairs + /// used pairs int used; - // main storage + /// stored pairs total (including those by links) + int count; + + /// pair storage class Pair { - friend Hash; + friend class Hash; uint code; - const Key key; + const Key& key; Val *value; Pair *link; @@ -125,16 +147,16 @@ private: link(alink) {} } **refs; - // filled to threshold: needs expanding + /// filled to threshold: needs expanding bool full() { return used==threshold; } - // allocate larger buffer & rehash + /// allocate larger buffer & rehash void expand(); private: //disabled - //Hash(Hash&) {} Hash& operator = (const Hash&) { return *this; } }; + #endif