Cache Prefs changes. All cache prefs are now read directly by NuCache.

git-svn-id: svn://10.0.0.236/trunk@11253 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
gagan%netscape.com
1998-09-28 20:32:40 +00:00
parent b78ff88d4e
commit 7bdf6e2c14
6 changed files with 245 additions and 38 deletions

View File

@@ -31,8 +31,7 @@
void
Cache_Init(void)
{
/* Most of the initilization gets done in the constructor for the
* nsCacheManager class. */
CACHEMGR->Init();
}
void

View File

@@ -33,6 +33,7 @@ LLIBS = \
$(DIST)\lib\libplc21.lib \
$(DIST)\lib\dbm32.lib \
$(DIST)\lib\xpcom32.lib \
$(DIST)\lib\libpref.lib \
$(NULL)
MISCDEP = $(LLIBS)
@@ -55,13 +56,12 @@ OBJS = \
.\$(OBJDIR)\nsMemStream.obj \
$(NULL)
# .\$(OBJDIR)\nsHash.obj \
LINCS = \
-I$(PUBLIC)\xpcom \
-I$(PUBLIC)\dbm \
-I$(PUBLIC)\pref \
-I..\public \
-I$(PUBLIC)\js \
-I..\public \
-I..\include \
$(NULL)

View File

