--------------------- PatchSet 471 Date: 2002/12/24 09:04:02 Author: rbcollins Branch: esi Tag: (none) Log: initial cache use Members: src/ESI.cc:1.1.2.76->1.1.2.77 src/ESIContext.cc:1.1.2.4->1.1.2.5 src/ESIContext.h:1.1.2.4->1.1.2.5 src/ESIElement.h:1.1.2.9->1.1.2.10 Index: squid3/src/ESI.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ESI.cc,v retrieving revision 1.1.2.76 retrieving revision 1.1.2.77 diff -u -r1.1.2.76 -r1.1.2.77 --- squid3/src/ESI.cc 24 Dec 2002 04:21:23 -0000 1.1.2.76 +++ squid3/src/ESI.cc 24 Dec 2002 09:04:02 -0000 1.1.2.77 @@ -1,6 +1,6 @@ /* - * $Id: ESI.cc,v 1.1.2.76 2002/12/24 04:21:23 rbcollins Exp $ + * $Id: ESI.cc,v 1.1.2.77 2002/12/24 09:04:02 rbcollins Exp $ * * DEBUG: section 86 ESI processing * AUTHOR: Robert Collins @@ -188,6 +188,7 @@ ~esiComment(); esiComment(); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; void render(ESISegment::Pointer); void finish(); @@ -209,6 +210,7 @@ void render(ESISegment::Pointer); esiProcessResult_t process (int dovars); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; /* optimise copies away later */ ESISegment::Pointer buffer; struct { @@ -239,7 +241,10 @@ bool mayFail () const; void wontFail(); void fail(ESIElement *); + void makeCachableElements(esiSequence const &old); Pointer makeCacheable() const; + void makeUsableElements(esiSequence const &old, esiVarState &); + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; ESIElement::Pointer * elements; /* unprocessed or rendered nodes */ int allocedcount; @@ -276,6 +281,7 @@ void render(ESISegment::Pointer); esiProcessResult_t process (int dovars); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; void subRequestDone (esiStreamContext *, bool); struct { int onerrorcontinue:1; /* on error return zero data */ @@ -312,6 +318,7 @@ void render(ESISegment::Pointer); bool addElement (ESIElement::Pointer); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; void finish(); }; CBDATA_TYPE (esiRemove); @@ -349,6 +356,7 @@ esiProcessResult_t process (int dovars); void provideData (ESISegment::Pointer data, ESIElement * source); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; ESIElement::Pointer attempt; ESIElement::Pointer except; @@ -394,6 +402,7 @@ void provideData (ESISegment::Pointer data, ESIElement *source); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; void NULLElements (int start, int end); void NULLUnChosen(); @@ -421,6 +430,7 @@ esiWhen(esiTreeParentPtr aParent, int attributes, const char **attr, esiVarState *); ~esiWhen(); Pointer makeCacheable() const; + Pointer makeUsable(esiTreeParentPtr, esiVarState &) const; bool testsTrue() const { return testValue;} void setTestResult(bool aBool) {testValue = aBool;} @@ -664,7 +674,8 @@ /* Nothing to send */ - if (context->flags.oktosend && context->flags.finishedtemplate && + if (context->flags.oktosend && (context->flags.finishedtemplate + || context->cachedASTInUse) && ! context->flags.finished) { /* we've started sending, finished reading, but not finished * processing. stop here, a callback will resume the stream @@ -928,6 +939,7 @@ /* once we finish the template, we *cannot* return here */ assert (!context->flags.finishedtemplate); + assert (!context->cachedASTInUse); /* Can we generate any data ?*/ @@ -1003,7 +1015,8 @@ /* ok.. no data sent, try to pull more data in from upstream. * FIXME: Don't try thisNode if we have finished reading the template */ - if (!context->flags.finishedtemplate && !context->reading()) { + if (!context->flags.finishedtemplate && !context->reading() + && !context->cachedASTInUse) { StoreIOBuffer tempBuffer = EMPTYIOBUFFER; assert (context->incoming.getRaw() && context->incoming->len < HTTP_REQBUF_SZ); tempBuffer.offset = context->readpos; @@ -1431,7 +1444,10 @@ assert (!flags.error); - parse(); + if (!hasCachedAST()) + parse(); + else + getCachedAST(); if (flags.error) { debug (86,5) ("ESIContext::process: Parsing failed\n"); @@ -1440,16 +1456,16 @@ return ESI_PROCESS_FAILED; } - if (!flags.finishedtemplate && !incoming.getRaw()) { + if (!flags.finishedtemplate && !incoming.getRaw() && !cachedASTInUse) { buffered = new ESISegment; incoming = buffered; } - if (!flags.finishedtemplate) { + if (!flags.finishedtemplate && !cachedASTInUse) { return ESI_PROCESS_PENDING_MAYFAIL; } - assert (flags.finishedtemplate); + assert (flags.finishedtemplate || cachedASTInUse); updateCachedAST(); /* ok, we've done all we can with the data. What can we process now? */ @@ -1476,7 +1492,7 @@ return ESI_PROCESS_FAILED; break; } - if (status != ESI_PROCESS_PENDING_MAYFAIL && flags.finishedtemplate){ + if (status != ESI_PROCESS_PENDING_MAYFAIL && (flags.finishedtemplate || cachedASTInUse)){ /* We've read the entire template, and no nodes will * return failure */ @@ -1484,7 +1500,8 @@ flags.oktosend = 1; } - if (status == ESI_PROCESS_COMPLETE && flags.finishedtemplate) { + if (status == ESI_PROCESS_COMPLETE + && (flags.finishedtemplate || cachedASTInUse)) { /* we've finished all processing. Render and send. */ debug (86,5)("esiProcess, processing complete\n"); flags.finished = 1; @@ -1797,6 +1814,13 @@ return NULL; } +ESIElement::Pointer +esiComment::makeUsable(esiTreeParentPtr, esiVarState &) const +{ + fatal ("esiComment::Usable: unreachable code!\n"); + return NULL; +} + /* esiLiteral */ void * esiLiteral::operator new(size_t byteCount) @@ -1903,6 +1927,15 @@ return new esiLiteral (*this); } +ESIElement::Pointer +esiLiteral::makeUsable(esiTreeParentPtr , esiVarState &newVarState) const +{ + debug (86,5)("esiLiteral::makeUsable: Creating usable literal\n"); + esiLiteral * result = new esiLiteral (*this); + result->varState = cbdataReference (&newVarState); + return result; +} + /* esiSequence */ void esiSequence::deleteSelf() const @@ -2162,7 +2195,11 @@ elementcount = 0; allocedcount = 0; allocedsize = 0; +} +void +esiSequence::makeCachableElements(esiSequence const &old) +{ for (int counter = 0; counter < old.elementcount; ++counter) { ESIElement::Pointer newElement = old.elements[counter]->makeCacheable(); if (newElement.getRaw()) @@ -2170,6 +2207,16 @@ } } +void +esiSequence::makeUsableElements(esiSequence const &old, esiVarState &newVarState) +{ + for (int counter = 0; counter < old.elementcount; ++counter) { + ESIElement::Pointer newElement = old.elements[counter]->makeUsable (parent, newVarState); + if (newElement.getRaw()) + assert (addElement(newElement)); + } +} + ESIElement::Pointer esiSequence::makeCacheable() const { @@ -2180,11 +2227,30 @@ debug (86,5)("esiSequence::makeCacheable: No elements in sequence %p, returning NULL\n", this); return NULL; } - ESIElement::Pointer result = new esiSequence (*this); + esiSequence * resultS = new esiSequence (*this); + ESIElement::Pointer result = resultS; + resultS->makeCachableElements(*this); debug (86,5)("esiSequence::makeCacheable: %p created %p\n", this, result.getRaw()); return result; } +ESIElement::Pointer +esiSequence::makeUsable(esiTreeParentPtr newParent, esiVarState &newVarState) const +{ + debug (86,5)("esiSequence::makeUsable: Creating usable Sequence\n"); + assert (processedcount == 0); + assert (!failed); + if (elementcount == 0) { + debug (86,5)("esiSequence::makeUsable: No elements in sequence %p, returning NULL\n", this); + return NULL; + } + esiSequence * resultS = new esiSequence (*this); + ESIElement::Pointer result = resultS; + resultS->parent = newParent; + resultS->makeUsableElements(*this, newVarState); + return result; +} + /* esiInclude */ esiInclude::~esiInclude() { @@ -2229,6 +2295,13 @@ return new esiInclude (*this); } +ESIElement::Pointer +esiInclude::makeUsable(esiTreeParentPtr newParent, esiVarState &newVarState) const +{ + assert (0); + return NULL; +} + esiInclude::esiInclude(esiInclude const &old) : parent (NULL), started (false), sent (false) { context = NULL; @@ -2527,6 +2600,13 @@ return NULL; } +ESIElement::Pointer +esiRemove::makeUsable(esiTreeParentPtr, esiVarState &) const +{ + fatal ("esiRemove::Usable: unreachable code!\n"); + return NULL; +} + /* esiTry */ esiTry::~esiTry() { @@ -2716,8 +2796,8 @@ esiTry::esiTry(esiTry const &old) { - attempt = old.attempt.getRaw() ? old.attempt->makeCacheable() : NULL; - except = old.except.getRaw() ? old.except->makeCacheable() : NULL; + attempt = NULL; + except = NULL; flags.attemptok = 0; flags.exceptok = 0; flags.attemptfailed = 0; @@ -2730,7 +2810,31 @@ esiTry::makeCacheable() const { debug (86,5)("esiTry::makeCacheable: making cachable Try from %p\n",this); - return new esiTry (*this); + esiTry *resultT = new esiTry (*this); + ESIElement::Pointer result = resultT; + + if (attempt.getRaw()) + resultT->attempt = attempt->makeCacheable(); + if (except.getRaw()) + resultT->except = except->makeCacheable(); + + return result; +} + +ESIElement::Pointer +esiTry::makeUsable(esiTreeParentPtr newParent, esiVarState &newVarState) const +{ + debug (86,5)("esiTry::makeUsable: making usable Try from %p\n",this); + esiTry *resultT = new esiTry (*this); + ESIElement::Pointer result = resultT; + + resultT->parent = newParent; + if (attempt.getRaw()) + resultT->attempt = attempt->makeUsable(newParent, newVarState); + if (except.getRaw()) + resultT->except = except->makeUsable(newParent, newVarState); + + return result; } void @@ -3565,6 +3669,13 @@ return new esiChoose (*this); } +ESIElement::Pointer +esiChoose::makeUsable(esiTreeParentPtr newParent, esiVarState &newVarState) const +{ + assert (0); + return NULL; +} + /* esiWhen */ void * esiWhen::operator new(size_t byteCount) @@ -3649,6 +3760,13 @@ return new esiWhen(*this); } +ESIElement::Pointer +esiWhen::makeUsable(esiTreeParentPtr newParent, esiVarState &newVarState) const +{ + assert (0); + return NULL; +} + /* esiOtherwise */ #if 0 void * Index: squid3/src/ESIContext.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ESIContext.cc,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid3/src/ESIContext.cc 24 Dec 2002 04:21:23 -0000 1.1.2.4 +++ squid3/src/ESIContext.cc 24 Dec 2002 09:04:02 -0000 1.1.2.5 @@ -1,6 +1,6 @@ /* - * $Id: ESIContext.cc,v 1.1.2.4 2002/12/24 04:21:23 rbcollins Exp $ + * $Id: ESIContext.cc,v 1.1.2.5 2002/12/24 09:04:02 rbcollins Exp $ * * DEBUG: section 86 ESI processing * AUTHOR: Robert Collins @@ -43,7 +43,7 @@ { assert (http); assert (http->entry); - if (http->entry->cachedESITree.getRaw()) { + if (hasCachedAST()) { debug (86,5)("ESIContext::updateCachedAST: not updating AST cache for entry %p from ESI Context %p as there is already a cached AST.\n", http->entry, this); return; } @@ -56,3 +56,28 @@ treeToCache = NULL; } +bool +ESIContext::hasCachedAST() const +{ + assert (http); + assert (http->entry); + if (http->entry->cachedESITree.getRaw()) { + debug (86,5)("ESIContext::hasCachedAST: %p - Cached AST present in store entry %p.\n", this, http->entry); + return true; + } else { + debug (86,5)("ESIContext::hasCachedAST: %p - Cached AST not present in store entry %p.\n", this, http->entry); + return false; + } +} + +void +ESIContext::getCachedAST() +{ + if (cachedASTInUse) + return; + assert (hasCachedAST()); + assert (varState); + parserState.popAll(); + tree = http->entry->cachedESITree->makeUsable (this, *varState); + cachedASTInUse = true; +} Index: squid3/src/ESIContext.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ESIContext.h,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid3/src/ESIContext.h 23 Dec 2002 23:17:49 -0000 1.1.2.4 +++ squid3/src/ESIContext.h 24 Dec 2002 09:04:02 -0000 1.1.2.5 @@ -1,5 +1,5 @@ /* - * $Id: ESIContext.h,v 1.1.2.4 2002/12/23 23:17:49 rbcollins Exp $ + * $Id: ESIContext.h,v 1.1.2.5 2002/12/24 09:04:02 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -121,6 +121,7 @@ esiKick_t kick (); RefCount cbdataLocker; bool failed() const {return flags.error != 0;} + bool cachedASTInUse; private: CBDATA_CLASS(ESIContext); void fail (); @@ -134,5 +135,7 @@ void parse(); void parseOneBuffer(); void updateCachedAST(); + bool hasCachedAST() const; + void getCachedAST(); }; #endif /* SQUID_ESICONTEXT_H */ Index: squid3/src/ESIElement.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/ESIElement.h,v retrieving revision 1.1.2.9 retrieving revision 1.1.2.10 diff -u -r1.1.2.9 -r1.1.2.10 --- squid3/src/ESIElement.h 23 Dec 2002 23:17:49 -0000 1.1.2.9 +++ squid3/src/ESIElement.h 24 Dec 2002 09:04:02 -0000 1.1.2.10 @@ -1,5 +1,5 @@ /* - * $Id: ESIElement.h,v 1.1.2.9 2002/12/23 23:17:49 rbcollins Exp $ + * $Id: ESIElement.h,v 1.1.2.10 2002/12/24 09:04:02 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -56,6 +56,8 @@ typedef RefCount esiTreeParentPtr; +class esiVarState; + struct ESIElement : public esiTreeParent { typedef RefCount Pointer; virtual bool addElement(ESIElement::Pointer) { @@ -76,6 +78,7 @@ } virtual Pointer makeCacheable() const = 0; + virtual Pointer makeUsable(esiTreeParentPtr, esiVarState &) const = 0; /* The top level no longer needs this element */ virtual void finish() = 0;