/*****************************************************************************/
/*
                                  cache.h
*/
/*****************************************************************************/

#ifndef CACHE_H_LOADED
#define CACHE_H_LOADED 1

#include "wasd.h"
#include "file.h"

/* number of bytes in each chunk of cache memory */
#define CACHE_CHUNK_SIZE 256
#define CACHE_CONTENT_TYPE_SIZE 64

#define CACHE_EXPIRES_NONE   0xffffffff
#define CACHE_EXPIRES_DAY    0xfffffffe
#define CACHE_EXPIRES_HOUR   0xfffffffd
#define CACHE_EXPIRES_MINUTE 0xfffffffc
/* any other value will be considered literal seconds */

/**************/
/* structures */
/**************/

#pragma member_alignment __save
#pragma member_alignment

typedef struct CacheStruct FILE_CENTRY;

struct CacheStruct
{
   LIST_ENTRY  CacheListEntry;

   struct CacheStruct  *HashCollisionNextPtr,
                       *HashCollisionPrevPtr;

   BOOL  /* cache data is currently being loaded */
         DataLoading,
         /* is a permanent entry */
         EntryPermanent,
         /* cache entry has been invalidated to reclaim memory */
         EntryReclaimed,
         /* cache data is currently being revalidated */
         EntryRevalidating,
         /* data in cache is valid and can be use for requests */
         EntryValid,
         /* loaded via FILE module */
         FromFile,
         /* loaded via NET module */
         FromNet,
         /* loaded via CGI module */
         FromScript,
         /* remove allocated data buffer as soon as not in use */
         Purge,
         /* also remove cache entry */
         PurgeCompletely;

   int  /* some portion of the CGI header is contained in the cache */
        CgiHeaderLength,
        /* analogue to 'rqPathSet.CacheExpiresAfter' */
        ExpiresAfterPeriod,
        /* expires on the change of day, hour or minute */
        ExpiresAfterTime,
        /* server-tick second when the content expires */
        ExpiresTickSecond,
        /* server-tick second where it is still considered recent */
        FrequentTickSecond,
        /* the last guard period set against this entry */
        GuardSeconds,
        /* server-tick second when gaurd period expires */
        GuardTickSecond;

   unsigned short  /* file protection bitmap */
                   Protection,
                   /* file ownership UIC group number */
                   UicGroup,
                   /* file ownership UIC member number */
                   UicMember;

   unsigned long  /* length of data (file contents) at 'ContentPtr' */
                  ContentLength,
                  /* virtual block number of end-of-file */
                  EndOfFileVbn,
                  /* size of the block pointed to by 'ContentPtr' */
                  EntrySize,
                  /* first free byte in end-of-file VBN */
                  FirstFreeByte,
                  /* length of GZIP deflated data at 'GzipContentPtr' */
                  GzipContentLength,
                  /* size of the block pointed to by 'ContentPtr' */
                  GzipEntrySize,
                  /* number of times cache used */
                  HitCount,
                  /* number of times cache hit but file unmodified */
                  HitNotModifiedCount,
                  /* cache entry is in use and should not be modified */
                  InUseCount,
                  /* seconds time when last loaded */
                  LoadSeconds,
                  /* number of times the entry has been validated */
                  ValidatedCount;

   int64  /* creation quadword */
          CdtTime64,
          /* last hit quadword */
          HitTime64,
          /* when cache data loaded quadword */
          LoadTime64,
          /* last modified quadword */
          RdtTime64,
          /* last validated quadword */
          ValidateTime64;

   char  /* points to entry contents */
         *ContentPtr,
         /* points to the GZIP deflated content */
         *GzipContentPtr;

   char  /* HTTP/1.1 entity tag */
         EntityTag [CACHE_ENTITY_MAX+1],
         /* entry's MIME content type */
         ContentType [CACHE_CONTENT_TYPE_SIZE];

   /* MD5 hash of cached resource (can be path, can be file name) */
   MD5_HASH  Md5Hash;

   ODS_STRUCT  FileOds;

   /* used to buffer the function address of the content handler */
   REQUEST_AST  ContentHandlerFunction;
};

#pragma member_alignment __restore

/***********************/
/* function prototypes */
/***********************/

void CacheAcpInfoAst (REQUEST_STRUCT*);
int CacheBegin (REQUEST_STRUCT*);
void CacheEnd (REQUEST_STRUCT*);
void CacheInit ();
BOOL CacheLoadBegin (REQUEST_STRUCT*, int, char*);
int CacheLoadData (REQUEST_STRUCT*, char*, int);
BOOL CacheLoadResponse (REQUEST_STRUCT*);
void CacheLoadEnd (REQUEST_STRUCT*);
int CacheSearch (REQUEST_STRUCT*);
void CacheNext (REQUEST_STRUCT*);
void CachePurge (BOOL, int*, int*);
void CacheRemoveEntry (FILE_CENTRY*, BOOL);
void CacheReport (REQUEST_STRUCT*, BOOL);
void CacheReportEntry (REQUEST_STRUCT*, char*);
void CacheZeroCounters ();

#endif /* CACHE_H_LOADED */

/*****************************************************************************/
