mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Renamed CHashTableT to HashTable and corrected code style
parent
0e13a7d124
commit
0200bc3720
|
@ -12,97 +12,95 @@
|
||||||
|
|
||||||
#include "../core/math_func.hpp"
|
#include "../core/math_func.hpp"
|
||||||
|
|
||||||
template <class Titem_>
|
template <class TItem>
|
||||||
struct CHashTableSlotT
|
struct HashTableSlot
|
||||||
{
|
{
|
||||||
typedef typename Titem_::Key Key; // make Titem_::Key a property of HashTable
|
typedef typename TItem::Key Key; // make Titem::Key a property of HashTable
|
||||||
|
|
||||||
Titem_ *m_pFirst;
|
TItem *first_item = nullptr;
|
||||||
|
|
||||||
inline CHashTableSlotT() : m_pFirst(nullptr) {}
|
|
||||||
|
|
||||||
/** hash table slot helper - clears the slot by simple forgetting its items */
|
/** hash table slot helper - clears the slot by simple forgetting its items */
|
||||||
inline void Clear()
|
inline void Clear()
|
||||||
{
|
{
|
||||||
m_pFirst = nullptr;
|
this->first_item = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash table slot helper - linear search for item with given key through the given blob - const version */
|
/** hash table slot helper - linear search for item with given key through the given blob - const version */
|
||||||
inline const Titem_ *Find(const Key &key) const
|
inline const TItem *Find(const Key &key) const
|
||||||
{
|
{
|
||||||
for (const Titem_ *pItem = m_pFirst; pItem != nullptr; pItem = pItem->GetHashNext()) {
|
for (const TItem *item = this->first_item; item != nullptr; item = item->GetHashNext()) {
|
||||||
if (pItem->GetKey() == key) {
|
if (item->GetKey() == key) {
|
||||||
/* we have found the item, return it */
|
/* we have found the item, return it */
|
||||||
return pItem;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash table slot helper - linear search for item with given key through the given blob - non-const version */
|
/** hash table slot helper - linear search for item with given key through the given blob - non-const version */
|
||||||
inline Titem_ *Find(const Key &key)
|
inline TItem *Find(const Key &key)
|
||||||
{
|
{
|
||||||
for (Titem_ *pItem = m_pFirst; pItem != nullptr; pItem = pItem->GetHashNext()) {
|
for (TItem *item = this->first_item; item != nullptr; item = item->GetHashNext()) {
|
||||||
if (pItem->GetKey() == key) {
|
if (item->GetKey() == key) {
|
||||||
/* we have found the item, return it */
|
/* we have found the item, return it */
|
||||||
return pItem;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash table slot helper - add new item to the slot */
|
/** hash table slot helper - add new item to the slot */
|
||||||
inline void Attach(Titem_ &new_item)
|
inline void Attach(TItem &new_item)
|
||||||
{
|
{
|
||||||
assert(new_item.GetHashNext() == nullptr);
|
assert(new_item.GetHashNext() == nullptr);
|
||||||
new_item.SetHashNext(m_pFirst);
|
new_item.SetHashNext(this->first_item);
|
||||||
m_pFirst = &new_item;
|
this->first_item = &new_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash table slot helper - remove item from a slot */
|
/** hash table slot helper - remove item from a slot */
|
||||||
inline bool Detach(Titem_ &item_to_remove)
|
inline bool Detach(TItem &item_to_remove)
|
||||||
{
|
{
|
||||||
if (m_pFirst == &item_to_remove) {
|
if (this->first_item == &item_to_remove) {
|
||||||
m_pFirst = item_to_remove.GetHashNext();
|
this->first_item = item_to_remove.GetHashNext();
|
||||||
item_to_remove.SetHashNext(nullptr);
|
item_to_remove.SetHashNext(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Titem_ *pItem = m_pFirst;
|
TItem *item = this->first_item;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (pItem == nullptr) {
|
if (item == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Titem_ *pNextItem = pItem->GetHashNext();
|
TItem *next_item = item->GetHashNext();
|
||||||
if (pNextItem == &item_to_remove) break;
|
if (next_item == &item_to_remove) break;
|
||||||
pItem = pNextItem;
|
item = next_item;
|
||||||
}
|
}
|
||||||
pItem->SetHashNext(item_to_remove.GetHashNext());
|
item->SetHashNext(item_to_remove.GetHashNext());
|
||||||
item_to_remove.SetHashNext(nullptr);
|
item_to_remove.SetHashNext(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash table slot helper - remove and return item from a slot */
|
/** hash table slot helper - remove and return item from a slot */
|
||||||
inline Titem_ *Detach(const Key &key)
|
inline TItem *Detach(const Key &key)
|
||||||
{
|
{
|
||||||
/* do we have any items? */
|
/* do we have any items? */
|
||||||
if (m_pFirst == nullptr) {
|
if (this->first_item == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/* is it our first item? */
|
/* is it our first item? */
|
||||||
if (m_pFirst->GetKey() == key) {
|
if (this->first_item->GetKey() == key) {
|
||||||
Titem_ &ret_item = *m_pFirst;
|
TItem &ret_item = *this->first_item;
|
||||||
m_pFirst = m_pFirst->GetHashNext();
|
this->first_item = this->first_item->GetHashNext();
|
||||||
ret_item.SetHashNext(nullptr);
|
ret_item.SetHashNext(nullptr);
|
||||||
return &ret_item;
|
return &ret_item;
|
||||||
}
|
}
|
||||||
/* find it in the following items */
|
/* find it in the following items */
|
||||||
Titem_ *pPrev = m_pFirst;
|
TItem *previous_item = this->first_item;
|
||||||
for (Titem_ *pItem = m_pFirst->GetHashNext(); pItem != nullptr; pPrev = pItem, pItem = pItem->GetHashNext()) {
|
for (TItem *item = this->first_item->GetHashNext(); item != nullptr; previous_item = item, item = item->GetHashNext()) {
|
||||||
if (pItem->GetKey() == key) {
|
if (item->GetKey() == key) {
|
||||||
/* we have found the item, unlink and return it */
|
/* we have found the item, unlink and return it */
|
||||||
pPrev->SetHashNext(pItem->GetHashNext());
|
previous_item->SetHashNext(item->GetHashNext());
|
||||||
pItem->SetHashNext(nullptr);
|
item->SetHashNext(nullptr);
|
||||||
return pItem;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -110,12 +108,12 @@ struct CHashTableSlotT
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class CHashTableT<Titem, Thash_bits> - simple hash table
|
* class HashTable<Titem, HASH_BITS> - simple hash table
|
||||||
* of pointers allocated elsewhere.
|
* of pointers allocated elsewhere.
|
||||||
*
|
*
|
||||||
* Supports: Add/Find/Remove of Titems.
|
* Supports: Add/Find/Remove of Titems.
|
||||||
*
|
*
|
||||||
* Your Titem must meet some extra requirements to be CHashTableT
|
* Your Titem must meet some extra requirements to be HashTable
|
||||||
* compliant:
|
* compliant:
|
||||||
* - its constructor/destructor (if any) must be public
|
* - its constructor/destructor (if any) must be public
|
||||||
* - if the copying of item requires an extra resource management,
|
* - if the copying of item requires an extra resource management,
|
||||||
|
@ -131,43 +129,35 @@ struct CHashTableSlotT
|
||||||
* - public 'equality' operator to compare the key with another one
|
* - public 'equality' operator to compare the key with another one
|
||||||
* bool operator==(const Key &other) const;
|
* bool operator==(const Key &other) const;
|
||||||
*/
|
*/
|
||||||
template <class Titem_, int Thash_bits_>
|
template <class Titem, int Thash_bits_>
|
||||||
class CHashTableT {
|
class HashTable {
|
||||||
public:
|
public:
|
||||||
typedef Titem_ Titem; // make Titem_ visible from outside of class
|
typedef typename Titem::Key Tkey; // make Titem::Key a property of HashTable
|
||||||
typedef typename Titem_::Key Tkey; // make Titem_::Key a property of HashTable
|
static constexpr int HASH_BITS = Thash_bits_; // publish num of hash bits
|
||||||
static const int Thash_bits = Thash_bits_; // publish num of hash bits
|
static constexpr int CAPACITY = 1 << HASH_BITS; // and num of slots 2^bits
|
||||||
static const int Tcapacity = 1 << Thash_bits; // and num of slots 2^bits
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* each slot contains pointer to the first item in the list,
|
* each slot contains pointer to the first item in the list,
|
||||||
* Titem contains pointer to the next item - GetHashNext(), SetHashNext()
|
* Titem contains pointer to the next item - GetHashNext(), SetHashNext()
|
||||||
*/
|
*/
|
||||||
typedef CHashTableSlotT<Titem_> Slot;
|
typedef HashTableSlot<Titem> Slot;
|
||||||
|
|
||||||
Slot m_slots[Tcapacity]; // here we store our data (array of blobs)
|
Slot slots[CAPACITY]; // here we store our data (array of blobs)
|
||||||
int m_num_items; // item counter
|
int number_of_items = 0; // item counter
|
||||||
|
|
||||||
public:
|
|
||||||
/* default constructor */
|
|
||||||
inline CHashTableT() : m_num_items(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** static helper - return hash for the given key modulo number of slots */
|
/** static helper - return hash for the given key modulo number of slots */
|
||||||
inline static int CalcHash(const Tkey &key)
|
inline static int CalcHash(const Tkey &key)
|
||||||
{
|
{
|
||||||
uint32_t hash = key.CalcHash();
|
uint32_t hash = key.CalcHash();
|
||||||
hash -= (hash >> 17); // hash * 131071 / 131072
|
hash -= (hash >> 17); // hash * 131071 / 131072
|
||||||
hash -= (hash >> 5); // * 31 / 32
|
hash -= (hash >> 5); // * 31 / 32
|
||||||
hash &= (1 << Thash_bits) - 1; // modulo slots
|
hash &= (1 << HASH_BITS) - 1; // modulo slots
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** static helper - return hash for the given item modulo number of slots */
|
/** static helper - return hash for the given item modulo number of slots */
|
||||||
inline static int CalcHash(const Titem_ &item)
|
inline static int CalcHash(const Titem &item)
|
||||||
{
|
{
|
||||||
return CalcHash(item.GetKey());
|
return CalcHash(item.GetKey());
|
||||||
}
|
}
|
||||||
|
@ -176,82 +166,82 @@ public:
|
||||||
/** item count */
|
/** item count */
|
||||||
inline int Count() const
|
inline int Count() const
|
||||||
{
|
{
|
||||||
return m_num_items;
|
return this->number_of_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** simple clear - forget all items - used by CSegmentCostCacheT.Flush() */
|
/** simple clear - forget all items - used by CSegmentCostCacheT.Flush() */
|
||||||
inline void Clear()
|
inline void Clear()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Tcapacity; i++) m_slots[i].Clear();
|
for (int i = 0; i < CAPACITY; i++) this->slots[i].Clear();
|
||||||
this->m_num_items = 0;
|
this->number_of_items = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** const item search */
|
/** const item search */
|
||||||
const Titem_ *Find(const Tkey &key) const
|
const Titem *Find(const Tkey &key) const
|
||||||
{
|
{
|
||||||
int hash = CalcHash(key);
|
int hash = CalcHash(key);
|
||||||
const Slot &slot = m_slots[hash];
|
const Slot &slot = this->slots[hash];
|
||||||
const Titem_ *item = slot.Find(key);
|
const Titem *item = slot.Find(key);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** non-const item search */
|
/** non-const item search */
|
||||||
Titem_ *Find(const Tkey &key)
|
Titem *Find(const Tkey &key)
|
||||||
{
|
{
|
||||||
int hash = CalcHash(key);
|
int hash = CalcHash(key);
|
||||||
Slot &slot = m_slots[hash];
|
Slot &slot = this->slots[hash];
|
||||||
Titem_ *item = slot.Find(key);
|
Titem *item = slot.Find(key);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** non-const item search & optional removal (if found) */
|
/** non-const item search & optional removal (if found) */
|
||||||
Titem_ *TryPop(const Tkey &key)
|
Titem *TryPop(const Tkey &key)
|
||||||
{
|
{
|
||||||
int hash = CalcHash(key);
|
int hash = CalcHash(key);
|
||||||
Slot &slot = m_slots[hash];
|
Slot &slot = this->slots[hash];
|
||||||
Titem_ *item = slot.Detach(key);
|
Titem *item = slot.Detach(key);
|
||||||
if (item != nullptr) {
|
if (item != nullptr) {
|
||||||
m_num_items--;
|
this->number_of_items--;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** non-const item search & removal */
|
/** non-const item search & removal */
|
||||||
Titem_ &Pop(const Tkey &key)
|
Titem &Pop(const Tkey &key)
|
||||||
{
|
{
|
||||||
Titem_ *item = TryPop(key);
|
Titem *item = TryPop(key);
|
||||||
assert(item != nullptr);
|
assert(item != nullptr);
|
||||||
return *item;
|
return *item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** non-const item search & optional removal (if found) */
|
/** non-const item search & optional removal (if found) */
|
||||||
bool TryPop(Titem_ &item)
|
bool TryPop(Titem &item)
|
||||||
{
|
{
|
||||||
const Tkey &key = item.GetKey();
|
const Tkey &key = item.GetKey();
|
||||||
int hash = CalcHash(key);
|
int hash = CalcHash(key);
|
||||||
Slot &slot = m_slots[hash];
|
Slot &slot = this->slots[hash];
|
||||||
bool ret = slot.Detach(item);
|
bool ret = slot.Detach(item);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
m_num_items--;
|
this->number_of_items--;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** non-const item search & removal */
|
/** non-const item search & removal */
|
||||||
void Pop(Titem_ &item)
|
void Pop(Titem &item)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool ret = TryPop(item);
|
[[maybe_unused]] bool ret = TryPop(item);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add one item - copy it from the given item */
|
/** add one item - copy it from the given item */
|
||||||
void Push(Titem_ &new_item)
|
void Push(Titem &new_item)
|
||||||
{
|
{
|
||||||
int hash = CalcHash(new_item);
|
int hash = CalcHash(new_item);
|
||||||
Slot &slot = m_slots[hash];
|
Slot &slot = this->slots[hash];
|
||||||
assert(slot.Find(new_item.GetKey()) == nullptr);
|
assert(slot.Find(new_item.GetKey()) == nullptr);
|
||||||
slot.Attach(new_item);
|
slot.Attach(new_item);
|
||||||
m_num_items++;
|
this->number_of_items++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ public:
|
||||||
typedef Titem_ Titem; ///< Make #Titem_ visible from outside of class.
|
typedef Titem_ Titem; ///< Make #Titem_ visible from outside of class.
|
||||||
typedef typename Titem_::Key Key; ///< Make Titem_::Key a property of this class.
|
typedef typename Titem_::Key Key; ///< Make Titem_::Key a property of this class.
|
||||||
using CItemArray = std::deque<Titem_>; ///< Type that we will use as item container.
|
using CItemArray = std::deque<Titem_>; ///< Type that we will use as item container.
|
||||||
typedef CHashTableT<Titem_, Thash_bits_open_ > COpenList; ///< How pointers to open nodes will be stored.
|
typedef HashTable<Titem_, Thash_bits_open_ > COpenList; ///< How pointers to open nodes will be stored.
|
||||||
typedef CHashTableT<Titem_, Thash_bits_closed_> CClosedList; ///< How pointers to closed nodes will be stored.
|
typedef HashTable<Titem_, Thash_bits_closed_> CClosedList; ///< How pointers to closed nodes will be stored.
|
||||||
typedef CBinaryHeapT<Titem_> CPriorityQueue; ///< How the priority queue will be managed.
|
typedef CBinaryHeapT<Titem_> CPriorityQueue; ///< How the priority queue will be managed.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -67,14 +67,12 @@ struct CSegmentCostCacheBase
|
||||||
*/
|
*/
|
||||||
template <class Tsegment>
|
template <class Tsegment>
|
||||||
struct CSegmentCostCacheT : public CSegmentCostCacheBase {
|
struct CSegmentCostCacheT : public CSegmentCostCacheBase {
|
||||||
static const int C_HASH_BITS = 14;
|
static constexpr int HASH_BITS = 14;
|
||||||
|
|
||||||
typedef CHashTableT<Tsegment, C_HASH_BITS> HashTable;
|
using Key = typename Tsegment::Key; ///< key to hash table
|
||||||
using Heap = std::deque<Tsegment>;
|
|
||||||
typedef typename Tsegment::Key Key; ///< key to hash table
|
|
||||||
|
|
||||||
HashTable map;
|
HashTable<Tsegment, HASH_BITS> map;
|
||||||
Heap heap;
|
std::deque<Tsegment> heap;
|
||||||
|
|
||||||
inline CSegmentCostCacheT() {}
|
inline CSegmentCostCacheT() {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue