richter 01/11/04 12:17:35
Modified: . Tag: Embperl2c epcache.c
driver Tag: Embperl2c epxalan.cpp
Log:
Embperl 2 - cache handling
Revision Changes Path
No revision
No revision
1.1.2.2 +302 -32 embperl/Attic/epcache.c
Index: epcache.c
===================================================================
RCS file: /home/cvs/embperl/Attic/epcache.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- epcache.c 2001/11/02 14:30:13 1.1.2.1
+++ epcache.c 2001/11/04 20:17:35 1.1.2.2
@@ -9,17 +9,25 @@
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
-# $Id: epcache.c,v 1.1.2.1 2001/11/02 14:30:13 richter Exp $
+# $Id: epcache.c,v 1.1.2.2 2001/11/04 20:17:35 richter Exp $
#
###################################################################################*/
+#define cache_mallaoc(r,s) malloc(s)
+#define cache_free(r,m) free(m)
+struct tProvider ;
+
+
typedef struct tCacheItem
{
- double nLastModified ; /**< time when item was last modified */
- int nExpiresInTime ; /**< time in sec when item expires, 0 =
does not expire */
+ bool bExpired ; /**< this item is expired */
+ int nLastChecked ; /**< request when this item was last
checked */
+ time_t nLastModified ; /**< time when item was last modified */
+ time_t nExpiresInTime ; /**< time in sec when item expires, 0 =
does not expire */
const char * sExpiresFilename ; /**< Item expires when mtime of
filename is different to nLastModified */
+ time_t nFileModified ; /**< time when file was last modified */
struct stat FileStat ; /**< Item expires when mtime of
filename is different to nLastModified */
CV * pExpiresCV ; /**< Perl code to call. If returns true
item expires */
int (*fExpires) (struct tCacheItem * pItem) ; /**< C code to call.
If returns true item expires */
@@ -30,39 +38,80 @@
tArray * pDependsOn ; /**< CacheItem on which this one
depends */
tArray * pNeededFor ; /**< CacheItems that need this item */
+ struct tProvider * pProvider ; /**< Provider for this cacheItem */
+
int (*fCacheItemFree) (struct tCacheItem * pItem) ; /**< Called to free
memory of associated data */
} tCacheItem ;
+
+typedef struct tProviderClass
+ {
+ const char * sOutputType ; /**< MIME type of output
format (maybe override by object) */
+ int (*fNew)(req * r, tCacheItem * pOutputCache) ; /**< called to initialize
the provider */
+ int (*fGetContent)(req * r, struct tProvider * pProvider, void ** pData, size_t
* pLen) ; /**< Get the content from that provider */
+ } tProviderClass ;
-typedef int (*fProviderNew)(req * r, tCacheItem * pOutputCache) tProviderNew ; /**<
called to initialize the provider */
/*! General provider for input */
typedef struct tProvider
{
const char * sOutputType ; /**< MIME type of output format */
- int (*fGetContent)(req * r, struct tProvider * pProvider, void ** pData, size_t
* pLen) ; /**< Get the content from that provider */
+ tCacheItem * pCache ; /**< CacheItem for this provider instance */
+ tProviderClass * pProviderClass ; /**< Provider class */
} tProvider ;
+
/*! Provider that reads input from file */
typedef struct tProviderFile
{
- tProvider Provider ; /**< Provider data */
- const char * sFilename ; /**< Filename */
- int (*fGetContent)(req * r, struct tProvider * pProvider, void ** pData, size_t
* pLen) ; /**< Get the content from that provider */
+ const char * sFilename ; /**< Filename */
} tProviderFile ;
+HV * pProviders ; /* global hash that holds all known providers classes */
+tProviderClass ProviderClassFile = { "text/*", &ProviderFile_New,
&ProviderFile_GetContent } ;
+
/* ------------------------------------------------------------------------ */
/* */
+/* Cache_Init */
+/* */
+/*!
+* \_en
+* Do global initialization of cache system
+* @return error code
+*
+* \endif
+*
+* \_de
+* F�hrt die globale Initialisierung des Cachesystems durch
+* @return Fehlercode
+*
+* \endif
+*
+* ------------------------------------------------------------------------ */
+
+int Cache_Init (void)
+
+ {
+ pProviders = newHV () ;
+
+ SetHashValueStr (pProviders, "file", &ProviderClassFile) ;
+ }
+
+
+
+/* ------------------------------------------------------------------------ */
+/* */
/* ProviderFile_New */
/* */
/*!
* \_en
* Creates a new file provider and fills it with data from the hash pParam
+* The resulting provider is put into the cache structure
*
* @param r Embperl request record
* @param pParam Parameter
@@ -70,7 +119,8 @@
* \endif
*
* \_de
-* Erzeugt einen neue Provider der daten aus Dateien lie�t
+* Erzeugt einen neue Provider der daten aus Dateien lie�t. Der ein Zeiger
+* auf den resultierenden Provider wird in die Cachestrutr eingef�gt
*
* @param r Embperl request record
* @param pParam Parameter
@@ -80,7 +130,35 @@
*
* ------------------------------------------------------------------------ */
+int ProviderFile_New (/*in*/ req * r,
+ /*in*/ tCacheItem * pItem,
+ /*in*/ HV * pParam)
+
+
+ {
+ int rc ;
+ HV * pProviderParameter ;
+ char * sProvider ;
+ tProvider * pProvider ;
+ tProviderFile * pNew = cache_malloc (r, sizeof(tProviderFile)) ;
+
+ if (!pNew)
+ return rcOutOfMemory ;
+
+ memset (pNew, 0, sizeof (tProviderFile)) ;
+
+ pNew -> Provider.pCache = pItem ;
+ pNew -> Provider.pProviderClass = pProviderClass ;
+ pNew -> Provider.sOutputType = pProviderClass -> sOutputType ;
+ pNew -> sFilename = GetHashValueStrDup (pParam, 'filename',
NULL) ;
+ pItem -> pProvider = pNew ;
+
+ return ok ;
+ }
+
+
+
/* ------------------------------------------------------------------------ */
/* */
/* ProviderFile_GetContent */
@@ -123,7 +201,7 @@
{
if ((rc = ReadHTML(r, pProvider -> sFilename, pProvider ->
Provider.FileStat.st_size, &pProvider -> Provider.pCache ->pSV)) != ok)
return rc ;
-
+ Cache_SetNotExpired (r, pItem) ;
}
*pData = SvPV(pProvider -> pCache ->pSV, nLen) ;
@@ -167,7 +245,7 @@
int rc ;
HV * pProviderParameter ;
char * sProvider ;
- tProvider * pProvider ;
+ tProviderClass * pProviderClass ;
tCacheItem * pNew = cache_malloc (r, sizeof(tCacheItem)) ;
if (!pNew)
@@ -183,8 +261,8 @@
sProvider = GetHashValueStr (pParam, 'provider', NULL) ;
if (sProvider)
{
- pProvider = GetHashValueInt (pProviders, sProvider, NULL) ;
- if (!pProvider)
+ pProviderClass = GetHashValueInt (pProviders, sProvider, NULL) ;
+ if (!pProviderClass)
{
cache_free (r, pNew) ;
strncpy (r -> errdat1, sProvider, sizeof(r -> errdat1) - 1) ;
@@ -192,7 +270,7 @@
}
pProviderParam = GetHashValueSV (pParam, 'param', NULL) ;
- if ((rc = (*pProvider -> fNew)(pNew, pProviderParam)) != ok)
+ if ((rc = (*pProvider -> fNew)(pNew, pProviderClass, pProviderParam)) != ok)
{
cache_free (r, pNew) ;
return rc ;
@@ -206,40 +284,37 @@
}
-
/* ------------------------------------------------------------------------ */
/* */
-/* Cache_NewFile */
+/* Cache_GetByFileKey */
/* */
/*!
* \_en
-* Creates a CacheItem for a file. Items expires when file changes
+* Gets an CacheItem by it's key. First key is considered a filename
+* an the current work direcory is appended, if the filename is relative
+* to make sure it is unique
*
* @param r Embperl request record
-* @param sFilename Filename
-* @return 0 on success
+* @param sFilename filename
+* @param sModifier modifier
+* @return errorcode, 0 on success
* \endif
*
* \_de
-* Erzeugt ein CacheItem f�r eine Datei. Das Item l�uft ab wenn sich die
-* Datei �ndert
+* Liefert das durch den Schl�ssel angegeben CacheItem zur�ck. Der Schl�ssel
+* setzt sich aus einem Dateinamen und einem Modifier zusammen. Ist der
+* Dateiname relativ, wird das aktuelle Verzeichnis angehangen um ihn
+* eindeutig zu machen.
*
* @param r Embperl request record
-* @param pItem CacheItem welches von pDependsOn anh�ngt
-* @param pDependsOn CacheItem von welchem pItem abh�ngt
-* @return 0 wenn fehlerfrei ausgef�hrt
+* @param sFilename Dateiname
+* @param sModifier modifier
+* @return Fehlercode, 0 wenn fehlerfrei ausgef�hrt
* \endif
*
* ------------------------------------------------------------------------ */
+Cache_GetByFileKey
-
-
-
-int Cache_AddDependency (/*in*/ req * r,
- /*in*/ tCacheItem * pItem,
- /*in*/ tCacheItem * pDependsOn)
-
-
/* ------------------------------------------------------------------------ */
/* */
/* Cache_AddDependency */
@@ -290,4 +365,199 @@
return ok ;
}
+
+
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Cache_IsExpired */
+/* */
+/*!
+* \_en
+* Checks if the cache item or a cache item on which this one depends is
+* expired
+*
+* @param r Embperl request record
+* @param pItem CacheItem which should be checked
+* @return true if expired, otherwise false
+* \endif
+*
+* \_de
+* Pr�ft ob das CacheItem oder eines von welchem dieses abh�ngt nihct
+* mehr g�ltig ist
+*
+* @param r Embperl request record
+* @param pItem CacheItem welches �berpr�ft werden soll
+* @return wahr wenn ung�ltig, ansonsten falsch
+* \endif
+*
+* ------------------------------------------------------------------------ */
+
+
+
+
+int Cache_IsExpired (/*in*/ req * r,
+ /*in*/ tCacheItem * pItem)
+
+
+ {
+ int rc ;
+ tCacheItem * pSubItem ;
+ int n ;
+ int numItems = ArrayGetSize (pItem -> pDependsOn) ;
+
+ if (pItem -> bExpired || pItem -> nLastChecked == r -> nRequestCount)
+ return pItem -> bExpired ; /* we already have checked this or know that is it
expired */
+
+ pItem -> nLastChecked = r -> nRequestCount ;
+
+ /* first check dependency */
+ for (i = 0; i < numItems; i++)
+ {
+ pSubItem = pItem -> pDependsOn[i] ;
+ if (Cache_IsExpired (r, pSubItem))
+ return pItem -> bExpired = true ;
+ }
+
+ if (pItem -> nExpiresInTime && pItem -> nLastModified + pItem -> nExpiresInTime
< r -> nRequestTime)
+ {
+ if (r -> bDebug & dbgCache)
+ lprintf (r, "[%d]CACHE: Expired because of timeout (%d sec)\n", r ->
nPid, pItem -> nExpiresInTime) ;
+ return pItem -> bExpired = true ;
+ }
+
+ if (pItem -> sExpiresFilename)
+ {
+ if (stat (pItem -> sExpiresFilename, &pItem -> FileStat))
+ {
+ if (r -> bDebug & dbgCache)
+ lprintf (r, "[%d]CACHE: Expired because cannot stat file %s\n", r
-> nPid, pItem -> sExpiresFilename) ;
+ return pItem -> bExpired = true ;
+ }
+
+ if (pItem -> nFileModified != pItem -> FileStat.st_mtime)
+ {
+ if (r -> bDebug & dbgCache)
+ lprintf (r, "[%d]CACHE: Expired because file %s changed\n", r ->
nPid, pItem -> sExpiresFilename) ;
+ pItem -> nFileModified = pItem -> FileStat.st_mtime ;
+ return pItem -> bExpired = true ;
+ }
+ }
+
+
+ if (pItem -> pExpiresCV)
+ {
+ SV * pRet ;
+
+ if ((rc = CallCV (r, "Expired?", pExpiresCV, 0, &pRet)) != ok)
+ {
+ LogError (r, rc) ;
+ return pItem -> bExpired = true ;
+ }
+
+ if (pRet && SvTRUE(pRet))
+ { /* Expire the entry */
+ if (r -> bDebug & dbgCache)
+ lprintf (r, "[%d]CACHE: Expired because expirey Perl sub returned
TRUE\n", r -> nPid) ;
+ return pItem -> bExpired = true ;
+ }
+ }
+
+ if (pItem -> fExpires)
+ {
+ if ((*pItem -> fExpires)(pItem))
+ {
+ if (r -> bDebug & dbgCache)
+ lprintf (r, "[%d]CACHE: Expired because expirey C sub returned
TRUE\n", r -> nPid) ;
+ return pItem -> bExpired = true ;
+ }
+ }
+
+ return false ;
+ }
+
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Cache_SetNotExpired */
+/* */
+/*!
+* \_en
+* Reset expired flag and last modification time
+*
+* @param r Embperl request record
+* @param pItem CacheItem which should be checked
+* @return true if expired, otherwise false
+* \endif
+*
+* \_de
+* Abgelaufen Flag zur�cksetzen und Zeitpunkt der letzten �nderung setzen
+*
+* @param r Embperl request record
+* @param pItem CacheItem welches �berpr�ft werden soll
+* @return wahr wenn ung�ltig, ansonsten falsch
+* \endif
+*
+* ------------------------------------------------------------------------ */
+
+
+int Cache_SetNotExpired (/*in*/ req * r,
+ /*in*/ tCacheItem * pItem)
+
+ {
+ pItem -> nLastChecked = r -> nRequestCount ;
+ pItem -> nLastModified = r -> nRequestTime ;
+ pItem -> bExpired = false ;
+ }
+
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Cache_GetContent */
+/* */
+/*!
+* \_en
+* Get the whole content, if not expired from the cache, otherwise ask
+* the provider to fetch it.
+*
+* @param r Embperl request record
+* @param pItem CacheItem which should be checked
+* @param pData Returns the content
+* @param pLen Returns the length
+* @return error code
+* \endif
+*
+* \_de
+* Holt den gesamt Inhalt soweit nich abgelaufen aus dem Cache, ansonsten
+* wird der Provider beauftragt ihn einzulesen.
+*
+* @param r Embperl request record
+* @param pItem CacheItem welches �berpr�ft werden soll
+* @param pData Liefert den Inhalt
+* @param pLen Liefert die L�nge
+* @return Fehlercode
+* \endif
+*
+* ------------------------------------------------------------------------ */
+
+
+
+int Cache_GetContent (/*in*/ req * r,
+ /*in*/ tCacheItem *pItem,
+ /*in*/ void * * pData,
+ /*in*/ int * * pLen)
+
+ {
+
+ if (Cache_IsExpired (pItem))
+ {
+ if ((rc = (*pItem -> pProvider -> pProviderClass -> fGetContent (r, pItem
-> pProvider, pData, pLen))) != ok)
+ return rc ;
+ Cache_SetNotExpired (r, pItem) ;
+ }
+
+ *pData = SvPV(pItem -> pSV, nLen) ;
+ return ok ;
+ }
+
No revision
No revision
1.1.2.4 +19 -2 embperl/driver/Attic/epxalan.cpp
Index: epxalan.cpp
===================================================================
RCS file: /home/cvs/embperl/driver/Attic/epxalan.cpp,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- epxalan.cpp 2001/09/20 08:23:56 1.1.2.3
+++ epxalan.cpp 2001/11/04 20:17:35 1.1.2.4
@@ -10,7 +10,7 @@
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
-# $Id: epxalan.cpp,v 1.1.2.3 2001/09/20 08:23:56 richter Exp $
+# $Id: epxalan.cpp,v 1.1.2.4 2001/11/04 20:17:35 richter Exp $
#
###################################################################################*/
@@ -169,8 +169,25 @@
p = SvPV (pSource, len) ;
istrstream theXMLStream(p, len);
+
+ /*
+ XalanCompiledStylesheet* compiledStylesheet = 0;
+ compiledStylesheet = theXalanTransformer.compileStylesheet("foo.xsl");
+ assert(compiledStylesheet!=0);
+ theXalanTransformer.transform("foo1.xml", *compiledStylesheet, "foo1.out.");
+ */
+
+ pFileCache = Cache_GetByKey (r, sStylesheet, NULL) ;
+ tCacheItem * pXSLCache = Cache_GetByFileKey (r, sStylesheet, "Xalan-CXSL") ;
+ XalanCompiledStylesheet * pCompiledXSL ;
+
+ if ((rc = Cache_GetContent (r, pXSLCache, &pCompiledXSL, &l)) != ok)
+ return rc ;
+
+
+
// Do the transform.
- int theResult = theXalanTransformer.transform(&theXMLStream, sStylesheet, r,
iowrite, NULL);
+ int theResult = theXalanTransformer.transform(&theXMLStream, *pCompiledXSL, r,
iowrite, NULL);
if(theResult != 0)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]