1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 35a3110598 Squashed 'software/chuffed/' content from commit 2ed0c015
git-subtree-dir: software/chuffed
git-subtree-split: 2ed0c01558d2a5c49c1ce57e048d32c17adf92d3
2021-06-18 09:36:35 +10:00

173 lines
3.3 KiB
C++

#ifndef __SPARSE_SET_H__
#define __SPARSE_SET_H__
// U indicates whether to use FAST_FSET.
#include <cassert>
#include <cstdlib>
template<int U = 0>
class SparseSet {
public:
SparseSet(void) : dom(0), sparse(NULL), dense(NULL), members( 0 )
{
}
SparseSet(unsigned int size) : dom(size),
sparse((unsigned int*) malloc(size*sizeof(unsigned int))),
dense((unsigned int*) malloc(size*sizeof(unsigned int))),
members( 0 )
{
if( U&1 )
{
assert( members == 0 );
for( unsigned int i = 0; i < dom; i++ )
{
sparse[i] = i;
dense[i] = i;
}
}
}
~SparseSet() {
if( sparse )
free(sparse);
if( dense )
free(dense);
}
bool elem(unsigned int value) const {
if( U&1 )
{
return (sparse[value] < members);
} else {
unsigned int a = sparse[value];
if( a < members && dense[a] == value )
return true;
return false;
}
}
bool elemLim(unsigned int lim, unsigned int el)
{
return (sparse[el] < lim) && elem(el);
}
virtual bool insert(unsigned int value)
{
if( U&1 )
{
unsigned int old_dense = sparse[value];
unsigned int lost_val = dense[members];
sparse[value] = members;
dense[members] = value;
sparse[lost_val] = old_dense;
dense[old_dense] = lost_val;
} else {
assert( !elem(value) );
sparse[value] = members;
dense[members] = value;
}
members++;
return true;
}
void clear(void) {
members = 0;
}
unsigned int pos(unsigned int val) const
{
assert( elem(val) );
return sparse[val];
}
unsigned int operator [] (unsigned int index) {
assert(index < members);
return dense[index];
}
void growTo(unsigned int sz)
{
if( sz > dom )
{
sparse = (unsigned int*) realloc(sparse,sizeof(unsigned int)*sz);
dense = (unsigned int*) realloc(dense,sizeof(unsigned int)*sz);
if( U&1 )
{
assert( members == 0 );
for(; dom < sz; dom++ )
{
sparse[dom] = dom;
dense[dom] = dom;
}
}
}
}
unsigned int size(void) {
return members;
}
unsigned int domain(void) {
return dom;
}
protected:
unsigned int dom;
unsigned int* sparse;
unsigned int* dense;
unsigned int members;
};
class TrailedSet : public SparseSet<0> {
public:
TrailedSet(int sz) : SparseSet<0>( sz )
{
}
bool insert(int value)
{
// Assumes not FFSET.
assert( !elem(value) );
sparse[value] = members;
dense[members] = value;
trailChange(members,members+1);
return true;
}
};
// Variant of a trailed sparse set which
// only trails at the end of a series of operations.
class DeferredSet : public SparseSet<0> {
public:
DeferredSet(int sz) : SparseSet<0>( sz )
{
}
// Ensure members is given the correct value.
inline void refresh(void)
{
members = stored;
}
inline void commit(void)
{
if(stored != members)
trailChange(stored, members);
}
protected:
unsigned int stored;
};
#endif