]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Summary: Convert mem_hdr to the use of a splay.
authorrobertc <>
Thu, 26 Jun 2003 18:51:57 +0000 (18:51 +0000)
committerrobertc <>
Thu, 26 Jun 2003 18:51:57 +0000 (18:51 +0000)
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.

include/splay.h
src/MemObject.cc
src/mem_node.cc
src/mem_node.h
src/stmem.cc
src/stmem.h
src/store.cc
src/store_swapout.cc
test-suite/mem_hdr_test.cc
test-suite/mem_node_test.cc
test-suite/splay.cc

index 5b3fde814859a0dc0bbef293b663c18cca9ae47c..433c31b315f32975e26011e43c10659d5d4cbfe2 100644 (file)
@@ -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 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;
 };
 
@@ -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<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>
@@ -89,7 +126,18 @@ SplayNode<V> const *
 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;
 }
 
@@ -98,35 +146,45 @@ void
 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 */
 }
 
@@ -137,27 +195,29 @@ SplayNode<V>::insert(Value dataToInsert, SPLAYCMP * compare)
     /* 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;
     }
 }
 
@@ -166,10 +226,11 @@ SplayNode<V> *
 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;
@@ -178,40 +239,49 @@ SplayNode<V>::splay(Value const &dataToFind, SPLAYCMP * compare) const
     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;
@@ -224,8 +294,10 @@ typename Splay<V>::Value const *
 Splay<V>::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<V>::insert(Value const &value, SPLAYCMP *compare)
 
 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 */
index 73fa2cd752cc7284675aa08d248c15edb877c84d..6f05663826940f1b3924eb2d23c4c2b14901394f 100644 (file)
@@ -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",
index 561d834816a5cf7cfa0282306a13d040d0787555..88cea9203f5673fb727effd314c820f9ad06b905 100644 (file)
@@ -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<size_t>
+mem_node::dataRange() const
+{
+    return Range<size_t> (start(), end());
+}
+
 size_t
 mem_node::space() const
 {
index 96673e3b9b28670e21a6ba8e4eba50a0c77038b9..bd47f181e290c8f097be17080d76ac48e0f108dc 100644 (file)
@@ -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<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];
 
index c0068f623fd886117ebfed5764dfe056e1001d8f..f44d6f6f8a5570e4561e675b0912de56a3c41b31 100644 (file)
@@ -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 <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;
 }
@@ -51,9 +54,10 @@ off_t
 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);
 
@@ -63,22 +67,15 @@ mem_hdr::endOffset () const
 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
@@ -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<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);
 
@@ -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<size_t> 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<mem_node *> * result = nodes.start();
+
+    if (result)
+        return result->data;
+
+    return NULL;
+}
index 89f398b53c7e9b87e8b4f6d9df8078097a3473b7..b47fff8a2938bfa27e775574d21899f9017fc5ff 100644 (file)
@@ -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 <robertc@squid-cache.org>
  */
 
 #ifndef SQUID_STMEM_H
@@ -55,25 +56,28 @@ public:
     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 */
index 7618a27d35bdefa22329fe8478510af0c2911526..33664766ce913e3e0265d1cd16487b1318f16380 100644 (file)
@@ -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;
index 3aafaa23e89852da8624bc4115a6ec86152c9a49..943901a20f51d76a14e249f982178bf4b4747d98 100644 (file)
@@ -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_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());
         }
 
         /*
index fd20230a0827efe7745fe7ac30da0792f9d5458b..c644123cdc53f6c7ee04d20b2cffb24551acce11 100644 (file)
@@ -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<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;
 }
index f9ce140a0e7fab60b6c62b0fce5ee4481ce4360f..e3fe8db6c19bc5a28b115d83edc5c2365ae15c1e 100644 (file)
@@ -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;
 }
index 5a52b7dbed1842ad38c070f424fd5143a616df90..cf5761f036cff627f757961b1343062a7747b2ea 100644 (file)
@@ -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
 #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)
@@ -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<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;
@@ -185,33 +206,73 @@ main(int argc, char *argv[])
     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;
 }