|
Packit |
8a864e |
// Copyright (c) 1994 James Clark
|
|
Packit |
8a864e |
// See the file COPYING for copying permission.
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifndef PointerTable_DEF_INCLUDED
|
|
Packit |
8a864e |
#define PointerTable_DEF_INCLUDED 1
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#include <stdlib.h>
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
namespace SP_NAMESPACE {
|
|
Packit |
8a864e |
#endif
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
PointerTable<P, K, HF, KF>::PointerTable()
|
|
Packit |
8a864e |
: used_(0), usedLimit_(0), null_(0)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
void PointerTable<P, K, HF, KF>::clear()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
vec_.clear();
|
|
Packit |
8a864e |
used_ = 0;
|
|
Packit |
8a864e |
usedLimit_ = 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
P PointerTable<P, K, HF, KF>::insert(P p, Boolean replace)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
size_t h;
|
|
Packit |
8a864e |
if (vec_.size() == 0) {
|
|
Packit |
8a864e |
vec_.assign(8, P(0));
|
|
Packit |
8a864e |
usedLimit_ = 4;
|
|
Packit |
8a864e |
h = startIndex(KF::key(*p));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
for (h = startIndex(KF::key(*p)); vec_[h] != 0 ; h = nextIndex(h))
|
|
Packit |
8a864e |
if (KF::key(*vec_[h]) == KF::key(*p)) {
|
|
Packit |
8a864e |
if (replace) {
|
|
Packit |
8a864e |
P tem(vec_[h]);
|
|
Packit |
8a864e |
vec_[h] = p;
|
|
Packit |
8a864e |
return tem;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
return vec_[h];
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (used_ >= usedLimit_) {
|
|
Packit |
8a864e |
if (vec_.size() > size_t(-1)/2) {
|
|
Packit |
8a864e |
if (usedLimit_ == vec_.size() - 1)
|
|
Packit |
8a864e |
abort(); // FIXME throw an exception
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
usedLimit_ = vec_.size() - 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
// rehash
|
|
Packit |
8a864e |
Vector oldVec(vec_.size()*2, P(0));
|
|
Packit |
8a864e |
vec_.swap(oldVec);
|
|
Packit |
8a864e |
usedLimit_ = vec_.size() / 2;
|
|
Packit |
8a864e |
for (size_t i = 0; i < oldVec.size(); i++)
|
|
Packit |
8a864e |
if (oldVec[i] != 0) {
|
|
Packit |
8a864e |
size_t j;
|
|
Packit |
8a864e |
for (j = startIndex(KF::key(*oldVec[i]));
|
|
Packit |
8a864e |
vec_[j] != 0;
|
|
Packit |
8a864e |
j = nextIndex(j))
|
|
Packit |
8a864e |
;
|
|
Packit |
8a864e |
vec_[j] = oldVec[i];
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
for (h = startIndex(KF::key(*p)); vec_[h] != 0; h = nextIndex(h))
|
|
Packit |
8a864e |
;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
used_++;
|
|
Packit |
8a864e |
vec_[h] = p;
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
const P &PointerTable<P, K, HF, KF>::lookup(const K &k) const
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (used_ > 0) {
|
|
Packit |
8a864e |
for (size_t i = startIndex(k); vec_[i] != 0; i = nextIndex(i))
|
|
Packit |
8a864e |
if (KF::key(*vec_[i]) == k)
|
|
Packit |
8a864e |
return vec_[i];
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return null_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
P PointerTable<P, K, HF, KF>::remove(const K &k)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (used_ > 0) {
|
|
Packit |
8a864e |
for (size_t i = startIndex(k); vec_[i] != 0; i = nextIndex(i))
|
|
Packit |
8a864e |
if (KF::key(*vec_[i]) == k) {
|
|
Packit |
8a864e |
P p = vec_[i];
|
|
Packit |
8a864e |
do {
|
|
Packit |
8a864e |
vec_[i] = P(0);
|
|
Packit |
8a864e |
size_t j = i;
|
|
Packit |
8a864e |
size_t r;
|
|
Packit |
8a864e |
do {
|
|
Packit |
8a864e |
i = nextIndex(i);
|
|
Packit |
8a864e |
if (vec_[i] == 0)
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
r = startIndex(KF::key(*vec_[i]));
|
|
Packit |
8a864e |
} while ((i <= r && r < j) || (r < j && j < i) || (j < i && i <= r));
|
|
Packit |
8a864e |
vec_[j] = vec_[i];
|
|
Packit |
8a864e |
} while (vec_[i] != 0);
|
|
Packit |
8a864e |
--used_;
|
|
Packit |
8a864e |
return p;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
void PointerTable<P, K, HF, KF>::swap(PointerTable<P, K, HF, KF> &to)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
vec_.swap(to.vec_);
|
|
Packit |
8a864e |
size_t tem = to.used_;
|
|
Packit |
8a864e |
to.used_ = used_;
|
|
Packit |
8a864e |
used_ = tem;
|
|
Packit |
8a864e |
tem = to.usedLimit_;
|
|
Packit |
8a864e |
to.usedLimit_ = usedLimit_;
|
|
Packit |
8a864e |
usedLimit_ = tem;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
PointerTableIter<P, K, HF, KF>::PointerTableIter(const PointerTable<P, K, HF, KF> &table)
|
|
Packit |
8a864e |
: tablePtr_(&table), i_(0)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
template<class P, class K, class HF, class KF>
|
|
Packit |
8a864e |
const P &PointerTableIter<P, K, HF, KF>::next()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (; i_ < tablePtr_->vec_.size(); i_++)
|
|
Packit |
8a864e |
if (tablePtr_->vec_[i_] != 0)
|
|
Packit |
8a864e |
return tablePtr_->vec_[i_++];
|
|
Packit |
8a864e |
return tablePtr_->null_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
#endif
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#endif /* not PointerTable_DEF_INCLUDED */
|