/* AbiSource Program Utilities * * Copyright (C) 2001 Mike Nordell * Copyright (C) 2001 Dom Lachowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #ifndef UT_HASH_H #define UT_HASH_H #include #include "ut_types.h" #include "ut_vector.h" #include "ut_string_class.h" // fwd. decl. class hash_slot; class ABI_EXPORT UT_StringPtrMap { public: UT_StringPtrMap(size_t expected_cardinality = 11); ~UT_StringPtrMap(); // insertion/addition bool insert(const char* key, const void* value); bool insert(const UT_String & key, const void* value); void set (const char* key, const void* val); void set (const UT_String & key, const void* val); // "find" const void* pick(const char* key) const; const void* pick(const UT_String & key) const; // contains - if contains(key) val will be the result of the lookup bool contains(const char* key, const void* val) const; bool contains(const UT_String & key, const void* val) const; // these are for removal void remove(const char* key, const void* /* ignored */); void remove(const UT_String & key, const void* /* ignored */); void clear(); UT_Vector* enumerate() const; UT_Vector* keys() const; // these are synonyms - for getting the # keys inline size_t cardinality() const { return n_keys; } inline size_t size() const { return n_keys; } // Like a std cursor class UT_Cursor { friend class UT_StringPtrMap; public: UT_Cursor(const UT_StringPtrMap * owner) : m_d(owner), m_index(-1) { //m_d._first(this); } ~UT_Cursor() { } // these can't be const since we're passing a non-const this ptr inline const UT_String &key() {return m_d->_key(*this); } inline const void* first() { return m_d->_first(*this); } inline const void* next() { return m_d->_next(*this); } inline const void* prev() { return m_d->_prev(*this); } inline bool is_valid() { return (m_index != -1); } private: inline void _set_index(int i) { m_index = i; } inline int _get_index() { return m_index; } const UT_StringPtrMap* m_d; UT_sint32 m_index; }; friend class UT_Cursor; private: UT_StringPtrMap(const UT_StringPtrMap&); // no impl void operator=(const UT_StringPtrMap&); // no impl enum SM_search_type { SM_INSERT, SM_LOOKUP, SM_REORG }; void reorg(size_t slots_to_allocate); void grow(); void assign_slots(hash_slot* p, size_t old_num_slots); static size_t compute_reorg_threshold(size_t nslots); bool too_full() const { return (n_keys + n_deleted) >= reorg_threshold; } bool too_many_deleted() const { return n_deleted > (reorg_threshold / 4); } bool exceeds_n_delete_threshold() const { return n_deleted > (reorg_threshold / 2); } hash_slot* find_slot(const UT_String& k, SM_search_type search_type, size_t& slot, bool& key_found, size_t& hashval, const void* v, bool* v_found, void* vi, size_t hashval_in) const; // enumeration of the elements const void* _first(UT_Cursor& c) const; const void* _next(UT_Cursor& c) const; const void* _prev(UT_Cursor& c) const; const UT_String& _key(UT_Cursor& c) const; // data hash_slot* m_pMapping; size_t n_keys; size_t n_deleted; size_t m_nSlots; size_t reorg_threshold; size_t flags; }; #define UT_HASH_PURGEDATA(type, hash, reaper) \ do { UT_StringPtrMap::UT_Cursor _hc1(hash); \ for ( type _hval1 = (type) _hc1.first(); _hc1.is_valid(); _hval1 = (type) _hc1.next() ) { \ if (_hval1) \ reaper (_hval1); \ } } while (0); #endif /* UT_HASH_H */