Blame include/PointerTable.cxx

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 */