Aging_MouthReplace / dlibs /dlib /hash_table /hash_table_kernel_2.h
AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
// Copyright (C) 2003 Davis E. King ([email protected])
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_HASH_TABLE_KERNEl_2_
#define DLIB_HASH_TABLE_KERNEl_2_
#include "hash_table_kernel_abstract.h"
#include "../general_hash/general_hash.h"
#include "../algs.h"
#include "../interfaces/map_pair.h"
#include "../interfaces/enumerable.h"
#include "../interfaces/remover.h"
#include "../assert.h"
#include "../serialize.h"
#include <functional>
namespace dlib
{
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager = default_memory_manager,
typename compare = std::less<domain>
>
class hash_table_kernel_2 : public enumerable<map_pair<domain,range> >,
public pair_remover<domain,range>
{
/*!
REQUIREMENTS ON bst_base
bst_base is instantiated with domain and range and
implements binray_search_tree/binary_search_tree_kernel_abstract.h
INITIAL VALUE
hash_size == 0
table == pointer to an array of num_of_buckets bst_base objects
num_of_buckets == the number of buckets in the hash table
current_bucket == 0
at_start_ == true
CONVENTION
current_element_valid() == (current_bucket != 0)
element() == current_bucket->element()
at_start_ == at_start()
mask == num_of_buckets-1
for all integers i where &table[i] != current_bucket
table[i].at_start() == true
hash_size = size() == the number of elements in the hash_table and
table == pointer to an array of num_of_buckets bst_base objects
num_of_buckets == the number of buckets in the hash table and
the elements in this hash table are stored in the bst_base objects in the
array table
!*/
public:
typedef domain domain_type;
typedef range range_type;
typedef compare compare_type;
typedef mem_manager mem_manager_type;
explicit hash_table_kernel_2(
unsigned long expnum
);
virtual ~hash_table_kernel_2(
)
{ pool.deallocate_array(table); }
void clear(
);
unsigned long count (
const domain& item
) const;
inline void add (
domain& d,
range& r
);
void destroy (
const domain& d
);
void remove (
const domain& d,
domain& d_copy,
range& r
);
const range* operator[] (
const domain& item
) const;
range* operator[] (
const domain& item
);
inline void swap (
hash_table_kernel_2& item
);
// functions from the remover interface
void remove_any (
domain& d,
range& r
);
// functions from the enumerable interface
inline size_t size (
) const;
inline bool at_start (
) const;
inline void reset (
) const;
bool current_element_valid (
) const;
inline const map_pair<domain,range>& element (
) const;
inline map_pair<domain,range>& element (
);
bool move_next (
) const;
private:
// data members
typename mem_manager::template rebind<bst_base>::other pool;
unsigned long mask;
unsigned long hash_size;
unsigned long num_of_buckets;
bst_base* table;
general_hash<domain> hash;
mutable bst_base* current_bucket;
mutable bool at_start_;
compare comp;
// restricted functions
hash_table_kernel_2(hash_table_kernel_2&);
hash_table_kernel_2& operator=(hash_table_kernel_2&);
};
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
inline void swap (
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& a,
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& b
) { a.swap(b); }
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void deserialize (
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& item,
std::istream& in
)
{
try
{
item.clear();
unsigned long size;
deserialize(size,in);
domain d;
range r;
for (unsigned long i = 0; i < size; ++i)
{
deserialize(d,in);
deserialize(r,in);
item.add(d,r);
}
}
catch (serialization_error& e)
{
item.clear();
throw serialization_error(e.info + "\n while deserializing object of type hash_table_kernel_2");
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
hash_table_kernel_2(
unsigned long expnum
) :
hash_size(0),
current_bucket(0),
at_start_(true)
{
num_of_buckets = 1;
while (expnum != 0)
{
--expnum;
num_of_buckets <<= 1;
}
mask = num_of_buckets-1;
table = pool.allocate_array(num_of_buckets);
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
clear(
)
{
if (hash_size != 0)
{
hash_size = 0;
for (unsigned long i = 0; i < num_of_buckets; ++i)
table[i].clear();
}
// reset the enumerator
reset();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
size_t hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
size(
) const
{
return hash_size;
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
unsigned long hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
count(
const domain& item
) const
{
return table[hash(item)&mask].count(item);
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
destroy(
const domain& item
)
{
table[hash(item)&mask].destroy(item);
--hash_size;
// reset the enumerator
reset();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
add(
domain& d,
range& r
)
{
table[hash(d)&mask].add(d,r);
++hash_size;
// reset the enumerator
reset();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
remove(
const domain& d,
domain& d_copy,
range& r
)
{
table[hash(d)&mask].remove(d,d_copy,r);
--hash_size;
// reset the enumerator
reset();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
remove_any(
domain& d,
range& r
)
{
unsigned long i = 0;
while (table[i].size() == 0)
{
++i;
}
table[i].remove_any(d,r);
--hash_size;
// reset the enumerator
reset();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
const range* hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
operator[](
const domain& d
) const
{
return table[hash(d)&mask][d];
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
range* hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
operator[](
const domain& d
)
{
return table[hash(d)&mask][d];
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
swap(
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& item
)
{
pool.swap(item.pool);
exchange(mask,item.mask);
exchange(hash_size,item.hash_size);
exchange(num_of_buckets,item.num_of_buckets);
exchange(table,item.table);
exchange(current_bucket,item.current_bucket);
exchange(at_start_,item.at_start_);
exchange(comp,item.comp);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// enumerable function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
at_start (
) const
{
return at_start_;
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
reset (
) const
{
at_start_ = true;
if (current_bucket != 0)
{
current_bucket->reset();
current_bucket = 0;
}
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
current_element_valid (
) const
{
return (current_bucket != 0);
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
const map_pair<domain,range>& hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
element (
) const
{
return current_bucket->element();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
map_pair<domain,range>& hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
element (
)
{
return current_bucket->element();
}
// ----------------------------------------------------------------------------------------
template <
typename domain,
typename range,
typename bst_base,
typename mem_manager,
typename compare
>
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
move_next (
) const
{
if (at_start_)
{
at_start_ = false;
// if the queue is empty then there is nothing to do
if (hash_size == 0)
{
return false;
}
else
{
// find the first element in the hash table
current_bucket = table;
while (current_bucket->size() == 0)
{
++current_bucket;
}
current_bucket->move_next();
return true;
}
}
else
{
// if we have already enumerated every element
if (current_bucket == 0)
{
return false;
}
else
{
if (current_bucket->move_next())
{
// if there is another element in this current bucket then use that
return true;
}
else
{
// find the next bucket
bst_base* end = table + num_of_buckets;
current_bucket->reset();
while (true)
{
++current_bucket;
// if we ran out of buckets and didn't find anything
if (current_bucket == end)
{
current_bucket = 0;
return false;
}
if (current_bucket->size() > 0)
{
current_bucket->move_next();
return true;
}
}
}
}
}
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_HASH_TABLE_KERNEl_2_