diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h')
-rw-r--r-- | contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h | 796 |
1 files changed, 398 insertions, 398 deletions
diff --git a/contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h b/contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h index 4ce9265b27..c149cd6b7e 100644 --- a/contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h +++ b/contrib/libs/poco/Foundation/include/Poco/SimpleHashTable.h @@ -1,398 +1,398 @@ -// -// SimpleHashTable.h -// -// Library: Foundation -// Package: Hashing -// Module: SimpleHashTable -// -// Definition of the SimpleHashTable class. -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// SPDX-License-Identifier: BSL-1.0 -// - - -#ifndef Foundation_SimpleHashTable_INCLUDED -#define Foundation_SimpleHashTable_INCLUDED - - -#include "Poco/Foundation.h" -#include "Poco/Exception.h" -#include "Poco/HashFunction.h" -#include "Poco/HashStatistic.h" -#include <vector> -#include <map> -#include <cstddef> -#include <algorithm> - - -namespace Poco { - - -//@ deprecated -template <class Key, class Value, class KeyHashFunction = HashFunction<Key> > -class SimpleHashTable - /// A SimpleHashTable stores a key value pair that can be looked up via a hashed key. - /// - /// In comparision to a HashTable, this class handles collisions by sequentially searching the next - /// free location. This also means that the maximum size of this table is limited, i.e. if the hash table - /// is full, it will throw an exception and that this class does not support remove operations. - /// On the plus side it is faster than the HashTable. - /// - /// This class is NOT thread safe. -{ -public: - class HashEntry - { - public: - Key key; - Value value; - HashEntry(const Key k, const Value v): key(k), value(v) - { - } - }; - - typedef std::vector<HashEntry*> HashTableVector; - - SimpleHashTable(UInt32 capacity = 251): _entries(capacity, 0), _size(0), _capacity(capacity) - /// Creates the SimpleHashTable. - { - } - - SimpleHashTable(const SimpleHashTable& ht): - _size(ht._size), - _capacity(ht._capacity) - { - _entries.reserve(ht._capacity); - for (typename HashTableVector::iterator it = ht._entries.begin(); it != ht._entries.end(); ++it) - { - if (*it) - _entries.push_back(new HashEntry(*it)); - else - _entries.push_back(0); - } - } - - ~SimpleHashTable() - /// Destroys the SimpleHashTable. - { - clear(); - } - - SimpleHashTable& operator = (const SimpleHashTable& ht) - { - if (this != &ht) - { - SimpleHashTable tmp(ht); - swap(tmp); - } - return *this; - } - - void swap(SimpleHashTable& ht) - { - using std::swap; - swap(_entries, ht._entries); - swap(_size, ht._size); - swap(_capacity, ht._capacity); - } - - void clear() - { - for (typename HashTableVector::iterator it = _entries.begin(); it != _entries.end(); ++it) - { - delete *it; - *it = 0; - } - _size = 0; - } - - UInt32 insert(const Key& key, const Value& value) - /// Returns the hash value of the inserted item. - /// Throws an exception if the entry was already inserted - { - UInt32 hsh = hash(key); - insertRaw(key, hsh, value); - return hsh; - } - - Value& insertRaw(const Key& key, UInt32 hsh, const Value& value) - /// Returns the hash value of the inserted item. - /// Throws an exception if the entry was already inserted - { - UInt32 pos = hsh; - if (!_entries[pos]) - _entries[pos] = new HashEntry(key, value); - else - { - UInt32 origHash = hsh; - while (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - throw ExistsException(); - if (hsh - origHash > _capacity) - throw PoolOverflowException("SimpleHashTable full"); - hsh++; - } - pos = hsh % _capacity; - _entries[pos] = new HashEntry(key, value); - } - _size++; - return _entries[pos]->value; - } - - UInt32 update(const Key& key, const Value& value) - /// Returns the hash value of the inserted item. - /// Replaces an existing entry if it finds one - { - UInt32 hsh = hash(key); - updateRaw(key, hsh, value); - return hsh; - } - - void updateRaw(const Key& key, UInt32 hsh, const Value& value) - /// Returns the hash value of the inserted item. - /// Replaces an existing entry if it finds one - { - if (!_entries[hsh]) - _entries[hsh] = new HashEntry(key, value); - else - { - UInt32 origHash = hsh; - while (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - _entries[hsh % _capacity]->value = value; - return; - } - if (hsh - origHash > _capacity) - throw PoolOverflowException("SimpleHashTable full"); - hsh++; - } - _entries[hsh % _capacity] = new HashEntry(key, value); - } - _size++; - } - - UInt32 hash(const Key& key) const - { - return _hash(key, _capacity); - } - - const Value& get(const Key& key) const - /// Throws an exception if the value does not exist - { - UInt32 hsh = hash(key); - return getRaw(key, hsh); - } - - const Value& getRaw(const Key& key, UInt32 hsh) const - /// Throws an exception if the value does not exist - { - UInt32 origHash = hsh; - while (true) - { - if (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - return _entries[hsh % _capacity]->value; - } - } - else - throw InvalidArgumentException("value not found"); - if (hsh - origHash > _capacity) - throw InvalidArgumentException("value not found"); - hsh++; - } - } - - Value& get(const Key& key) - /// Throws an exception if the value does not exist - { - UInt32 hsh = hash(key); - return const_cast<Value&>(getRaw(key, hsh)); - } - - const Value& operator [] (const Key& key) const - { - return get(key); - } - - Value& operator [] (const Key& key) - { - UInt32 hsh = hash(key); - UInt32 origHash = hsh; - while (true) - { - if (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - return _entries[hsh % _capacity]->value; - } - } - else return insertRaw(key, hsh, Value()); - if (hsh - origHash > _capacity) - return insertRaw(key, hsh, Value()); - hsh++; - } - } - - const Key& getKeyRaw(const Key& key, UInt32 hsh) - /// Throws an exception if the key does not exist. returns a reference to the internally - /// stored key. Useful when someone does an insert and wants for performance reason only to store - /// a pointer to the key in another collection - { - UInt32 origHash = hsh; - while (true) - { - if (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - return _entries[hsh % _capacity]->key; - } - } - else - throw InvalidArgumentException("key not found"); - - if (hsh - origHash > _capacity) - throw InvalidArgumentException("key not found"); - hsh++; - } - } - - bool get(const Key& key, Value& v) const - /// Sets v to the found value, returns false if no value was found - { - UInt32 hsh = hash(key); - return getRaw(key, hsh, v); - } - - bool getRaw(const Key& key, UInt32 hsh, Value& v) const - /// Sets v to the found value, returns false if no value was found - { - UInt32 origHash = hsh; - while (true) - { - if (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - v = _entries[hsh % _capacity]->value; - return true; - } - } - else - return false; - if (hsh - origHash > _capacity) - return false; - hsh++; - } - } - - bool exists(const Key& key) const - { - UInt32 hsh = hash(key); - return existsRaw(key, hsh); - } - - bool existsRaw(const Key& key, UInt32 hsh) const - { - UInt32 origHash = hsh; - while (true) - { - if (_entries[hsh % _capacity]) - { - if (_entries[hsh % _capacity]->key == key) - { - return true; - } - } - else - return false; - if (hsh - origHash > _capacity) - return false; - hsh++; - } - } - - std::size_t size() const - /// Returns the number of elements already inserted into the SimpleHashTable - { - return _size; - } - - UInt32 capacity() const - { - return _capacity; - } - - void resize(UInt32 newSize) - /// Resizes the hashtable, rehashes all existing entries. Expensive! - { - if (_capacity != newSize) - { - SimpleHashTable tmp(newSize); - swap(tmp); - for (typename HashTableVector::const_iterator it = tmp._entries.begin(); it != tmp._entries.end(); ++it) - { - if (*it) - { - insertRaw((*it)->key, hash((*it)->key), (*it)->value); - } - } - } - } - - HashStatistic currentState(bool details = false) const - /// Returns the current internal state - { - UInt32 numberOfEntries = (UInt32)_size; - UInt32 numZeroEntries = 0; - UInt32 maxEntriesPerHash = 0; - std::vector<UInt32> detailedEntriesPerHash; - #ifdef _DEBUG - UInt32 totalSize = 0; - #endif - for (int i=0; i < _capacity; ++i) - { - if (_entries[i]) - { - maxEntriesPerHash = 1; - UInt32 size = 1; - if (details) - detailedEntriesPerHash.push_back(size); - #ifdef _DEBUG - totalSize += size; - #endif - } - else - { - numZeroEntries++; - if (details) - detailedEntriesPerHash.push_back(0); - } - } - #ifdef _DEBUG - poco_assert_dbg(totalSize == numberOfEntries); - #endif - return HashStatistic(_capacity, numberOfEntries, numZeroEntries, maxEntriesPerHash, detailedEntriesPerHash); - } - -private: - HashTableVector _entries; - std::size_t _size; - UInt32 _capacity; - KeyHashFunction _hash; -}; - - -} // namespace Poco - - -#endif // Foundation_HashTable_INCLUDED +// +// SimpleHashTable.h +// +// Library: Foundation +// Package: Hashing +// Module: SimpleHashTable +// +// Definition of the SimpleHashTable class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef Foundation_SimpleHashTable_INCLUDED +#define Foundation_SimpleHashTable_INCLUDED + + +#include "Poco/Foundation.h" +#include "Poco/Exception.h" +#include "Poco/HashFunction.h" +#include "Poco/HashStatistic.h" +#include <vector> +#include <map> +#include <cstddef> +#include <algorithm> + + +namespace Poco { + + +//@ deprecated +template <class Key, class Value, class KeyHashFunction = HashFunction<Key> > +class SimpleHashTable + /// A SimpleHashTable stores a key value pair that can be looked up via a hashed key. + /// + /// In comparision to a HashTable, this class handles collisions by sequentially searching the next + /// free location. This also means that the maximum size of this table is limited, i.e. if the hash table + /// is full, it will throw an exception and that this class does not support remove operations. + /// On the plus side it is faster than the HashTable. + /// + /// This class is NOT thread safe. +{ +public: + class HashEntry + { + public: + Key key; + Value value; + HashEntry(const Key k, const Value v): key(k), value(v) + { + } + }; + + typedef std::vector<HashEntry*> HashTableVector; + + SimpleHashTable(UInt32 capacity = 251): _entries(capacity, 0), _size(0), _capacity(capacity) + /// Creates the SimpleHashTable. + { + } + + SimpleHashTable(const SimpleHashTable& ht): + _size(ht._size), + _capacity(ht._capacity) + { + _entries.reserve(ht._capacity); + for (typename HashTableVector::iterator it = ht._entries.begin(); it != ht._entries.end(); ++it) + { + if (*it) + _entries.push_back(new HashEntry(*it)); + else + _entries.push_back(0); + } + } + + ~SimpleHashTable() + /// Destroys the SimpleHashTable. + { + clear(); + } + + SimpleHashTable& operator = (const SimpleHashTable& ht) + { + if (this != &ht) + { + SimpleHashTable tmp(ht); + swap(tmp); + } + return *this; + } + + void swap(SimpleHashTable& ht) + { + using std::swap; + swap(_entries, ht._entries); + swap(_size, ht._size); + swap(_capacity, ht._capacity); + } + + void clear() + { + for (typename HashTableVector::iterator it = _entries.begin(); it != _entries.end(); ++it) + { + delete *it; + *it = 0; + } + _size = 0; + } + + UInt32 insert(const Key& key, const Value& value) + /// Returns the hash value of the inserted item. + /// Throws an exception if the entry was already inserted + { + UInt32 hsh = hash(key); + insertRaw(key, hsh, value); + return hsh; + } + + Value& insertRaw(const Key& key, UInt32 hsh, const Value& value) + /// Returns the hash value of the inserted item. + /// Throws an exception if the entry was already inserted + { + UInt32 pos = hsh; + if (!_entries[pos]) + _entries[pos] = new HashEntry(key, value); + else + { + UInt32 origHash = hsh; + while (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + throw ExistsException(); + if (hsh - origHash > _capacity) + throw PoolOverflowException("SimpleHashTable full"); + hsh++; + } + pos = hsh % _capacity; + _entries[pos] = new HashEntry(key, value); + } + _size++; + return _entries[pos]->value; + } + + UInt32 update(const Key& key, const Value& value) + /// Returns the hash value of the inserted item. + /// Replaces an existing entry if it finds one + { + UInt32 hsh = hash(key); + updateRaw(key, hsh, value); + return hsh; + } + + void updateRaw(const Key& key, UInt32 hsh, const Value& value) + /// Returns the hash value of the inserted item. + /// Replaces an existing entry if it finds one + { + if (!_entries[hsh]) + _entries[hsh] = new HashEntry(key, value); + else + { + UInt32 origHash = hsh; + while (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + _entries[hsh % _capacity]->value = value; + return; + } + if (hsh - origHash > _capacity) + throw PoolOverflowException("SimpleHashTable full"); + hsh++; + } + _entries[hsh % _capacity] = new HashEntry(key, value); + } + _size++; + } + + UInt32 hash(const Key& key) const + { + return _hash(key, _capacity); + } + + const Value& get(const Key& key) const + /// Throws an exception if the value does not exist + { + UInt32 hsh = hash(key); + return getRaw(key, hsh); + } + + const Value& getRaw(const Key& key, UInt32 hsh) const + /// Throws an exception if the value does not exist + { + UInt32 origHash = hsh; + while (true) + { + if (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + return _entries[hsh % _capacity]->value; + } + } + else + throw InvalidArgumentException("value not found"); + if (hsh - origHash > _capacity) + throw InvalidArgumentException("value not found"); + hsh++; + } + } + + Value& get(const Key& key) + /// Throws an exception if the value does not exist + { + UInt32 hsh = hash(key); + return const_cast<Value&>(getRaw(key, hsh)); + } + + const Value& operator [] (const Key& key) const + { + return get(key); + } + + Value& operator [] (const Key& key) + { + UInt32 hsh = hash(key); + UInt32 origHash = hsh; + while (true) + { + if (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + return _entries[hsh % _capacity]->value; + } + } + else return insertRaw(key, hsh, Value()); + if (hsh - origHash > _capacity) + return insertRaw(key, hsh, Value()); + hsh++; + } + } + + const Key& getKeyRaw(const Key& key, UInt32 hsh) + /// Throws an exception if the key does not exist. returns a reference to the internally + /// stored key. Useful when someone does an insert and wants for performance reason only to store + /// a pointer to the key in another collection + { + UInt32 origHash = hsh; + while (true) + { + if (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + return _entries[hsh % _capacity]->key; + } + } + else + throw InvalidArgumentException("key not found"); + + if (hsh - origHash > _capacity) + throw InvalidArgumentException("key not found"); + hsh++; + } + } + + bool get(const Key& key, Value& v) const + /// Sets v to the found value, returns false if no value was found + { + UInt32 hsh = hash(key); + return getRaw(key, hsh, v); + } + + bool getRaw(const Key& key, UInt32 hsh, Value& v) const + /// Sets v to the found value, returns false if no value was found + { + UInt32 origHash = hsh; + while (true) + { + if (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + v = _entries[hsh % _capacity]->value; + return true; + } + } + else + return false; + if (hsh - origHash > _capacity) + return false; + hsh++; + } + } + + bool exists(const Key& key) const + { + UInt32 hsh = hash(key); + return existsRaw(key, hsh); + } + + bool existsRaw(const Key& key, UInt32 hsh) const + { + UInt32 origHash = hsh; + while (true) + { + if (_entries[hsh % _capacity]) + { + if (_entries[hsh % _capacity]->key == key) + { + return true; + } + } + else + return false; + if (hsh - origHash > _capacity) + return false; + hsh++; + } + } + + std::size_t size() const + /// Returns the number of elements already inserted into the SimpleHashTable + { + return _size; + } + + UInt32 capacity() const + { + return _capacity; + } + + void resize(UInt32 newSize) + /// Resizes the hashtable, rehashes all existing entries. Expensive! + { + if (_capacity != newSize) + { + SimpleHashTable tmp(newSize); + swap(tmp); + for (typename HashTableVector::const_iterator it = tmp._entries.begin(); it != tmp._entries.end(); ++it) + { + if (*it) + { + insertRaw((*it)->key, hash((*it)->key), (*it)->value); + } + } + } + } + + HashStatistic currentState(bool details = false) const + /// Returns the current internal state + { + UInt32 numberOfEntries = (UInt32)_size; + UInt32 numZeroEntries = 0; + UInt32 maxEntriesPerHash = 0; + std::vector<UInt32> detailedEntriesPerHash; + #ifdef _DEBUG + UInt32 totalSize = 0; + #endif + for (int i=0; i < _capacity; ++i) + { + if (_entries[i]) + { + maxEntriesPerHash = 1; + UInt32 size = 1; + if (details) + detailedEntriesPerHash.push_back(size); + #ifdef _DEBUG + totalSize += size; + #endif + } + else + { + numZeroEntries++; + if (details) + detailedEntriesPerHash.push_back(0); + } + } + #ifdef _DEBUG + poco_assert_dbg(totalSize == numberOfEntries); + #endif + return HashStatistic(_capacity, numberOfEntries, numZeroEntries, maxEntriesPerHash, detailedEntriesPerHash); + } + +private: + HashTableVector _entries; + std::size_t _size; + UInt32 _capacity; + KeyHashFunction _hash; +}; + + +} // namespace Poco + + +#endif // Foundation_HashTable_INCLUDED |