@@ -38,24 +38,31 @@ static nsCacheManager TheManager;
PRUint32 NumberOfObjects(void);
nsCacheManager::nsCacheManager(): m_pFirstModule(0), m_bOffline(PR_FALSE)
nsCacheManager::nsCacheManager():
m_pFirstModule(0),
m_bOffline(PR_FALSE),
m_pPrefs(0)
{
Init();
}
nsCacheManager::~nsCacheManager()
{
if (m_pBkgThd)
if (m_pPrefs)
{
m_pBkgThd->Stop();
delete m_pBkgThd;
m_pBkgThd = 0;
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*
@@ -205,6 +212,11 @@ void
nsCacheManager::Init()
{
MonitorLocker ml(this);
//Init prefs
if (!m_pPrefs)
m_pPrefs = new nsCachePref();
if (m_pFirstModule)
delete m_pFirstModule;

View File

@@ -32,6 +32,7 @@
nsCacheModule::nsCacheModule(const PRUint32 i_size=DEFAULT_SIZE):
m_Size(i_size),
m_SizeInUse(0),
m_pEnumeration(0),
m_pNext(0),
m_Entries(0)

View File

@@ -17,17 +17,30 @@
*/
#include "nsCachePref.h"
//#include "prefapi.h"
#include "xp.h"
#include "prefapi.h"
#include "prmem.h"
#include "nsCacheManager.h"
#include "plstr.h"
static const PRUint32 MEM_CACHE_SIZE_DEFAULT = 1024*1024;
static const PRUint32 DISK_CACHE_SIZE_DEFAULT = 5*MEM_CACHE_SIZE_DEFAULT;
static const PRUint32 BKG_THREAD_SLEEP = 15*60; /*in seconds, 15 minutes */
static const PRUint32 BKG_THREAD_SLEEP = 60;//TODO- Testing 15*60; /*in seconds, 15 minutes */
static const PRUint16 BUGS_FOUND_SO_FAR = 0;
//Preferences
static const char* MEM_CACHE_PREF = "browser.cache.memory_cache_size";
static const char* DISK_CACHE_PREF = "browser.cache.disk_cache_size";
static const char* CACHE_DIR_PREF = "browser.cache.directory";
static const char* FREQ_PREF = "browser.cache.check_doc_frequency";
/* Find a bug in NU_CACHE, get these many chocolates */
static const PRUint16 CHOCOLATES_PER_BUG_FOUND = 2^BUGS_FOUND_SO_FAR;
/* TODO move this to InitNetLib */
static nsCachePref ThePrefs;
int PR_CALLBACK Cache_PrefChangedFunc(const char *pref, void *data) {
nsCachePref::GetInstance()->SetupPrefs(pref);
return PR_TRUE;
}
nsCachePref::nsCachePref(void):
m_BkgSleepTime(BKG_THREAD_SLEEP),
@@ -37,15 +50,85 @@ nsCachePref::nsCachePref(void):
m_MemCacheSize(MEM_CACHE_SIZE_DEFAULT),
m_RefreshFreq(ONCE)
{
//Read all the stuff from pref here.
//If this changes to nsPref, here is all that needs to be changed.
//PRUint32 nTemp;
//PREF_GetIntPref("browser.cache.memory_cache_size",&nTemp);
//*1024
PREF_RegisterCallback("browser.cache",Cache_PrefChangedFunc,0);
SetupPrefs(0);
}
nsCachePref::~nsCachePref()
{
if (m_DiskCacheFolder)
{
delete m_DiskCacheFolder;
m_DiskCacheFolder = 0;
}
}
//Read all the stuff from pref here.
void
nsCachePref::SetupPrefs(const char* i_Pref)
{
PRBool bSetupAll = PR_FALSE;
long nTemp;
char* tempPref=0;
if (!i_Pref)
bSetupAll = PR_TRUE;
if (bSetupAll || !PL_strcmp(i_Pref,MEM_CACHE_PREF))
{
if (PREF_OK == PREF_GetIntPref(MEM_CACHE_PREF,&nTemp))
m_MemCacheSize = 1024*nTemp;
else
m_MemCacheSize = MEM_CACHE_SIZE_DEFAULT;
}
if (bSetupAll || !PL_strcmp(i_Pref,DISK_CACHE_PREF))
{
if (PREF_OK == PREF_GetIntPref(DISK_CACHE_PREF,&nTemp))
m_DiskCacheSize = 1024*nTemp;
else
m_DiskCacheSize = DISK_CACHE_SIZE_DEFAULT;
}
if (bSetupAll || !PL_strcmp(i_Pref,FREQ_PREF))
{
if (PREF_OK == PREF_GetIntPref(FREQ_PREF,&nTemp))
{
m_RefreshFreq = (nsCachePref::Refresh)nTemp;
}
else
m_RefreshFreq = ONCE;
}
if (bSetupAll || !PL_strcmp(i_Pref,CACHE_DIR_PREF))
{
if (PREF_OK == PREF_CopyCharPref(CACHE_DIR_PREF,&tempPref))
{
PR_ASSERT(tempPref);
if (m_DiskCacheFolder)
delete m_DiskCacheFolder;
m_DiskCacheFolder = new char[PL_strlen(tempPref)+1];
if (!m_DiskCacheFolder)
{
if (tempPref)
PR_Free(tempPref);
return;
}
PL_strcpy(m_DiskCacheFolder, tempPref);
}
else //TODO set to temp folder
{
m_DiskCacheFolder = new char [1];
if (!m_DiskCacheFolder)
return;
*m_DiskCacheFolder = '\0';
}
}
if (tempPref)
PR_Free(tempPref);
}
const PRUint32
@@ -81,12 +164,13 @@ const char* nsCachePref::DiskCacheDBFilename(void)
const char* nsCachePref::DiskCacheFolder(void)
{
return 0;
return "";
}
nsCachePref* nsCachePref::GetInstance()
{
return &ThePrefs;
PR_ASSERT(nsCacheManager::GetInstance()->GetPrefs());
return nsCacheManager::GetInstance()->GetPrefs();
}
PRUint32 nsCachePref::MemCacheSize()

View File

@@ -46,15 +46,29 @@
PR_ASSERT(res); \
}
typedef struct {
struct recentlyUsedObject {
PRCList link;
nsCacheObject* cacheObject;
} recentlyUsedObject;
};
/* Find pointer to recentlyUsedObject struct
* from the list linkaged embedded in it
*/
#define OBJECT_PTR(_link) \
((recentlyUsedObject*) ((char*) (_link) - offsetof(recentlyUsedObject,link)))
//File static list of recently used cache objects
static PRCList g_RecentlyUsedList;
static char* g_FullFilename=0;
const static PRUint16 MAX_FILENAME_LEN = 512;
const static int MAX_FILENAME_LEN = 512;
// Every time we cleanup we cleanup to 75% of the max available size.
// This should ideally change to a more const number than a percentage.
// Since someone may have a bigger cache size, so we don't really want to
// be cleaning up 5 megs if some one has a 20 megs cache size.
// I will revisit this issue once the basic architecture is up and running.
#define CLEANUP_FACTOR 0.75
char* FullFilename(const char* i_Filename);
//
@@ -64,7 +78,6 @@ nsDiskModule::nsDiskModule(const PRUint32 size):
nsCacheModule(size),
m_pDB(0)
{
/* initialize the list recently used urls*/
PR_INIT_CLIST(&g_RecentlyUsedList);
}
@@ -76,15 +89,24 @@ nsDiskModule::~nsDiskModule()
(*m_pDB->close)(m_pDB);
m_pDB = 0;
}
/* Clean up the recently used list */
recentlyUsedObject* obj;
while (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList))
{
obj = (recentlyUsedObject*) PR_LIST_HEAD(&g_RecentlyUsedList);
PR_FREEIF(obj->cacheObject);
if (obj->cacheObject)
delete obj->cacheObject;
PR_REMOVE_LINK(&obj->link);
PR_DELETE(obj);
}
PR_ASSERT(PR_CLIST_IS_EMPTY(&g_RecentlyUsedList));
if (g_FullFilename)
{
delete[] g_FullFilename;
g_FullFilename = 0;
}
}
PRBool nsDiskModule::AddObject(nsCacheObject* io_pObject)
@@ -119,6 +141,8 @@ PRBool nsDiskModule::AddObject(nsCacheObject* io_pObject)
{
// if (m_Sync == EVERYTIME)
status = (*m_pDB->sync)(m_pDB, 0);
m_Entries++;
m_SizeInUse += io_pObject->Size();
}
PR_Free(key);
PR_Free(data);
@@ -129,8 +153,6 @@ PRBool nsDiskModule::AddObject(nsCacheObject* io_pObject)
PRBool nsDiskModule::Contains(nsCacheObject* io_pObject) const
{
//return Contains(io_oObject->Address());
ENSURE_INIT;
if (!m_pDB || !io_pObject)
@@ -139,7 +161,8 @@ PRBool nsDiskModule::Contains(nsCacheObject* io_pObject) const
nsCacheObject* pTemp = GetObject(io_pObject->Address());
if (pTemp)
{
io_pObject = pTemp; /*bug */
PR_ASSERT(io_pObject == pTemp);
// until I do a copyFrom function
return PR_TRUE;
}
return PR_FALSE;
@@ -167,6 +190,9 @@ PRBool nsDiskModule::Contains(const char* i_url) const
void nsDiskModule::GarbageCollect(void)
{
MonitorLocker ml(this);
ReduceSizeTo((PRUint32)(CLEANUP_FACTOR*m_Size));
// TODO
// if the recentlyusedlist has grown too big, trim some objects from there as well
}
nsCacheObject* nsDiskModule::GetObject(const PRUint32 i_index) const
@@ -181,11 +207,27 @@ nsCacheObject* nsDiskModule::GetObject(const PRUint32 i_index) const
nsCacheObject* nsDiskModule::GetObject(const char* i_url) const
{
ENSURE_INIT;
MonitorLocker ml((nsDiskModule*)this);
if (!m_pDB || !i_url || !*i_url)
return 0;
//TODO check from recently used list.
/* Check amongst recently used objects */
recentlyUsedObject* obj;
PRCList* list = &g_RecentlyUsedList;
if (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList))
{
list = g_RecentlyUsedList.next;
nsCacheObject* pObj;
while (list != &g_RecentlyUsedList)
{
obj = OBJECT_PTR(list);
pObj = obj->cacheObject;
if (0 == PL_strcasecmp(i_url, pObj->Address())) //todo also validate
return pObj;
list = list->next;
}
}
DBT key, data;
@@ -196,8 +238,9 @@ nsCacheObject* nsDiskModule::GetObject(const char* i_url) const
{
nsCacheObject* pTemp = new nsCacheObject();
pTemp->Info(data.data);
recentlyUsedObject* pNode = PR_NEW(recentlyUsedObject);
recentlyUsedObject* pNode = PR_NEWZAP(recentlyUsedObject);
PR_APPEND_LINK(&pNode->link, &g_RecentlyUsedList);
pNode->cacheObject = pTemp;
return pTemp;
}
@@ -283,20 +326,87 @@ PRBool nsDiskModule::InitDB(void)
PRBool nsDiskModule::ReduceSizeTo(const PRUint32 i_NewSize)
{
//TODO
return PR_TRUE;
return PR_FALSE; //TODO Fix this.
PRInt32 needToFree = m_SizeInUse - i_NewSize;
if (needToFree > 0)
{
PRUint32 avg = AverageSize();
if (avg==0)
return PR_FALSE;
PRUint32 nObjectsToFree = needToFree/AverageSize();
if (nObjectsToFree < 1)
nObjectsToFree = 1;
//TODO
/*
DBT key, data;
key.data = (void*) i_url;
key.size = PL_strlen(i_url);
if (0 == (*m_pDB->get)(m_pDB, &key, &data, 0))
{
nsCacheObject* pTemp = new nsCacheObject();
pTemp->Info(data.data);
recentlyUsedObject* pNode = PR_NEWZAP(recentlyUsedObject);
PR_APPEND_LINK(&pNode->link, &g_RecentlyUsedList);
pNode->cacheObject = pTemp;
return pTemp;
}
*/
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsDiskModule::Remove(const char* i_url)
{
ENSURE_INIT;
//TODO
// Also remove the file corresponding to this item.
nsCacheObject* pObject = GetObject(i_url);
if (pObject)
{
return Remove(pObject);
}
return PR_FALSE;
}
PRBool nsDiskModule::Remove(nsCacheObject* pObject)
{
MonitorLocker ml(this);
if (!pObject)
return PR_FALSE;
//PR_ASSERT(Contains(pObject);
//Remove it from the index
DBT key;
key.data = (void*) pObject->Address();
key.size = PL_strlen(pObject->Address());
if (0 == (*m_pDB->del)(m_pDB, &key, 0))
{
--m_Entries;
m_SizeInUse -= pObject->Size();
}
//Remove it from the recently used list
//TODO till done I am not removing it from here
//Remove it from the disk
//Remove file FullFilename(pObject->Filename());
//Finally delete it
//delete pObject; //Currently recentlyused will delete these.
//pObject = 0;
return PR_TRUE;
}
PRBool nsDiskModule::Remove(const PRUint32 i_index)
{
//This will probably go away.
ENSURE_INIT;
//TODO
// Also remove the file corresponding to this item.
@@ -316,7 +426,7 @@ void nsDiskModule::SetSize(const PRUint32 i_Size)
m_Size = i_Size;
if (m_Size >0)
{
ReduceSizeTo(m_Size);
ReduceSizeTo((PRUint32)(CLEANUP_FACTOR*m_Size));
}
else
{
@@ -329,6 +439,7 @@ char* FullFilename(const char* i_Filename)
if (0 == g_FullFilename)
{
g_FullFilename = new char[MAX_FILENAME_LEN];
*g_FullFilename = '\0';
if (0 == g_FullFilename)
return 0;
}