Sets - Index-backed implementation
This commit is contained in:
parent
752b4977e6
commit
17810a58bf
2 changed files with 143 additions and 2 deletions
133
Sets-inline.hh
133
Sets-inline.hh
|
@ -212,6 +212,139 @@ M_TMPL_ void M_TYPE_::clear( ) noexcept
|
||||||
#undef M_TYPE_
|
#undef M_TYPE_
|
||||||
|
|
||||||
|
|
||||||
|
/*= SET IMPLEMENTATION - INDEX ===============================================*/
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename Type ,
|
||||||
|
uint32_t InitialSize ,
|
||||||
|
uint32_t HashSize ,
|
||||||
|
uint32_t Growth
|
||||||
|
> class T_SetImplementation< Type , IndexBacked< InitialSize , HashSize , Growth > >
|
||||||
|
{
|
||||||
|
static_assert( InitialSize > 0 , "invalid initial size" );
|
||||||
|
static_assert( HashSize > 0 , "invalid hash array size" );
|
||||||
|
static_assert( Growth > 0 , "invalid growth" );
|
||||||
|
|
||||||
|
private:
|
||||||
|
T_HashIndex index_{ HashSize , InitialSize , Growth };
|
||||||
|
T_Array< Type > items_{ Growth };
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t size( ) const noexcept;
|
||||||
|
int32_t indexOf( Type const& item ) const noexcept;
|
||||||
|
Type const* access( uint32_t item ) const noexcept;
|
||||||
|
|
||||||
|
bool add( Type const& item ) noexcept;
|
||||||
|
bool add( Type&& item ) noexcept;
|
||||||
|
bool remove( Type const& item ) noexcept;
|
||||||
|
|
||||||
|
void free( ) noexcept;
|
||||||
|
void clear( ) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t find( Type const& k ,
|
||||||
|
const uint32_t hash ) const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define M_TMPL_ template< typename Type , uint32_t ISize , uint32_t HSize , uint32_t Growth >
|
||||||
|
#define M_TYPE_ T_SetImplementation< Type , IndexBacked< ISize , HSize , Growth > >
|
||||||
|
|
||||||
|
M_TMPL_ uint32_t M_TYPE_::size( ) const noexcept
|
||||||
|
{
|
||||||
|
return items_.size( );
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TMPL_ int32_t M_TYPE_::indexOf(
|
||||||
|
Type const& item ) const noexcept
|
||||||
|
{
|
||||||
|
const auto idx{ find( item , ComputeHash( item ) ) };
|
||||||
|
return idx == T_HashIndex::INVALID_INDEX ? -1 : int32_t( idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TMPL_ Type const* M_TYPE_::access(
|
||||||
|
const uint32_t item ) const noexcept
|
||||||
|
{
|
||||||
|
return &items_[ item ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
M_TMPL_ bool M_TYPE_::add(
|
||||||
|
Type const& item ) noexcept
|
||||||
|
{
|
||||||
|
const auto hash{ ComputeHash( item ) };
|
||||||
|
const auto idx{ find( item , hash ) };
|
||||||
|
if ( idx == T_HashIndex::INVALID_INDEX ) {
|
||||||
|
index_.add( hash );
|
||||||
|
items_.add( item );
|
||||||
|
}
|
||||||
|
return idx == T_HashIndex::INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TMPL_ bool M_TYPE_::add(
|
||||||
|
Type&& item ) noexcept
|
||||||
|
{
|
||||||
|
const auto hash{ ComputeHash( item ) };
|
||||||
|
const auto idx{ find( item , hash ) };
|
||||||
|
if ( idx == T_HashIndex::INVALID_INDEX ) {
|
||||||
|
index_.add( hash );
|
||||||
|
items_.add( std::move( item ) );
|
||||||
|
}
|
||||||
|
return idx == T_HashIndex::INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TMPL_ bool M_TYPE_::remove(
|
||||||
|
Type const& item ) noexcept
|
||||||
|
{
|
||||||
|
const auto hash{ ComputeHash( item ) };
|
||||||
|
const auto idx{ find( item , hash ) };
|
||||||
|
if ( idx != T_HashIndex::INVALID_INDEX ) {
|
||||||
|
items_.removeSwap( idx );
|
||||||
|
index_.remove( idx );
|
||||||
|
}
|
||||||
|
return idx != T_HashIndex::INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
M_TMPL_ void M_TYPE_::free( ) noexcept
|
||||||
|
{
|
||||||
|
index_.free( );
|
||||||
|
items_.free( );
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TMPL_ void M_TYPE_::clear( ) noexcept
|
||||||
|
{
|
||||||
|
index_.clear( );
|
||||||
|
items_.clear( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
M_TMPL_ uint32_t M_TYPE_::find(
|
||||||
|
Type const& k ,
|
||||||
|
const uint32_t hash ) const noexcept
|
||||||
|
{
|
||||||
|
uint32_t idx = index_.first( hash );
|
||||||
|
while ( idx != T_HashIndex::INVALID_INDEX ) {
|
||||||
|
// XXX use a match function?
|
||||||
|
// if ( match_( keys_[ idx ] , k ) ) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
if ( items_[ idx ] == k ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx = index_.next( idx );
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef M_TMPL_
|
||||||
|
#undef M_TYPE_
|
||||||
|
|
||||||
|
|
||||||
/*= COMMON HANDLER ===========================================================*/
|
/*= COMMON HANDLER ===========================================================*/
|
||||||
|
|
||||||
// In-place version
|
// In-place version
|
||||||
|
|
12
Sets.hh
12
Sets.hh
|
@ -5,6 +5,7 @@
|
||||||
#ifndef _H_EBCL_SETS
|
#ifndef _H_EBCL_SETS
|
||||||
#define _H_EBCL_SETS
|
#define _H_EBCL_SETS
|
||||||
#include <ebcl/Arrays.hh>
|
#include <ebcl/Arrays.hh>
|
||||||
|
#include <ebcl/HashIndex.hh>
|
||||||
namespace ebcl {
|
namespace ebcl {
|
||||||
|
|
||||||
// FIXME move this to utilities \/
|
// FIXME move this to utilities \/
|
||||||
|
@ -41,7 +42,14 @@ M_DEFINE_TEMPLATE_TAG( ArrayBacked ,
|
||||||
uint32_t InPlace ,
|
uint32_t InPlace ,
|
||||||
uint32_t Growth = 0
|
uint32_t Growth = 0
|
||||||
);
|
);
|
||||||
//M_DEFINE_TAG( IndexBacked );
|
|
||||||
|
// IndexBacked implementation tag - the implementation will use a
|
||||||
|
// T_HashIndex and an array. InitialSize and HashSize affect the index,
|
||||||
|
// Growth affects both the index and the array.
|
||||||
|
M_DEFINE_TEMPLATE_TAG( IndexBacked ,
|
||||||
|
uint32_t InitialSize = T_HashIndex::DEFAULT_SIZE ,
|
||||||
|
uint32_t HashSize = T_HashIndex::DEFAULT_SIZE ,
|
||||||
|
uint32_t Growth = T_HashIndex::DEFAULT_GROWTH );
|
||||||
|
|
||||||
|
|
||||||
// Templated horrors used by the main T_Set class.
|
// Templated horrors used by the main T_Set class.
|
||||||
|
@ -49,7 +57,7 @@ struct T_SetHelper
|
||||||
{
|
{
|
||||||
// Default implementation to use; also determines the in-place
|
// Default implementation to use; also determines the in-place
|
||||||
// storage size
|
// storage size
|
||||||
using DefaultImplementation = ArrayBacked< 8 >; // FIXME should use Index by default
|
using DefaultImplementation = IndexBacked< >;
|
||||||
|
|
||||||
// Default implementation class
|
// Default implementation class
|
||||||
template< typename Type
|
template< typename Type
|
||||||
|
|
Loading…
Reference in a new issue