/*
- * $Id: splay.h,v 1.20 2003/06/24 12:30:59 robertc Exp $
+ * $Id: splay.h,v 1.21 2003/06/26 12:51:57 robertc Exp $
*/
#ifndef SQUID_SPLAY_H
#ifndef __cplusplus
/* legacy C bindings - can be removed when mempool is C++ */
-typedef struct _splay_node {
+
+typedef struct _splay_node
+{
void *data;
+
struct _splay_node *left;
+
struct _splay_node *right;
-} splayNode;
+}
+
+splayNode;
typedef int SPLAYCMP(const void **a, const void **b);
typedef void SPLAYWALKEE(void **nodedata, void *state);
template <class V>
-class SplayNode {
- public:
+
+class SplayNode
+{
+
+public:
typedef V Value;
typedef int SPLAYCMP(Value const &a, Value const &b);
typedef void SPLAYFREE(Value &);
typedef void SPLAYWALKEE(Value const & nodedata, void *state);
static void DefaultFree (Value &aValue) {aValue->deleteSelf();}
+
Value data;
mutable SplayNode<V> *left;
mutable SplayNode<V> *right;
void destroy(SPLAYFREE *);
void walk(SPLAYWALKEE *, void *callerState);
SplayNode<V> const * start() const;
- SplayNode<V> * remove(const Value data, SPLAYCMP * compare);
+ SplayNode<V> const * end() const;
+
+ SplayNode<V> * remove
+ (const Value data, SPLAYCMP * compare);
+
SplayNode<V> * insert(Value data, SPLAYCMP * compare);
+
SplayNode<V> * splay(const Value &data, SPLAYCMP * compare) const;
};
typedef SplayNode<void *> splayNode;
template <class V>
-class Splay {
- public:
+
+class Splay
+{
+
+public:
typedef V Value;
typedef int SPLAYCMP(Value const &a, Value const &b);
+ typedef void SPLAYFREE(Value &);
Splay():head(NULL), elements (0){}
+
mutable SplayNode<V> * head;
Value const *find (Value const &, SPLAYCMP *compare) const;
void insert(Value const &, SPLAYCMP *compare);
- void remove(Value const &, SPLAYCMP *compare);
+
+ void remove
+ (Value const &, SPLAYCMP *compare);
+
+ void destroy(SPLAYFREE *);
+
SplayNode<V> const * start() const;
+
+ SplayNode<V> const * end() const;
+
+ size_t size() const;
+
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 */
SplayNode<V>::walk(SPLAYWALKEE * walkee, void *state)
{
if (this == NULL)
- return;
+ return;
+
if (left)
- left->walk(walkee, state);
+ left->walk(walkee, state);
+
walkee(data, state);
+
if (right)
- right->walk(walkee, state);
+ right->walk(walkee, state);
}
template<class V>
SplayNode<V>::start() const
{
if (this && left)
- return left->start();
+ return left->start();
+
+ return this;
+}
+
+template<class V>
+SplayNode<V> const *
+SplayNode<V>::end() const
+{
+ if (this && right)
+ return right->end();
+
return this;
}
SplayNode<V>::destroy(SPLAYFREE * free_func)
{
if (!this)
- return;
+ return;
+
if (left)
- left->destroy(free_func);
+ left->destroy(free_func);
+
if (right)
- right->destroy(free_func);
+ right->destroy(free_func);
+
free_func(data);
+
delete this;
}
template<class V>
SplayNode<V> *
-SplayNode<V>::remove(Value const dataToRemove, SPLAYCMP * compare)
+SplayNode<V>::remove
+ (Value const dataToRemove, SPLAYCMP * compare)
{
if (this == NULL)
- return NULL;
+ return NULL;
+
SplayNode<V> *result = splay(dataToRemove, compare);
+
if (splayLastResult == 0) { /* found it */
- SplayNode<V> *newTop;
- if (result->left == NULL) {
- newTop = result->right;
- } else {
- newTop = result->left->splay(dataToRemove, compare);
- /* temporary */
- newTop->right = result->right;
- result->right = NULL;
- }
- delete result;
- return newTop;
+ SplayNode<V> *newTop;
+
+ if (result->left == NULL) {
+ newTop = result->right;
+ } else {
+ newTop = result->left->splay(dataToRemove, compare);
+ /* temporary */
+ newTop->right = result->right;
+ result->right = NULL;
+ }
+
+ delete result;
+ return newTop;
}
+
return result; /* It wasn't there */
}
/* create node to insert */
SplayNode<V> *newNode = new SplayNode<V>;
newNode->data = dataToInsert;
+
if (this == NULL) {
- splayLastResult = -1;
- newNode->left = newNode->right = NULL;
- return newNode;
+ splayLastResult = -1;
+ newNode->left = newNode->right = NULL;
+ return newNode;
}
-
+
SplayNode<V> *newTop = splay(dataToInsert, compare);
+
if (splayLastResult < 0) {
- newNode->left = newTop->left;
- newNode->right = newTop;
- newTop->left = NULL;
- return newNode;
+ newNode->left = newTop->left;
+ newNode->right = newTop;
+ newTop->left = NULL;
+ return newNode;
} else if (splayLastResult > 0) {
- newNode->right = newTop->right;
- newNode->left = newTop;
- newTop->right = NULL;
- return newNode;
+ newNode->right = newTop->right;
+ newNode->left = newTop;
+ newTop->right = NULL;
+ return newNode;
} else {
- /* duplicate entry */
- delete newNode;
- return newTop;
+ /* duplicate entry */
+ delete newNode;
+ return newTop;
}
}
SplayNode<V>::splay(Value const &dataToFind, SPLAYCMP * compare) const
{
if (this == NULL) {
- /* can't have compared successfully :} */
- splayLastResult = -1;
- return NULL;
+ /* can't have compared successfully :} */
+ splayLastResult = -1;
+ return NULL;
}
+
SplayNode<V> N;
SplayNode<V> *l;
SplayNode<V> *r;
l = r = &N;
SplayNode<V> *top = const_cast<SplayNode<V> *>(this);
+
for (;;) {
- splayLastResult = compare(dataToFind, top->data);
- if (splayLastResult < 0) {
- if (top->left == NULL)
- break;
- if ((splayLastResult = compare(dataToFind, top->left->data)) < 0) {
- y = top->left; /* rotate right */
- top->left = y->right;
- y->right = top;
- top = y;
- if (top->left == NULL)
- break;
- }
- r->left = top; /* link right */
- r = top;
- top = top->left;
- } else if (splayLastResult > 0) {
- if (top->right == NULL)
- break;
- if ((splayLastResult = compare(dataToFind, top->right->data)) > 0) {
- y = top->right; /* rotate left */
- top->right = y->left;
- y->left = top;
- top = y;
- if (top->right == NULL)
- break;
- }
- l->right = top; /* link left */
- l = top;
- top = top->right;
- } else {
- break;
- }
+ splayLastResult = compare(dataToFind, top->data);
+
+ if (splayLastResult < 0) {
+ if (top->left == NULL)
+ break;
+
+ if ((splayLastResult = compare(dataToFind, top->left->data)) < 0) {
+ y = top->left; /* rotate right */
+ top->left = y->right;
+ y->right = top;
+ top = y;
+
+ if (top->left == NULL)
+ break;
+ }
+
+ r->left = top; /* link right */
+ r = top;
+ top = top->left;
+ } else if (splayLastResult > 0) {
+ if (top->right == NULL)
+ break;
+
+ if ((splayLastResult = compare(dataToFind, top->right->data)) > 0) {
+ y = top->right; /* rotate left */
+ top->right = y->left;
+ y->left = top;
+ top = y;
+
+ if (top->right == NULL)
+ break;
+ }
+
+ l->right = top; /* link left */
+ l = top;
+ top = top->right;
+ } else {
+ break;
+ }
}
+
l->right = top->left; /* assemble */
r->left = top->right;
top->left = N.right;
Splay<V>::find (Value const &value, SPLAYCMP *compare) const
{
head = head->splay(value, compare);
+
if (splayLastResult != 0)
- return NULL;
+ return NULL;
+
return &head->data;
}
template <class V>
void
-Splay<V>::remove(Value const &value, SPLAYCMP *compare)
+Splay<V>::remove
+ (Value const &value, SPLAYCMP *compare)
{
assert (find (value, compare));
- head = head->remove(value, compare);
+
+ head = head->remove
+ (value, compare);
+
--elements;
}
template <class V>
-SplayNode<V> const *
-Splay<V>:: start() const{
+SplayNode<V> const *
+Splay<V>:: start() const
+{
+ if (head)
+ return head->start();
+
+ return NULL;
+}
+
+template <class V>
+SplayNode<V> const *
+Splay<V>:: end() const
+{
if (head)
- return head->start();
+ return head->end();
+
return NULL;
}
+template <class V>
+void
+Splay<V>:: destroy(SPLAYFREE *free_func)
+{
+ if (head)
+ head->destroy(free_func);
+
+ head = NULL;
+
+ elements = 0;
+}
+
+template <class V>
+size_t
+Splay<V>::size() const
+{
+ return elements;
+}
+
#endif
#endif /* SQUID_SPLAY_H */
/*
- * $Id: MemObject.cc,v 1.8 2003/06/24 12:42:25 robertc Exp $
+ * $Id: MemObject.cc,v 1.9 2003/06/26 12:51:57 robertc Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Robert Collins
void
MemObject::dump() const
{
- debug(20, 1) ("MemObject->data.head: %p\n",
- data_hdr.head);
- debug(20, 1) ("MemObject->data.tail: %p\n",
- data_hdr.tail);
+ data_hdr.dump();
#if 0
/* do we want this one? */
debug(20, 1) ("MemObject->data.origin_offset: %d\n",
/*
- * $Id: mem_node.cc,v 1.3 2003/06/24 12:30:59 robertc Exp $
+ * $Id: mem_node.cc,v 1.4 2003/06/26 12:51:57 robertc Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Robert Collins
memPoolFree(pool, address);
}
-mem_node::mem_node(off_t offset):nodeBuffer(0,offset,data), next (NULL)
+void
+mem_node::deleteSelf() const
+{
+ delete this;
+}
+
+mem_node::mem_node(off_t offset):nodeBuffer(0,offset,data)
{}
mem_node::~mem_node()
return nodeBuffer.offset + nodeBuffer.length;
}
+Range<size_t>
+mem_node::dataRange() const
+{
+ return Range<size_t> (start(), end());
+}
+
size_t
mem_node::space() const
{
/*
- * $Id: mem_node.h,v 1.3 2003/06/24 12:30:59 robertc Exp $
+ * $Id: mem_node.h,v 1.4 2003/06/26 12:51:57 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#define SQUID_MEM_NODE_H
#include "StoreIOBuffer.h"
+#include "Range.h"
class mem_node
{
void operator delete (void *);
void *operator new (size_t);
+ void deleteSelf() const;
mem_node(off_t);
~mem_node();
size_t space() const;
size_t start() const;
size_t end() const;
+ Range<size_t> dataRange() const;
bool contains (size_t const &location) const;
bool canAccept (size_t const &location) const;
bool operator < (mem_node const & rhs) const;
/* public */
StoreIOBuffer nodeBuffer;
- mem_node *next;
/* Private */
char data[SM_PAGE_SIZE];
/*
- * $Id: stmem.cc,v 1.78 2003/06/24 12:42:25 robertc Exp $
+ * $Id: stmem.cc,v 1.79 2003/06/26 12:51:57 robertc Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Harvest Derived
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
*/
#include "squid.h"
int
mem_hdr::lowestOffset () const
{
- if (head)
- return head->nodeBuffer.offset;
+ const SplayNode<mem_node *> *theStart = nodes.start();
+
+ if (theStart)
+ return theStart->data->nodeBuffer.offset;
return 0;
}
mem_hdr::endOffset () const
{
off_t result = 0;
+ const SplayNode<mem_node *> *theEnd = nodes.end();
- if (tail)
- result = tail->nodeBuffer.offset + tail->nodeBuffer.length;
+ if (theEnd)
+ result = theEnd->data->dataRange().end;
assert (result == inmem_hi);
void
mem_hdr::freeContent()
{
- while (head)
- unlinkHead();
-
- head = tail = NULL;
-
+ nodes.destroy(SplayNode<mem_node *>::DefaultFree);
inmem_hi = 0;
}
void
-mem_hdr::unlinkHead()
+mem_hdr::unlink(mem_node *aNode)
{
- assert (head);
- mem_node *aNode = head;
- head = aNode->next;
- aNode->next = NULL;
- delete aNode;
+ nodes.remove (aNode, NodeCompare);
+ aNode->deleteSelf();
}
int
{
/* keep the last one to avoid change to other part of code */
- while (head && head != tail &&
- ((lowestOffset() + head->nodeBuffer.length) <= (size_t)target_offset))
- unlinkHead ();
+ SplayNode<mem_node*> const * theStart = nodes.start();
+
+ while (theStart && theStart != nodes.end() &&
+ theStart->data->end() <= (size_t) target_offset ) {
+ unlink(theStart->data);
+ theStart = nodes.start();
+ }
assert (lowestOffset () <= target_offset);
void
mem_hdr::appendNode (mem_node *aNode)
{
- assert (aNode->next == NULL);
-
- if (!head) {
- /* The chain is empty */
- head = tail = aNode;
- } else {
- mem_node *pointer = getHighestBlockBeforeLocation(aNode->nodeBuffer.offset);
-
- if (!pointer) {
- /* prepend to list */
- aNode->next = head;
- head = aNode;
- } else {
- /* Append it to existing chain */
- aNode->next = pointer->next;
- pointer->next = aNode;
-
- if (tail == pointer)
- tail = aNode;
- }
- }
+ nodes.insert (aNode, NodeCompare);
}
void
mem_hdr::makeAppendSpace()
{
- if (!head) {
- appendNode (new mem_node(0));
+ if (!nodes.size()) {
+ appendNode (new mem_node (0));
return;
}
- if (!tail->space())
+ if (!nodes.end()->data->space())
appendNode (new mem_node (endOffset()));
- assert (tail->space());
+ assert (nodes.end()->data->space());
}
void
while (len > 0) {
makeAppendSpace();
-
- int copied = appendToNode (tail, data, len);
+ int copied = appendToNode (nodes.end()->data, data, len);
assert (copied);
len -= copied;
}
}
-mem_node *
-mem_hdr::getHighestBlockBeforeLocation (size_t location) const
-{
- mem_node *result = head;
- mem_node *prevResult = NULL;
-
- while (result && result->end() <= location) {
- if (!result->next)
- return result;
-
- prevResult = result;
-
- result = result->next;
-
- if (result->contains(location))
- return result;
- }
-
- /* the if here is so we catch 0 offset requests */
- if (result && result->contains(location))
- return result;
- else
- return prevResult;
-}
-
/* returns a mem_node that contains location..
* If no node contains the start, it returns NULL.
*/
mem_node *
mem_hdr::getBlockContainingLocation (size_t location) const
{
- mem_node *result = getHighestBlockBeforeLocation(location);
+ mem_node target (location);
+ target.nodeBuffer.length = 1;
+ mem_node *const *result = nodes.find (&target, NodeCompare);
- if (!result || !result->contains(location))
- return NULL;
+ if (result)
+ return *result;
- return result;
+ return NULL;
}
size_t
debug(19, 6) ("memCopy: offset %ld: size %u\n", (long int) offset, size);
- if (head == NULL)
+ if (nodes.size() == 0) {
+ /* we shouldn't ever ask for absent offsets */
+ assert (0);
return 0;
+ }
/* RC: the next assert is nearly useless */
assert(size > 0);
bytes_to_go -= bytes_to_copy;
- p = p->next;
+ p = getBlockContainingLocation(location);
}
return size - bytes_to_go;
bool
mem_hdr::unionNotEmpty(StoreIOBuffer const &candidate)
{
- mem_node *low = getHighestBlockBeforeLocation(candidate.offset);
assert (candidate.offset >= 0);
-
- if (low && low->end() > (size_t) candidate.offset)
- return true;
-
- mem_node *high = getHighestBlockBeforeLocation(candidate.offset + candidate.length);
-
- /* trivial case - we are writing completely beyond the end of the current object */
- if (low == high)
- return false;
-
- if (high && high->start() < candidate.offset + candidate.length &&
- !high->end() > candidate.offset)
- return true;
-
- return false;
+ mem_node target(candidate.offset);
+ target.nodeBuffer.length = candidate.length;
+ return nodes.find (&target, NodeCompare);
}
mem_node *
{
/* case 1: Nothing in memory */
- if (!head) {
+ if (!nodes.size()) {
appendNode (new mem_node(offset));
- return head;
+ return nodes.start()->data;
}
+ mem_node *candidate = NULL;
/* case 2: location fits within an extant node */
- mem_node *candidate = getHighestBlockBeforeLocation(offset);
- /* case 3: no nodes before it */
- if (!candidate) {
- candidate = new mem_node(offset);
- appendNode (candidate);
- assert (candidate->canAccept(offset));
+ if (offset > 0) {
+ mem_node search (offset - 1);
+ search.nodeBuffer.length = 1;
+ mem_node *const *leadup = nodes.find (&search, NodeCompare);
+
+ if (leadup)
+ candidate = *leadup;
}
- if (candidate->canAccept(offset))
+ if (candidate && candidate->canAccept(offset))
return candidate;
/* candidate can't accept, so we need a new node */
return true;
}
-mem_hdr::mem_hdr() : head (NULL), tail(NULL), inmem_hi(0)
+mem_hdr::mem_hdr() : inmem_hi(0)
{}
mem_hdr::~mem_hdr()
{
freeContent();
}
+
+/* splay of mem nodes:
+ * conditions:
+ * a = b if a.intersection(b).size > 0;
+ * a < b if a < b
+ */
+int
+mem_hdr::NodeCompare(mem_node * const &left, mem_node * const &right)
+{
+ // possibly Range can help us at some point.
+
+ if (left->dataRange().intersection(right->dataRange()).size() > 0)
+ return 0;
+
+ return *left < *right ? -1 : 1;
+}
+
+void
+mem_hdr::dump() const
+{
+ debug(20, 1) ("mem_hdr: %p nodes.start() %p\n", this, nodes.start());
+ debug(20, 1) ("mem_hdr: %p nodes.end() %p\n", this, nodes.end());
+}
+
+size_t
+mem_hdr::size() const
+{
+ return nodes.size();
+}
+
+mem_node const *
+mem_hdr::start() const
+{
+ const SplayNode<mem_node *> * result = nodes.start();
+
+ if (result)
+ return result->data;
+
+ return NULL;
+}
/*
- * $Id: stmem.h,v 1.3 2003/06/24 12:30:59 robertc Exp $
+ * $Id: stmem.h,v 1.4 2003/06/26 12:51:57 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
*/
#ifndef SQUID_STMEM_H
bool hasContigousContentRange(Range<size_t> const &range) const;
/* success or fail */
bool write (StoreIOBuffer const &);
+ void dump() const;
+ size_t size() const;
+ /* Not an iterator - thus the start, not begin() */
+ mem_node const *start() const;
+ mem_node *getBlockContainingLocation (size_t location) const;
/* Only for use of MemObject */
void internalAppend(const char *data, int len);
- mem_node *head;
- mem_node *tail;
+
+ static SplayNode<mem_node *>::SPLAYCMP NodeCompare;
private:
- void unlinkHead();
+ void unlink(mem_node *aNode);
void makeAppendSpace();
int appendToNode(mem_node *aNode, const char *data, int maxLength);
void appendNode (mem_node *aNode);
- mem_node *getBlockContainingLocation (size_t location) const;
size_t copyAvailable(mem_node *aNode, size_t location, size_t amount, char *target) const;
bool unionNotEmpty (StoreIOBuffer const &);
- mem_node *getHighestBlockBeforeLocation (size_t location) const;
mem_node *nodeToRecieve(off_t offset);
size_t writeAvailable(mem_node *aNode, size_t location, size_t amount, char const *source);
off_t inmem_hi;
- Splay<mem_node> nodes;
+ Splay<mem_node *> nodes;
};
#endif /* SQUID_STMEM_H */
/*
- * $Id: store.cc,v 1.569 2003/06/24 12:42:27 robertc Exp $
+ * $Id: store.cc,v 1.570 2003/06/26 12:51:58 robertc Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
if (mem == NULL)
return 0;
- if (mem->data_hdr.head == NULL)
+ if (mem->data_hdr.size() == 0)
return 0;
return mem->inmem_lo == 0;
/*
- * $Id: store_swapout.cc,v 1.94 2003/03/04 01:40:30 robertc Exp $
+ * $Id: store_swapout.cc,v 1.95 2003/06/26 12:51:58 robertc Exp $
*
* DEBUG: section 20 Storage Manager Swapout Functions
* AUTHOR: Duane Wessels
if (mem->swapout.memnode == NULL) {
/* We need to swap out the first page */
- mem->swapout.memnode = mem->data_hdr.head;
+ mem->swapout.memnode = const_cast<mem_node *>(mem->data_hdr.start());
} else {
/* We need to swap out the next page */
- mem->swapout.memnode = mem->swapout.memnode->next;
+ /* 20030636 RBC - we don't have ->next anymore.
+ * But we do have the next location */
+ mem->swapout.memnode = mem->data_hdr.getBlockContainingLocation (mem->swapout.memnode->end());
}
/*
/*
- * $Id: mem_hdr_test.cc,v 1.1 2003/06/24 12:31:02 robertc Exp $
+ * $Id: mem_hdr_test.cc,v 1.2 2003/06/26 12:52:00 robertc Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Robert Collins
assert (!aHeader.hasContigousContentRange(Range<size_t>(10,101)));
}
+void
+testSplayOfNodes()
+{
+ Splay<mem_node *> aSplay;
+ mem_node *temp5;
+ temp5 = new mem_node(5);
+ temp5->nodeBuffer.length = 10;
+ aSplay.insert (temp5, mem_hdr::NodeCompare);
+ assert (aSplay.start()->data == temp5);
+ assert (aSplay.end()->data == temp5);
+
+ mem_node *temp0;
+ temp0 = new mem_node(0);
+ temp0->nodeBuffer.length = 5;
+ aSplay.insert (temp0, mem_hdr::NodeCompare);
+ assert (aSplay.start()->data == temp0);
+ assert (aSplay.end()->data == temp5);
+
+ mem_node *temp14;
+ temp14 = new mem_node (14);
+ temp14->nodeBuffer.length = 1;
+ assert (aSplay.find(temp14,mem_hdr::NodeCompare));
+
+ mem_node ref13 (13);
+ assert (!aSplay.find(&ref13,mem_hdr::NodeCompare));
+ ref13.nodeBuffer.length = 1;
+ assert (aSplay.find(&ref13,mem_hdr::NodeCompare));
+}
+
int
main (int argc, char *argv)
{
testLowAndHigh();
assert (mem_node::InUseCount() == 0);
+ testSplayOfNodes();
return 0;
}
/*
- * $Id: mem_node_test.cc,v 1.3 2003/06/24 12:31:00 robertc Exp $
+ * $Id: mem_node_test.cc,v 1.4 2003/06/26 12:52:00 robertc Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Robert Collins
std::cout << "Assertion failed: (" << msg << ") at " << file << ":" << line << std::endl;
exit (1);
}
+
time_t squid_curtime = 0;
int
aNode->nodeBuffer.length = 45;
assert (aNode->start() == 0);
assert (aNode->end() == 45);
+ assert (aNode->dataRange().size() == 45);
aNode->nodeBuffer.offset = 50;
assert (aNode->start() == 50);
assert (aNode->end() == 95);
+ assert (aNode->dataRange().size() == 45);
assert (!aNode->contains(49));
assert (aNode->contains(50));
assert (aNode->contains(75));
assert (mem_node (0) < mem_node (2));
assert (!(mem_node (0) < mem_node (0)));
assert (!(mem_node (2) < mem_node (0)));
+ aNode->deleteSelf();
+ assert (mem_node::InUseCount() == 0);
return 0;
}
/*
- * $Id: splay.cc,v 1.4 2003/06/24 12:31:00 robertc Exp $
+ * $Id: splay.cc,v 1.5 2003/06/26 12:52:00 robertc Exp $
*
* based on ftp://ftp.cs.cmu.edu/user/sleator/splaying/top-down-splay.c
* http://bobo.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl
#include <unistd.h>
#endif
+#define assert(X) {if (!(X)) exit (1);}
#include "splay.h"
+#undef assert
#include "util.h"
-typedef struct {
+
+class intnode
+{
+
+public:
+ intnode() : i(0){}
+
+ intnode (int anInt) : i (anInt) {}
+
int i;
-} intnode;
+};
int
compareintvoid(void * const &a, void * const &n)
class SplayCheck
{
- public:
+
+public:
static void BeginWalk();
static int LastValue;
static bool ExpectedFail;
SplayCheck::CheckNode(intnode const &A)
{
if (LastValue > A.i) {
- /* failure */
- if (!ExpectedFail)
- exit (1);
+ /* failure */
+
+ if (!ExpectedFail)
+ exit (1);
} else
- /* success */
- if (ExpectedFail)
- exit (1);
+ /* success */
+ if (ExpectedFail)
+ exit (1);
+
LastValue = A.i;
}
void
destintref (intnode &)
-{
-}
+{}
int
main(int argc, char *argv[])
{
- {
- int i;
- intnode *I;
- /* test void * splay containers */
- splayNode *top = NULL;
- srandom(time(NULL));
- for (i = 0; i < 100; i++) {
- I = (intnode *)xcalloc(sizeof(intnode), 1);
- I->i = random();
- top = splay_insert(I, top, compareintvoid);
+ {
+ int i;
+ intnode *I;
+ /* test void * splay containers */
+ splayNode *top = NULL;
+ srandom(time(NULL));
+
+ for (i = 0; i < 100; i++) {
+ I = (intnode *)xcalloc(sizeof(intnode), 1);
+ I->i = random();
+ top = splay_insert(I, top, compareintvoid);
+ }
+
+ SplayCheck::BeginWalk();
+ splay_walk(top, SplayCheck::WalkVoid, NULL);
+
+ SplayCheck::BeginWalk();
+ top->walk(SplayCheck::WalkVoid, NULL);
+ top->destroy(destintvoid);
+ /* check we don't segfault on NULL splay calls */
+ top = NULL;
+ top->splay(NULL, compareintvoid);
}
- SplayCheck::BeginWalk();
- splay_walk(top, SplayCheck::WalkVoid, NULL);
-
- SplayCheck::BeginWalk();
- top->walk(SplayCheck::WalkVoid, NULL);
- top->destroy(destintvoid);
- /* check we don't segfault on NULL splay calls */
- top = NULL;
- top->splay(NULL, compareintvoid);
- }
+
/* test typesafe splay containers */
- {
- /* intnode* */
- SplayNode<intnode *> *safeTop = NULL;
- for ( int i = 0; i < 100; i++) {
- intnode *I;
- I = new intnode;
- I->i = random();
- safeTop = safeTop->insert(I, compareint);
+ {
+ /* intnode* */
+ SplayNode<intnode *> *safeTop = NULL;
+
+ for ( int i = 0; i < 100; i++)
+ {
+ intnode *I;
+ I = new intnode;
+ I->i = random();
+ safeTop = safeTop->insert(I, compareint);
+ }
+
+ SplayCheck::BeginWalk();
+ safeTop->walk(SplayCheck::WalkNode, NULL);
+
+ safeTop->destroy(destint);
+ /* check we don't segfault on NULL splay calls */
+ safeTop = NULL;
+ safeTop->splay(NULL, compareint);
}
- SplayCheck::BeginWalk();
- safeTop->walk(SplayCheck::WalkNode, NULL);
-
- safeTop->destroy(destint);
- /* check we don't segfault on NULL splay calls */
- safeTop = NULL;
- safeTop->splay(NULL, compareint);
- }
- {
- /* intnode */
- SplayNode<intnode> *safeTop = NULL;
- for (int i = 0; i < 100; i++) {
- intnode I;
- I.i = random();
- safeTop = safeTop->insert(I, compareintref);
+ {
+ /* intnode */
+ SplayNode<intnode> *safeTop = NULL;
+
+ for (int i = 0; i < 100; i++)
+ {
+ intnode I;
+ I.i = random();
+ safeTop = safeTop->insert(I, compareintref);
+ }
+
+ SplayCheck::BeginWalk();
+ safeTop->walk(SplayCheck::WalkNodeRef, NULL);
+
+ safeTop->destroy(destintref);
+ /* check we don't segfault on NULL splay calls */
+ safeTop = NULL;
+ safeTop->splay(intnode(), compareintref);
+ SplayCheck::BeginWalk();
+ safeTop->walk(SplayCheck::WalkNodeRef, NULL);
}
- SplayCheck::BeginWalk();
- safeTop->walk(SplayCheck::WalkNodeRef, NULL);
-
- safeTop->destroy(destintref);
- /* check we don't segfault on NULL splay calls */
- safeTop = NULL;
- safeTop->splay(intnode(), compareintref);
- SplayCheck::BeginWalk();
- safeTop->walk(SplayCheck::WalkNodeRef, NULL);
-}
/* check the check routine */
SplayCheck::BeginWalk();
intnode I;
I.i = 0;
SplayCheck::ExpectedFail = true;
SplayCheck::WalkNodeRef(I, NULL);
-
-{
- /* check for begin() */
- SplayNode<intnode> *safeTop = NULL;
- if (safeTop->start() != NULL)
- exit (1);
- for (int i = 0; i < 100; i++) {
- intnode I;
- I.i = random();
- if (i > 50)
- safeTop = safeTop->insert(I, compareintref);
- }
+
{
- intnode I;
- I.i = 50;
- safeTop = safeTop->insert (I, compareintref);
+ /* check for begin() */
+ SplayNode<intnode> *safeTop = NULL;
+
+ if (safeTop->start() != NULL)
+ exit (1);
+
+ if (safeTop->end() != NULL)
+ exit (1);
+
+ for (int i = 0; i < 100; i++) {
+ intnode I;
+ I.i = random();
+
+ if (I.i > 50 && I.i < 10000000)
+ safeTop = safeTop->insert(I, compareintref);
+ }
+
+ {
+ intnode I;
+ I.i = 50;
+ safeTop = safeTop->insert (I, compareintref);
+ I.i = 10000000;
+ safeTop = safeTop->insert (I, compareintref);
+ }
+
+ if (!safeTop->start())
+ exit (1);
+
+ if (safeTop->start()->data.i != 50)
+ exit (1);
+
+ if (!safeTop->end())
+ exit (1);
+
+ if (safeTop->end()->data.i != 10000000)
+ exit (1);
+
+ safeTop->destroy(destintref);
}
- if (!safeTop->start())
- exit (1);
- if (safeTop->start()->data.i != 50)
- exit (1);
- safeTop->destroy(destintref);
-}
+
{
- Splay<intnode *> aSplay;
- if (aSplay.start() != NULL)
- exit (1);
+ Splay<intnode *> aSplay;
+
+ if (aSplay.start() != NULL)
+ exit (1);
+
+ if (aSplay.size() != 0)
+ exit (1);
+
+ aSplay.insert (new intnode(5), compareint);
+
+ if (aSplay.start() == NULL)
+ exit (1);
+
+ if (aSplay.size() != 1)
+ exit (1);
+
+ aSplay.destroy(destint);
+
+ if (aSplay.start() != NULL)
+ exit (1);
+
+ if (aSplay.size() != 0)
+ exit (1);
}
+
return 0;
}