/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* * Gagan Saksena 02/02/98 * */ #include "prtypes.h" #include "prinrval.h" #include "plstr.h" #include "prprf.h" //PR_smprintf and PR_smprintf_free #include "nsCacheManager.h" #include "nsCacheTrace.h" #include "nsCachePref.h" #include "nsCacheModule.h" #include "nsMemModule.h" #include "nsDiskModule.h" #include "nsCacheBkgThd.h" /* TODO move this to InitNetLib */ static nsCacheManager TheManager; PRUint32 NumberOfObjects(void); nsCacheManager::nsCacheManager(): m_pFirstModule(0), m_bOffline(PR_FALSE), m_pPrefs(0) { } nsCacheManager::~nsCacheManager() { if (m_pPrefs) { delete m_pPrefs; m_pPrefs = 0; } if (m_pFirstModule) { delete m_pFirstModule; m_pFirstModule = 0; } if (m_pBkgThd) { m_pBkgThd->Stop(); delete m_pBkgThd; m_pBkgThd = 0; } } nsCacheManager* nsCacheManager::GetInstance() { return &TheManager; } #if 0 /* Caller must free returned char* */ const char* nsCacheManager::Trace() const { char linebuffer[128]; char* total; sprintf(linebuffer, "nsCacheManager: Modules = %d\n", Entries()); total = new char[strlen(linebuffer) + 1]; strcpy(total, linebuffer); return total; } #endif PRInt32 nsCacheManager::AddModule(nsCacheModule* pModule) { MonitorLocker ml(this); if (pModule) { if (m_pFirstModule) LastModule()->NextModule(pModule); else m_pFirstModule = pModule; return Entries()-1; } else return -1; } PRBool nsCacheManager::Contains(const char* i_url) const { MonitorLocker ml((nsMonitorable*)this); // Add logic to check for IMAP type URLs, byteranges, and search with / appended as well... // TODO PRBool bStatus = ContainsExactly(i_url); if (!bStatus) { // try alternate stuff /* char* extraBytes; char extraBytesSeparator; */ } #if !defined(NDEBUG) && defined(DEBUG_gagan) fputs(i_url, stdout); fputs(bStatus ? " is " : " is not ", stdout); fputs("in cache\n", stdout); #endif return bStatus; } PRBool nsCacheManager::ContainsExactly(const char* i_url) const { if (m_pFirstModule) { nsCacheModule* pModule = m_pFirstModule; while (pModule) { if (pModule->Contains(i_url)) { return PR_TRUE; } pModule = pModule->NextModule(); } } return PR_FALSE; } nsCacheObject* nsCacheManager::GetObj(const char* i_url) const { MonitorLocker ml((nsMonitorable*)this); if (m_pFirstModule) { nsCacheModule* pModule = m_pFirstModule; nsCacheObject* obj = 0; while (pModule) { obj = pModule->GetObject(i_url); if (obj) return obj; pModule = pModule->NextModule(); } } return 0; } PRInt16 nsCacheManager::Entries() const { MonitorLocker ml((nsMonitorable*)this); if (m_pFirstModule) { PRInt16 count=1; nsCacheModule* pModule = m_pFirstModule->NextModule(); while (pModule) { count++; pModule = pModule->NextModule(); } return count; } return 0; } nsCacheModule* nsCacheManager::GetModule(PRInt16 i_index) const { MonitorLocker ml((nsMonitorable*)this); if ((i_index < 0) || (i_index >= Entries())) return 0; nsCacheModule* pModule = m_pFirstModule; PR_ASSERT(pModule); for (PRInt16 i=0; iNextModule()) { i++; PR_ASSERT(pModule); } return pModule; } void nsCacheManager::InfoAsHTML(char* o_Buffer) const { MonitorLocker ml((nsMonitorable*)this); char* tmpBuffer =/* TODO - make this cool */ PR_smprintf("

Your cache has %d modules

\ It has a total of %d cache objects. Hang in there for the details. \0", Entries(), NumberOfObjects()); if (tmpBuffer) { PL_strncpyz(o_Buffer, tmpBuffer, PL_strlen(tmpBuffer)+1); PR_smprintf_free(tmpBuffer); } } void nsCacheManager::Init() { MonitorLocker ml(this); //Init prefs if (!m_pPrefs) m_pPrefs = new nsCachePref(); if (m_pFirstModule) delete m_pFirstModule; m_pFirstModule = new nsMemModule(nsCachePref::GetInstance()->MemCacheSize()); PR_ASSERT(m_pFirstModule); if (m_pFirstModule) { nsDiskModule* pTemp = new nsDiskModule(nsCachePref::GetInstance()->DiskCacheSize()); PR_ASSERT(pTemp); m_pFirstModule->NextModule(pTemp); m_pBkgThd = new nsCacheBkgThd(PR_SecondsToInterval(nsCachePref::GetInstance()->BkgSleepTime())); PR_ASSERT(m_pBkgThd); } } nsCacheModule* nsCacheManager::LastModule() const { MonitorLocker ml((nsMonitorable*)this); if (m_pFirstModule) { nsCacheModule* pModule = m_pFirstModule; while(pModule->NextModule()) { pModule = pModule->NextModule(); } return pModule; } return 0; } PRBool nsCacheManager::Remove(const char* i_url) { MonitorLocker ml(this); PRBool bStatus = PR_FALSE; if (m_pFirstModule) { nsCacheModule* pModule = m_pFirstModule; bStatus = pModule->Remove(i_url); if (bStatus) return bStatus; while(pModule->NextModule()) { pModule = pModule->NextModule(); bStatus = pModule->Remove(i_url); if (bStatus) return bStatus; } } return bStatus; } PRUint32 nsCacheManager::WorstCaseTime(void) const { PRIntervalTime start = PR_IntervalNow(); if (this->Contains("a vague string that should not be in any of the modules")) { PR_ASSERT(0); } return PR_IntervalToMicroseconds(PR_IntervalNow() - start); } PRUint32 NumberOfObjects(void) { PRUint32 objs = 0; int i = TheManager.Entries(); while (i>0) { objs += TheManager.GetModule(--i)->Entries(); } return objs; }