|
|
| version 1.3, 2001/01/27 15:00:04 | version 1.36.2.1, 2001/04/16 11:26:40 |
|---|---|
| Line 1 | Line 1 |
| /* | /** @file |
| $Id$ | Parser: hash class decl. |
| */ | |
| /* | Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | |
| $Id$ | |
| */ | */ |
| #ifndef PA_HASH_H | #ifndef PA_HASH_H |
| Line 12 | Line 13 |
| #include <stddef.h> | #include <stddef.h> |
| #include "pa_pool.h" | |
| #include "pa_types.h" | #include "pa_types.h" |
| #include "pa_string.h" | #include "pa_string.h" |
| class Pool; | |
| class Hash { | /** |
| Pooled hash. | |
| Automatically rehashed when almost full. | |
| */ | |
| class Hash : public Pooled { | |
| public: | public: |
| typedef String Key; | typedef String Key; ///< hash Key type. longing for templates |
| typedef void Value; | typedef void Val; ///< hash Val type. longing for templates |
| /// for_each iterator function type | |
| typedef void (*For_each_func)(const Key& key, Val *value, void *info); | |
| public: | |
| Hash(Pool& apool) : Pooled(apool) { | |
| construct(apool); | |
| } | |
| /// 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); | |
| /* | |
| /// dirty hack to allow constant items storage. I long for Hash<const Val*> | |
| /*SYNCHRONIZED* / bool put(const Key& key, const Val *value) { | |
| return put(key, const_cast<Val *>(value)); | |
| } | |
| */ | |
| /// get associated [value] by the [key] | |
| /*SYNCHRONIZED*/ 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); | |
| /// 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); | |
| /// put all 'src' values if NO with same key existed | |
| /*SYNCHRONIZED*/ void merge_dont_replace(const Hash& src); | |
| void put(const Key& key, int value) { put(key, reinterpret_cast<Val *>(value)); } | |
| void put(const Key& key, const String *value) { | |
| put(key, static_cast<Val *>(const_cast<String *>(value))); | |
| } | |
| //@{ | |
| /// handy get, longing for Hash<int>, Hash<String *> | |
| int get_int(const Key& key) const { return reinterpret_cast<int>(get(key)); } | |
| const String *get_string(const Key& key) const { return static_cast<String *>(get(key)); } | |
| //@} | |
| /// number of elements in hash | |
| int size() const { return used; } | |
| /// iterate over all not zero elements | |
| void for_each(For_each_func func, void *info=0) const; | |
| /// remove all elements | |
| void clear(); | |
| protected: | |
| void construct(Pool& apool); | |
| private: | private: |
| friend Pool; | |
| // expand when used these %% of size | // expand when these %% of allocated exausted |
| enum { | enum { |
| THRESHOLD_PERCENT=75 | THRESHOLD_PERCENT=75 |
| }; | }; |
| // the pool I'm allocated on | // the index of [allocated] in [allocates] |
| Pool *pool; | int allocates_index; |
| // the index of size in sizes | |
| int size_index; | |
| // possible sizes. prime numbers | // possible [allocates]. prime numbers |
| static uint sizes[]; | static uint allocates[]; |
| static int sizes_count; | static int allocates_count; |
| // number of allocated pairs | // number of allocated pairs |
| int size; | int allocated; |
| // helper: expanding when used == threshold | // helper: expanding when used == threshold |
| int threshold; | int threshold; |
| Line 55 private: | Line 113 private: |
| friend Hash; | friend Hash; |
| uint code; | uint code; |
| Key key; | const Key key; |
| Value *value; | Val *value; |
| Pair *link; | Pair *link; |
| void *operator new(size_t size, Pool *apool); | void *operator new(size_t allocated, Pool& apool); |
| Pair(uint acode, Key& akey, Value *avalue, Pair *alink) : | Pair(uint acode, const Key& akey, Val *avalue, Pair *alink) : |
| code(acode), | code(acode), |
| key(akey), | key(akey), |
| value(avalue), | value(avalue), |
| link(alink) {} | link(alink) {} |
| } **refs; | } **refs; |
| // new&constructors made private to enforce factory manufacturing at pool | // filled to threshold: needs expanding |
| void *operator new(size_t size, Pool *apool); | bool full() { return used==threshold; } |
| Hash(Pool *apool); | // allocate larger buffer & rehash |
| bool full() { | |
| return used==threshold; | |
| } | |
| void expand(); | void expand(); |
| public: | private: //disabled |
| static uint generic_code(uint aresult, char *start, uint size); | //Hash(Hash&) {} |
| void put(Key& key, Value *value); | Hash& operator = (const Hash&) { return *this; } |
| Value* get(Key& key); | |
| }; | }; |
| #endif | #endif |