#ifndef SQUID_SPLAY_H
#define SQUID_SPLAY_H
-#if defined(__cplusplus)
-
#include "fatal.h"
-
#include <stack>
+// private class of Splay. Do not use directly
template <class V>
class SplayNode
{
-
public:
typedef V Value;
typedef int SPLAYCMP(Value const &a, Value const &b);
Value data;
mutable SplayNode<V> *left;
mutable SplayNode<V> *right;
- void destroy(SPLAYFREE *);
+ void destroy(SPLAYFREE * = DefaultFree);
void walk(SPLAYWALKEE *, void *callerState);
- bool empty() const {return false;}
SplayNode<V> const * start() const;
SplayNode<V> const * finish() const;
SplayNode<V> * insert(Value data, SPLAYCMP * compare);
+ /// look in the splay for data for where compare(data,candidate) == true.
+ /// return NULL if not found, a pointer to the sought data if found.
template <class FindValue> SplayNode<V> * splay(const FindValue &data, int( * compare)(FindValue const &a, Value const &b)) const;
/// recursively visit left nodes, this node, and then right nodes
template <class V>
class Splay
{
-
public:
typedef V Value;
typedef int SPLAYCMP(Value const &a, Value const &b);
typedef const SplayConstIterator<V> const_iterator;
Splay():head(NULL), elements (0) {}
- mutable SplayNode<V> * head;
template <class FindValue> Value const *find (FindValue const &, int( * compare)(FindValue const &a, Value const &b)) const;
+
void insert(Value const &, SPLAYCMP *compare);
void remove(Value const &, SPLAYCMP *compare);
- void destroy(SPLAYFREE *);
+ void destroy(SPLAYFREE * = SplayNode<V>::DefaultFree);
SplayNode<V> const * start() const;
size_t size() const;
+ bool empty() const { return size() == 0; }
+
const_iterator begin() const;
const_iterator end() const;
/// recursively visit all nodes, in left-to-right order
template <class Visitor> void visit(Visitor &v) const;
+private:
+ mutable SplayNode<V> * head;
size_t elements;
};
SQUIDCEXTERN int splayLastResult;
-SQUIDCEXTERN splayNode *splay_insert(void *, splayNode *, splayNode::SPLAYCMP *);
-
-SQUIDCEXTERN splayNode *splay_delete(const void *, splayNode *, splayNode::SPLAYCMP *);
-
-SQUIDCEXTERN splayNode *splay_splay(const void **, splayNode *, splayNode::SPLAYCMP *);
-
-SQUIDCEXTERN void splay_destroy(splayNode *, splayNode::SPLAYFREE *);
-
-SQUIDCEXTERN void splay_walk(splayNode *, splayNode::SPLAYWALKEE *, void *callerState);
-
-/* inline methods */
template<class V>
SplayNode<V>::SplayNode (Value const &someData) : data(someData), left(NULL), right (NULL) {}
{
SplayNode<V> *result = splay(dataToRemove, compare);
- if (splayLastResult == 0) { /* found it */
+ if (splayLastResult == 0) { /* found it */
SplayNode<V> *newTop;
if (result->left == NULL) {
return newTop;
}
- return result; /* It wasn't there */
+ return result; /* It wasn't there */
}
template<class V>
{
/* create node to insert */
SplayNode<V> *newNode = new SplayNode<V>(dataToInsert);
-
SplayNode<V> *newTop = splay(dataToInsert, compare);
if (splayLastResult < 0) {
break;
if ((splayLastResult = compare(dataToFind, top->left->data)) < 0) {
- y = top->left; /* rotate right */
+ y = top->left; /* rotate right */
top->left = y->right;
y->right = top;
top = y;
break;
}
- r->left = top; /* link right */
+ r->left = top; /* link right */
r = top;
top = top->left;
} else if (splayLastResult > 0) {
break;
if ((splayLastResult = compare(dataToFind, top->right->data)) > 0) {
- y = top->right; /* rotate left */
+ y = top->right; /* rotate left */
top->right = y->left;
y->left = top;
top = y;
break;
}
- l->right = top; /* link left */
+ l->right = top; /* link left */
l = top;
top = top->right;
} else {
}
}
- l->right = top->left; /* assemble */
+ l->right = top->left; /* assemble */
r->left = top->right;
top->left = N.right;
top->right = N.left;
typename Splay<V>::Value const *
Splay<V>::find (FindValue const &value, int( * compare)(FindValue const &a, Value const &b)) const
{
+ if (head == NULL)
+ return NULL;
+
head = head->splay(value, compare);
if (splayLastResult != 0)
void
Splay<V>::insert(Value const &value, SPLAYCMP *compare)
{
- assert (!find (value, compare));
- head = head->insert(value, compare);
+ assert (find (value, compare) == NULL);
+ if (head == NULL)
+ head = new SplayNode<V>(value);
+ else
+ head = head->insert(value, compare);
++elements;
}
return toVisit.top()->data;
}
-#endif /* cplusplus */
-
#endif /* SQUID_SPLAY_H */
+