• Main Page
  • Classes
  • Files
  • File List
  • File Members

Beesnest/DcFileCacher.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2007 Erez Bibi (erezbibi@users.sourceforge.net)
00003 This file is part of Beesnest.
00004 
00005 Beesnest is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 Beesnest is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with Beesnest; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00020 
00021 /**
00022  * DcFilecacher.cpp: implementation of the CdcFilecacher class.
00023  * for documentation see the header file.
00024  */
00025 
00026 #include "DcFilecacher.h"
00027 
00028 
00029 CdcFileCacher::CdcFileCacher ()
00030 : nAccessCounter (0), isLimitThreadGo (true)
00031 { }
00032 
00033 CdcFileCacher::~CdcFileCacher()
00034 {
00035     /* Signal the limit thread to exit. */
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     /* Create the limiter thread. */
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     {   /* If file is in the map - lock it. */
00066         pfile->oMutex.Lock ();
00067         /* If file was not modified. */
00068         int is_true = pfile->oModifiedTime == time;
00069         if (is_true != 0)
00070         {   /* Get the data and update access number. */
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     {   /* If file is already in map - lock it. */
00089         pfile->oMutex.Lock ();
00090         /* If new file modified after existing one. */
00091         int is_true = pfile->oModifiedTime < time;
00092         if (is_true != 0)
00093         {   /* Set new data, time and access counter. */
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     {   /* Create new file. */
00103         pfile = new CdcFile (name, time, data, ++nAccessCounter);
00104         if (pfile != NULL)
00105         {   /* Insert to map. */
00106             oMap [name] = pfile;
00107             /* Signal to the limiter thread. */
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     /* Find the last accessed file in the map. */
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) /* Some bug... */
00127             return;
00128         if (min >= pfile->nAccessNumber)
00129         {
00130             min = pfile->nAccessNumber;
00131             plast_file = pfile;
00132         }
00133     }
00134     /* Lock the file. */
00135     plast_file->oMutex.Lock ();
00136     /* If file was accessed since - unlock and return. */
00137     if (plast_file->nAccessNumber == min)
00138     {   /* Remove the file from map and delete it. */
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;   /* if pParam is not valid. */
00151 
00152     while (pThis->isLimitThreadGo)
00153     {   /* Wait for event. */
00154         pThis->oStartThread.Wait ();
00155         if (pThis->isLimitThreadGo == false) return 0;
00156         /* If more file than the limit - delete the last one. */
00157         while (pThis->oMap.size () > pThis->nCacheLimit)
00158             pThis->DeleteLast ();
00159     }
00160 
00161     return 0;
00162 }

Generated on Mon Oct 11 2010 16:23:24 for Beesnest by  doxygen 1.7.2