Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "DcFilecacher.h"
00027
00028
00029 CdcFileCacher::CdcFileCacher ()
00030 : nAccessCounter (0), isLimitThreadGo (true)
00031 { }
00032
00033 CdcFileCacher::~CdcFileCacher()
00034 {
00035
00036 if (nCacheLimit > 0)
00037 {
00038 isLimitThreadGo = false;
00039 oStartThread.Call ();
00040 while (oThread.IsStillActive ()) Sleep (1);
00041 }
00042 }
00043
00044 void CdcFileCacher::Init ()
00045 {
00046 nCacheLimit = CdcParameters::ToInt (CdcParameters::GetParam
00047 ("Server->Cache-Limit"));
00048
00049
00050 if (nCacheLimit > 0)
00051 {
00052 oThread.MakeThread (DcLimit, (void*) this);
00053 oThread.SetPriority (DC_TP_LOW);
00054 }
00055 }
00056
00057
00058 bool CdcFileCacher::GetFile (const CdcString& name, const CdcHttpTime& time,
00059 CdcBuffer& data)
00060 {
00061 if (nCacheLimit <= 0) return false;
00062 CdcFile* pfile = NULL;
00063 pfile = oMap [name];
00064 if (pfile != NULL)
00065 {
00066 pfile->oMutex.Lock ();
00067
00068 int is_true = pfile->oModifiedTime == time;
00069 if (is_true != 0)
00070 {
00071 data = pfile->aData;
00072 pfile->nAccessNumber = ++nAccessCounter;
00073 }
00074 pfile->oMutex.Unlock ();
00075 return is_true != 0;
00076 }
00077 return false;
00078 }
00079
00080
00081 bool CdcFileCacher::PutFile (const CdcString& name, const CdcHttpTime& time,
00082 const CdcBuffer& data)
00083 {
00084 if (nCacheLimit <= 0) return false;
00085 CdcFile* pfile = NULL;
00086 pfile = oMap [name];
00087 if (pfile != NULL)
00088 {
00089 pfile->oMutex.Lock ();
00090
00091 int is_true = pfile->oModifiedTime < time;
00092 if (is_true != 0)
00093 {
00094 pfile->aData = data;
00095 pfile->oModifiedTime = time;
00096 pfile->nAccessNumber = ++nAccessCounter;
00097 }
00098 pfile->oMutex.Unlock ();
00099 return is_true != 0;
00100 }
00101 else
00102 {
00103 pfile = new CdcFile (name, time, data, ++nAccessCounter);
00104 if (pfile != NULL)
00105 {
00106 oMap [name] = pfile;
00107
00108 oStartThread.Call ();
00109 return true;
00110 }
00111 }
00112 return false;
00113 }
00114
00115
00116 void CdcFileCacher::DeleteLast ()
00117 {
00118 unsigned int min = nAccessCounter;
00119 CdcString name;
00120 CdcFile *pfile, *plast_file;
00121
00122 for (CdcFileCacher::t_file_map::const_iterator pos = oMap.begin ();
00123 pos != oMap.end (); ++pos)
00124 {
00125 pfile = (*pos).second;
00126 if (pfile == NULL)
00127 return;
00128 if (min >= pfile->nAccessNumber)
00129 {
00130 min = pfile->nAccessNumber;
00131 plast_file = pfile;
00132 }
00133 }
00134
00135 plast_file->oMutex.Lock ();
00136
00137 if (plast_file->nAccessNumber == min)
00138 {
00139 oMap.erase (plast_file->sFileName);
00140 delete plast_file;
00141 }
00142 else
00143 plast_file->oMutex.Unlock ();
00144 }
00145
00146
00147 int DcLimit (void* pParam)
00148 {
00149 CdcFileCacher* pThis = (CdcFileCacher*)pParam;
00150 if (pThis == NULL) return 1;
00151
00152 while (pThis->isLimitThreadGo)
00153 {
00154 pThis->oStartThread.Wait ();
00155 if (pThis->isLimitThreadGo == false) return 0;
00156
00157 while (pThis->oMap.size () > pThis->nCacheLimit)
00158 pThis->DeleteLast ();
00159 }
00160
00161 return 0;
00162 }