From: robertc <> Date: Thu, 26 Jun 2003 18:51:57 +0000 (+0000) Subject: Summary: Convert mem_hdr to the use of a splay. X-Git-Tag: SQUID_3_0_PRE1~79 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=42a503bda480ca45bac384ace2deb77910dd1948;p=thirdparty%2Fsquid.git Summary: Convert mem_hdr to the use of a splay. Keywords: * Add a dataRange() method to mem_node, to allow direct access to the range available. * Add mem_node::deleteSelf(). * Update copyright on stmem.[cc|h]. * Test new mem_node methods. * Add Splay::end() method and test. * Add mem_hdr::unlink(). * Remove mem_hdr::unlinkHead(), mem_hdr::getHighest.., mem_hdr::head and mem_hdr::tail. * Remove mem_node::next. * Introduce mem_hdr::dump(). * Introduce mem_hdr::size(). * Introduce mem_hdr::start(). * Make mem_hdr::getBlockContainingLocation() public. --- diff --git a/include/splay.h b/include/splay.h index 5b3fde8148..433c31b315 100644 --- a/include/splay.h +++ b/include/splay.h @@ -1,5 +1,5 @@ /* - * $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 @@ -7,11 +7,17 @@ #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); @@ -27,37 +33,61 @@ SQUIDCEXTERN void splay_walk(splayNode *, SPLAYWALKEE *, void *); template -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 *left; mutable SplayNode *right; void destroy(SPLAYFREE *); void walk(SPLAYWALKEE *, void *callerState); SplayNode const * start() const; - SplayNode * remove(const Value data, SPLAYCMP * compare); + SplayNode const * end() const; + + SplayNode * remove + (const Value data, SPLAYCMP * compare); + SplayNode * insert(Value data, SPLAYCMP * compare); + SplayNode * splay(const Value &data, SPLAYCMP * compare) const; }; typedef SplayNode splayNode; template -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 * 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 const * start() const; + + SplayNode const * end() const; + + size_t size() const; + size_t elements; }; @@ -65,9 +95,13 @@ class Splay { 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 */ @@ -76,12 +110,15 @@ void SplayNode::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 @@ -89,7 +126,18 @@ SplayNode const * SplayNode::start() const { if (this && left) - return left->start(); + return left->start(); + + return this; +} + +template +SplayNode const * +SplayNode::end() const +{ + if (this && right) + return right->end(); + return this; } @@ -98,35 +146,45 @@ void SplayNode::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 SplayNode * -SplayNode::remove(Value const dataToRemove, SPLAYCMP * compare) +SplayNode::remove + (Value const dataToRemove, SPLAYCMP * compare) { if (this == NULL) - return NULL; + return NULL; + SplayNode *result = splay(dataToRemove, compare); + if (splayLastResult == 0) { /* found it */ - SplayNode *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 *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 */ } @@ -137,27 +195,29 @@ SplayNode::insert(Value dataToInsert, SPLAYCMP * compare) /* create node to insert */ SplayNode *newNode = new SplayNode; 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 *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; } } @@ -166,10 +226,11 @@ SplayNode * SplayNode::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 N; SplayNode *l; SplayNode *r; @@ -178,40 +239,49 @@ SplayNode::splay(Value const &dataToFind, SPLAYCMP * compare) const l = r = &N; SplayNode *top = const_cast *>(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; @@ -224,8 +294,10 @@ typename Splay::Value const * Splay::find (Value const &value, SPLAYCMP *compare) const { head = head->splay(value, compare); + if (splayLastResult != 0) - return NULL; + return NULL; + return &head->data; } @@ -240,21 +312,56 @@ Splay::insert(Value const &value, SPLAYCMP *compare) template void -Splay::remove(Value const &value, SPLAYCMP *compare) +Splay::remove + (Value const &value, SPLAYCMP *compare) { assert (find (value, compare)); - head = head->remove(value, compare); + + head = head->remove + (value, compare); + --elements; } template -SplayNode const * -Splay:: start() const{ +SplayNode const * +Splay:: start() const +{ + if (head) + return head->start(); + + return NULL; +} + +template +SplayNode const * +Splay:: end() const +{ if (head) - return head->start(); + return head->end(); + return NULL; } +template +void +Splay:: destroy(SPLAYFREE *free_func) +{ + if (head) + head->destroy(free_func); + + head = NULL; + + elements = 0; +} + +template +size_t +Splay::size() const +{ + return elements; +} + #endif #endif /* SQUID_SPLAY_H */ diff --git a/src/MemObject.cc b/src/MemObject.cc index 73fa2cd752..6f05663826 100644 --- a/src/MemObject.cc +++ b/src/MemObject.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -176,10 +176,7 @@ MemObject::write ( StoreIOBuffer writeBuffer, STMCB *callback, void *callbackDat 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", diff --git a/src/mem_node.cc b/src/mem_node.cc index 561d834816..88cea9203f 100644 --- a/src/mem_node.cc +++ b/src/mem_node.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -57,7 +57,13 @@ mem_node::operator delete (void *address) 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() @@ -91,6 +97,12 @@ mem_node::end() const return nodeBuffer.offset + nodeBuffer.length; } +Range +mem_node::dataRange() const +{ + return Range (start(), end()); +} + size_t mem_node::space() const { diff --git a/src/mem_node.h b/src/mem_node.h index 96673e3b9b..bd47f181e2 100644 --- a/src/mem_node.h +++ b/src/mem_node.h @@ -1,6 +1,6 @@ /* - * $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/ @@ -35,6 +35,7 @@ #define SQUID_MEM_NODE_H #include "StoreIOBuffer.h" +#include "Range.h" class mem_node { @@ -45,17 +46,18 @@ public: 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 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]; diff --git a/src/stmem.cc b/src/stmem.cc index c0068f623f..f44d6f6f8a 100644 --- a/src/stmem.cc +++ b/src/stmem.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -31,6 +31,7 @@ * 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 */ #include "squid.h" @@ -41,8 +42,10 @@ int mem_hdr::lowestOffset () const { - if (head) - return head->nodeBuffer.offset; + const SplayNode *theStart = nodes.start(); + + if (theStart) + return theStart->data->nodeBuffer.offset; return 0; } @@ -51,9 +54,10 @@ off_t mem_hdr::endOffset () const { off_t result = 0; + const SplayNode *theEnd = nodes.end(); - if (tail) - result = tail->nodeBuffer.offset + tail->nodeBuffer.length; + if (theEnd) + result = theEnd->data->dataRange().end; assert (result == inmem_hi); @@ -63,22 +67,15 @@ mem_hdr::endOffset () const void mem_hdr::freeContent() { - while (head) - unlinkHead(); - - head = tail = NULL; - + nodes.destroy(SplayNode::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 @@ -86,9 +83,13 @@ mem_hdr::freeDataUpto(int target_offset) { /* 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 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); @@ -131,41 +132,21 @@ mem_hdr::writeAvailable(mem_node *aNode, size_t location, size_t amount, char co 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 @@ -175,8 +156,7 @@ mem_hdr::internalAppend(const char *data, int len) while (len > 0) { makeAppendSpace(); - - int copied = appendToNode (tail, data, len); + int copied = appendToNode (nodes.end()->data, data, len); assert (copied); len -= copied; @@ -184,43 +164,20 @@ mem_hdr::internalAppend(const char *data, int len) } } -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 @@ -255,8 +212,11 @@ mem_hdr::copy(off_t offset, char *buf, size_t size) const 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); @@ -293,7 +253,7 @@ mem_hdr::copy(off_t offset, char *buf, size_t size) const bytes_to_go -= bytes_to_copy; - p = p->next; + p = getBlockContainingLocation(location); } return size - bytes_to_go; @@ -317,23 +277,10 @@ mem_hdr::hasContigousContentRange(Range const & range) const 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 * @@ -341,22 +288,24 @@ mem_hdr::nodeToRecieve(off_t offset) { /* 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 */ @@ -401,10 +350,50 @@ mem_hdr::write (StoreIOBuffer const &writeBuffer) 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 * result = nodes.start(); + + if (result) + return result->data; + + return NULL; +} diff --git a/src/stmem.h b/src/stmem.h index 89f398b53c..b47fff8a29 100644 --- a/src/stmem.h +++ b/src/stmem.h @@ -1,6 +1,6 @@ /* - * $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/ @@ -29,6 +29,7 @@ * 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 */ #ifndef SQUID_STMEM_H @@ -55,25 +56,28 @@ public: bool hasContigousContentRange(Range 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::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 nodes; + Splay nodes; }; #endif /* SQUID_STMEM_H */ diff --git a/src/store.cc b/src/store.cc index 7618a27d35..33664766ce 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -1415,7 +1415,7 @@ storeKeepInMemory(const StoreEntry * e) if (mem == NULL) return 0; - if (mem->data_hdr.head == NULL) + if (mem->data_hdr.size() == 0) return 0; return mem->inmem_lo == 0; diff --git a/src/store_swapout.cc b/src/store_swapout.cc index 3aafaa23e8..943901a20f 100644 --- a/src/store_swapout.cc +++ b/src/store_swapout.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -121,10 +121,12 @@ doPages(StoreEntry *anEntry) 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->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()); } /* diff --git a/test-suite/mem_hdr_test.cc b/test-suite/mem_hdr_test.cc index fd20230a08..c644123cdc 100644 --- a/test-suite/mem_hdr_test.cc +++ b/test-suite/mem_hdr_test.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -63,10 +63,40 @@ testLowAndHigh() assert (!aHeader.hasContigousContentRange(Range(10,101))); } +void +testSplayOfNodes() +{ + Splay 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; } diff --git a/test-suite/mem_node_test.cc b/test-suite/mem_node_test.cc index f9ce140a0e..e3fe8db6c1 100644 --- a/test-suite/mem_node_test.cc +++ b/test-suite/mem_node_test.cc @@ -1,6 +1,6 @@ /* - * $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 @@ -44,6 +44,7 @@ xassert(const char *msg, const char *file, int line) std::cout << "Assertion failed: (" << msg << ") at " << file << ":" << line << std::endl; exit (1); } + time_t squid_curtime = 0; int @@ -59,9 +60,11 @@ main (int argc, char *argv) 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)); @@ -76,5 +79,7 @@ main (int argc, char *argv) 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; } diff --git a/test-suite/splay.cc b/test-suite/splay.cc index 5a52b7dbed..cf5761f036 100644 --- a/test-suite/splay.cc +++ b/test-suite/splay.cc @@ -1,5 +1,5 @@ /* - * $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 @@ -17,12 +17,22 @@ #include #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) @@ -40,7 +50,8 @@ compareint(intnode * const &a, intnode * const &b) class SplayCheck { - public: + +public: static void BeginWalk(); static int LastValue; static bool ExpectedFail; @@ -70,13 +81,15 @@ void 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; } @@ -113,69 +126,77 @@ compareintref(intnode const &a, intnode const &b) 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 *safeTop = NULL; - for ( int i = 0; i < 100; i++) { - intnode *I; - I = new intnode; - I->i = random(); - safeTop = safeTop->insert(I, compareint); + { + /* intnode* */ + SplayNode *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 *safeTop = NULL; - for (int i = 0; i < 100; i++) { - intnode I; - I.i = random(); - safeTop = safeTop->insert(I, compareintref); + { + /* intnode */ + SplayNode *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; @@ -185,33 +206,73 @@ main(int argc, char *argv[]) I.i = 0; SplayCheck::ExpectedFail = true; SplayCheck::WalkNodeRef(I, NULL); - -{ - /* check for begin() */ - SplayNode *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 *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 aSplay; - if (aSplay.start() != NULL) - exit (1); + Splay 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; }