Fix bug 105344 "Memory cache should be based on amount of physical RAM"

This allows the cache to use a lot more memory than previously.
r=saari, sr=darin.
This commit is contained in:
gordon%netscape.com 2003-04-23 05:15:48 +00:00
Родитель fe2d32fd4e
Коммит c1c3cb1197
3 изменённых файлов: 242 добавлений и 116 удалений

346
netwerk/cache/src/nsCacheService.cpp поставляемый
Просмотреть файл

@ -58,9 +58,15 @@
#define DISK_CACHE_ENABLE_PREF "browser.cache.disk.enable" #define DISK_CACHE_ENABLE_PREF "browser.cache.disk.enable"
#define DISK_CACHE_DIR_PREF "browser.cache.disk.parent_directory" #define DISK_CACHE_DIR_PREF "browser.cache.disk.parent_directory"
#define DISK_CACHE_CAPACITY_PREF "browser.cache.disk.capacity" #define DISK_CACHE_CAPACITY_PREF "browser.cache.disk.capacity"
#define DISK_CACHE_MAX_ENTRY_SIZE_PREF "browser.cache.disk.max_entry_size"
#define DISK_CACHE_CAPACITY 51200
#define MEMORY_CACHE_ENABLE_PREF "browser.cache.memory.enable" #define MEMORY_CACHE_ENABLE_PREF "browser.cache.memory.enable"
#define MEMORY_CACHE_CAPACITY_PREF "browser.cache.memory.capacity" #define MEMORY_CACHE_CAPACITY_PREF "browser.cache.memory.capacity"
#define MEMORY_CACHE_MAX_ENTRY_SIZE_PREF "browser.cache.memory.max_entry_size"
#define MEMORY_CACHE_CAPACITY 4096
#define BROWSER_CACHE_MEMORY_CAPACITY 4096
class nsCacheProfilePrefObserver : public nsIObserver class nsCacheProfilePrefObserver : public nsIObserver
@ -74,7 +80,7 @@ public:
, mDiskCacheEnabled(PR_FALSE) , mDiskCacheEnabled(PR_FALSE)
, mDiskCacheCapacity(0) , mDiskCacheCapacity(0)
, mMemoryCacheEnabled(PR_TRUE) , mMemoryCacheEnabled(PR_TRUE)
, mMemoryCacheCapacity(4 * 1024 * 1024) , mMemoryCacheCapacity(-1)
{ {
} }
@ -128,34 +134,36 @@ nsCacheProfilePrefObserver::Install()
// install preferences observer // install preferences observer
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (NS_FAILED(rv)) return rv; if (!prefs) return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(prefService, &rv); nsCOMPtr<nsIPrefBranchInternal> branch = do_QueryInterface(prefs);
if (NS_FAILED(rv)) return rv; if (!branch) return NS_ERROR_FAILURE;
rv = prefInternal->AddObserver(MEMORY_CACHE_ENABLE_PREF, this, PR_FALSE); char * prefList[] = {
if (NS_FAILED(rv)) rv2 = rv; DISK_CACHE_ENABLE_PREF,
DISK_CACHE_CAPACITY_PREF,
DISK_CACHE_DIR_PREF,
MEMORY_CACHE_ENABLE_PREF,
MEMORY_CACHE_CAPACITY_PREF
};
int listCount = NS_ARRAY_LENGTH(prefList);
for (int i=0; i<listCount; i++) {
rv = branch->AddObserver(prefList[i], this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
}
// Determine if we have a profile already
// Install() is called *after* the profile-after-change notification
// when there is only a single profile, or it is specified on the
// commandline at startup.
// In that case, we detect the presence of a profile by the existence
// of the NS_APP_USER_PROFILE_50_DIR directory.
rv = prefInternal->AddObserver(DISK_CACHE_ENABLE_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(DISK_CACHE_DIR_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(DISK_CACHE_CAPACITY_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(MEMORY_CACHE_CAPACITY_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
// determine if we have a profile already
// if there is only a single profile, or it is specified on the commandline
// at startup, our Install() method won't be called until after the
// profile-after-change notification. In that case we detect the presence of
// a profile by the existence of the NS_APP_USER_PROFILE_50_DIR.
nsCOMPtr<nsIFile> directory; nsCOMPtr<nsIFile> directory;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(directory)); rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(directory));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mHaveProfile = PR_TRUE; mHaveProfile = PR_TRUE;
} }
@ -216,76 +224,76 @@ nsCacheProfilePrefObserver::Remove()
NS_IMETHODIMP NS_IMETHODIMP
nsCacheProfilePrefObserver::Observe(nsISupports * subject, nsCacheProfilePrefObserver::Observe(nsISupports * subject,
const char * topic, const char * topic,
const PRUnichar * data) const PRUnichar * data_unicode)
{ {
#ifdef DEBUG
printf("### nsCacheProfilePrefObserver::Observe [topic=%s data=%s]\n", topic,
NS_ConvertUCS2toUTF8(data).get());
#endif
nsresult rv; nsresult rv;
if (!nsCRT::strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) { NS_ConvertUCS2toUTF8 data(data_unicode);
CACHE_LOG_ALWAYS(("Observe [topic=%s data=%s]\n", topic, data.get()));
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) {
// xpcom going away, shutdown cache service // xpcom going away, shutdown cache service
if (nsCacheService::GlobalInstance()) if (nsCacheService::GlobalInstance())
nsCacheService::GlobalInstance()->Shutdown(); nsCacheService::GlobalInstance()->Shutdown();
} else if (!nsCRT::strcmp("profile-before-change", topic)) { } else if (!strcmp("profile-before-change", topic)) {
// profile before change // profile before change
mHaveProfile = PR_FALSE; mHaveProfile = PR_FALSE;
// XXX shutdown devices // XXX shutdown devices
nsCacheService::OnProfileShutdown(!nsCRT::strcmp("shutdown-cleanse", NS_ConvertUCS2toUTF8(data).get())); nsCacheService::OnProfileShutdown(!strcmp("shutdown-cleanse",
data.get()));
} else if (!nsCRT::strcmp("profile-after-change", topic)) { } else if (!strcmp("profile-after-change", topic)) {
// profile after change // profile after change
mHaveProfile = PR_TRUE; mHaveProfile = PR_TRUE;
ReadPrefs(); ReadPrefs();
nsCacheService::OnProfileChanged(); nsCacheService::OnProfileChanged();
} else if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, topic)) { } else if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, topic)) {
// ignore pref changes until we're done switch profiles
if (!mHaveProfile) return NS_OK; if (!mHaveProfile) return NS_OK;
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject, &rv);
if (NS_FAILED(rv)) nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(subject, &rv);
return rv; if (NS_FAILED(rv)) return rv;
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
// which preference changed? // which preference changed?
if (!nsCRT::strcmp(DISK_CACHE_ENABLE_PREF, NS_ConvertUCS2toUTF8(data).get())) { if (!strcmp(DISK_CACHE_ENABLE_PREF, data.get())) {
rv = prefBranch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled); rv = branch->GetBoolPref(DISK_CACHE_ENABLE_PREF,
&mDiskCacheEnabled);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled()); nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled());
} else if (!nsCRT::strcmp(DISK_CACHE_CAPACITY_PREF, NS_ConvertUCS2toUTF8(data).get())) { } else if (!strcmp(DISK_CACHE_CAPACITY_PREF, data.get())) {
PRInt32 capacity = 0; PRInt32 capacity = 0;
rv = prefBranch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &capacity); rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &capacity);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
mDiskCacheCapacity = PR_MAX(0, capacity); mDiskCacheCapacity = PR_MAX(0, capacity);
nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity); nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity);
#if 0 #if 0
} else if (!nsCRT::strcmp(DISK_CACHE_DIR_PREF, NS_ConvertUCS2toUTF8(data).get())) { } else if (!strcmp(DISK_CACHE_DIR_PREF, data.get())) {
// XXX we probaby don't want to respond to this pref except after profile changes // XXX We probaby don't want to respond to this pref except after
// XXX ideally, there should be somekind of user notification that the pref change // XXX profile changes. Ideally, there should be somekind of user
// XXX won't take effect until the next time the profile changes (browser launch) // XXX notification that the pref change won't take effect until
// XXX the next time the profile changes (browser launch)
#endif #endif
} else } else
#endif // !NECKO_DISK_CACHE #endif // !NECKO_DISK_CACHE
if (!strcmp(MEMORY_CACHE_ENABLE_PREF, data.get())) {
if (!nsCRT::strcmp(MEMORY_CACHE_ENABLE_PREF, NS_ConvertUCS2toUTF8(data).get())) { rv = branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF,
&mMemoryCacheEnabled);
rv = prefBranch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCacheService::SetMemoryCacheEnabled(MemoryCacheEnabled()); nsCacheService::SetMemoryCacheEnabled(MemoryCacheEnabled());
} else if (!nsCRT::strcmp(MEMORY_CACHE_CAPACITY_PREF, NS_ConvertUCS2toUTF8(data).get())) { } else if (!strcmp(MEMORY_CACHE_CAPACITY_PREF, data.get())) {
PRInt32 capacity = 0; (void) branch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF,
rv = prefBranch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF, &capacity); &mMemoryCacheCapacity);
if (NS_FAILED(rv)) return rv;
mMemoryCacheCapacity = PR_MAX(0, capacity);
nsCacheService::SetMemoryCacheCapacity(mMemoryCacheCapacity); nsCacheService::SetMemoryCacheCapacity(mMemoryCacheCapacity);
} }
} }
@ -297,36 +305,43 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject,
nsresult nsresult
nsCacheProfilePrefObserver::ReadPrefs() nsCacheProfilePrefObserver::ReadPrefs()
{ {
nsresult rv, rv2 = NS_OK; nsresult rv = NS_OK;
PRInt32 capacity = 0;
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (NS_FAILED(rv)) return rv; if (!prefs) return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefService, &rv); nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
if (NS_FAILED(rv)) return rv; if (!branch) return NS_ERROR_FAILURE;
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
// read disk cache device prefs // read disk cache device prefs
rv = prefBranch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled); mDiskCacheEnabled = PR_TRUE; // presume disk cache is enabled
if (NS_FAILED(rv)) rv2 = rv; (void) branch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled);
rv = prefBranch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &capacity); mDiskCacheCapacity = DISK_CACHE_CAPACITY;
if (NS_FAILED(rv)) rv2 = rv; (void)branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &mDiskCacheCapacity);
mDiskCacheCapacity = PR_MAX(0, capacity); mDiskCacheCapacity = PR_MAX(0, mDiskCacheCapacity);
(void) prefBranch->GetComplexValue(DISK_CACHE_DIR_PREF, // ignore error (void) branch->GetComplexValue(DISK_CACHE_DIR_PREF, // ignore error
NS_GET_IID(nsILocalFile), NS_GET_IID(nsILocalFile),
getter_AddRefs(mDiskCacheParentDirectory)); getter_AddRefs(mDiskCacheParentDirectory));
if (!mDiskCacheParentDirectory) { if (!mDiskCacheParentDirectory) {
nsCOMPtr<nsIFile> directory; nsCOMPtr<nsIFile> directory;
// try to get the profile directory (there may not be a profile yet)
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(directory)); // try to get the disk cache parent directory
#if DEBUG rv = NS_GetSpecialDirectory(NS_APP_CACHE_PARENT_DIR,
getter_AddRefs(directory));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
// try to get the profile directory (there may not be a profile yet)
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(directory));
#if DEBUG
} else if (NS_FAILED(rv)) {
// use current process directory during development // use current process directory during development
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(directory)); rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(directory));
} }
#endif #endif
if (directory) if (directory)
@ -335,14 +350,12 @@ nsCacheProfilePrefObserver::ReadPrefs()
#endif // !NECKO_DISK_CACHE #endif // !NECKO_DISK_CACHE
// read memory cache device prefs // read memory cache device prefs
rv = prefBranch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled); (void) branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled);
if (NS_FAILED(rv)) rv2 = rv;
(void) branch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF,
capacity = 0; &mMemoryCacheCapacity);
rv = prefBranch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF, &capacity);
mMemoryCacheCapacity = PR_MAX(0, capacity);
return NS_SUCCEEDED(rv) ? rv2 : rv; return rv;
} }
@ -464,9 +477,6 @@ nsCacheService::Shutdown()
if (mInitialized) { if (mInitialized) {
mInitialized = PR_FALSE; mInitialized = PR_FALSE;
#if defined(PR_LOGGING)
LogCacheStatistics();
#endif
mObserver->Remove(); mObserver->Remove();
NS_RELEASE(mObserver); NS_RELEASE(mObserver);
@ -482,6 +492,10 @@ nsCacheService::Shutdown()
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
delete mDiskDevice; delete mDiskDevice;
mDiskDevice = nsnull; mDiskDevice = nsnull;
#if defined(PR_LOGGING)
LogCacheStatistics();
#endif
#endif #endif
} }
return NS_OK; return NS_OK;
@ -692,7 +706,7 @@ nsCacheService::CreateMemoryDevice()
if (!mMemoryDevice) return NS_ERROR_OUT_OF_MEMORY; if (!mMemoryDevice) return NS_ERROR_OUT_OF_MEMORY;
// set preference // set preference
mMemoryDevice->SetCapacity(mObserver->MemoryCacheCapacity()); mMemoryDevice->SetCapacity(CacheMemoryAvailable());
nsresult rv = mMemoryDevice->Init(); nsresult rv = mMemoryDevice->Init();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -1108,12 +1122,16 @@ nsCacheService::OnProfileShutdown(PRBool cleanse)
gService->mEnableDiskDevice = PR_FALSE; gService->mEnableDiskDevice = PR_FALSE;
} }
#endif // !NECKO_DISK_CACHE #endif // !NECKO_DISK_CACHE
#if 0
if (gService->mMemoryDevice) { if (gService->mMemoryDevice) {
// clear memory cache
gService->mMemoryDevice->EvictEntries(nsnull);
#if 0
gService->mMemoryDevice->Shutdown(); gService->mMemoryDevice->Shutdown();
gService->mEnableMemoryDevice = PR_FALSE; gService->mEnableMemoryDevice = PR_FALSE;
}
#endif #endif
}
} }
@ -1127,6 +1145,10 @@ nsCacheService::OnProfileChanged()
gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled();
if (gService->mEnableMemoryDevice && !gService->mMemoryDevice) {
(void) gService->CreateMemoryDevice();
}
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
if (gService->mDiskDevice) { if (gService->mDiskDevice) {
@ -1144,10 +1166,10 @@ nsCacheService::OnProfileChanged()
#endif // !NECKO_DISK_CACHE #endif // !NECKO_DISK_CACHE
if (gService->mMemoryDevice) { if (gService->mMemoryDevice) {
gService->mMemoryDevice->SetCapacity(gService->mObserver->MemoryCacheCapacity()); gService->mMemoryDevice->SetCapacity(gService->CacheMemoryAvailable());
rv = gService->mMemoryDevice->Init(); rv = gService->mMemoryDevice->Init();
if (NS_FAILED(rv) && (rv != NS_ERROR_ALREADY_INITIALIZED)) { if (NS_FAILED(rv) && (rv != NS_ERROR_ALREADY_INITIALIZED)) {
NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing disk device failed"); NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing memory device failed");
gService->mEnableMemoryDevice = PR_FALSE; gService->mEnableMemoryDevice = PR_FALSE;
// XXX delete mMemoryDevice? // XXX delete mMemoryDevice?
} }
@ -1201,36 +1223,128 @@ nsCacheService::SetMemoryCacheCapacity(PRInt32 capacity)
if (!gService) return; if (!gService) return;
nsAutoLock lock(gService->mCacheServiceLock); nsAutoLock lock(gService->mCacheServiceLock);
if (gService->mMemoryDevice) {
gService->mMemoryDevice->SetCapacity(capacity);
}
gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled();
} if (gService->mEnableMemoryDevice && !gService->mMemoryDevice) {
(void) gService->CreateMemoryDevice();
#if 0
void
nsCacheService::SetCacheDevicesEnabled(PRBool enableDisk, PRBool enableMemory)
{
if (this == nsnull) return; // NS_ERROR_NOT_AVAILABLE;
nsAutoLock lock(mCacheServiceLock);
if (enableDisk && !mDiskDevice) {
// disk device requires lazy activation
} else if (!enableDisk && mDiskDevice) {
// XXX deactivate disk
} }
if (enableMemory && !mMemoryDevice) { if (gService->mMemoryDevice) {
// XXX enable memory cache device gService->mMemoryDevice->SetCapacity(gService->CacheMemoryAvailable());
} else if (!enableMemory && mMemoryDevice) {
// XXX disable memory cache device
} }
} }
/**
* CacheMemoryAvailable
*
* If the browser.cache.memory.capacity preference is positive, we use that
* value for the amount of memory available for the cache.
*
* If browser.cache.memory.capacity is zero, the memory cache is disabled.
*
* If browser.cache.memory.capacity is negative or not present, we use a
* formula that grows less than linearly with the amount of system memory.
*
* RAM Cache
* --- -----
* 32 Mb 2 Mb
* 64 Mb 4 Mb
* 128 Mb 8 Mb
* 256 Mb 14 Mb
* 512 Mb 22 Mb
* 1024 Mb 32 Mb
* 2048 Mb 44 Mb
* 4096 Mb 58 Mb
*
*/
#include <math.h>
#if defined(__linux) || defined(__sun)
#include <unistd.h>
#elif defined(__hpux)
#include <sys/pstat.h>
#elif defined(XP_MACOSX)
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#elif defined(XP_OS2)
#define INCL_DOSMISC
#include <os2.h>
#elif defined(XP_WIN)
#include <windows.h>
#endif #endif
PRInt32
nsCacheService::CacheMemoryAvailable()
{
PRInt32 capacity = mObserver->MemoryCacheCapacity();
if (capacity >= 0)
return capacity;
long kbytes = 0;
#if defined(__linux) || defined(__sun)
long pageSize = sysconf(_SC_PAGESIZE);
long pageCount = sysconf(_SC_PHYS_PAGES);
kbytes = (pageSize / 1024) * pageCount;
#elif defined(__hpux)
struct pst_static info;
int result = pstat_getstatic(&info, sizeof(info), 1, 0);
if (result == 1) {
kbytes = info.physical_memory * (info.page_size / 1024);
}
#elif defined(XP_MACOSX)
struct host_basic_info hInfo;
mach_msg_type_number_t count;
int result = host_info(mach_host_self(),
HOST_BASIC_INFO,
(host_info_t) &hInfo,
&count);
if (result == KERN_SUCCESS) {
kbytes = hInfo.memory_size / 1024;
}
#elif defined(XP_WIN)
// XXX we should use GlobalMemoryStatusEx on XP and 2000, but
// XXX our current build environment doesn't support it.
MEMORYSTATUS memStat;
memset(&memStat, 0, sizeof(memStat));
GlobalMemoryStatus(&memStat);
kbytes = memStat.dwTotalPhys / 1024;
#elif defined(XP_OS2)
ULONG ulPhysMem;
DosQuerySysInfo(QSV_TOTPHYSMEM,
QSV_TOTPHYSMEM,
&ulPhysMem,
sizeof(ulPhysMem));
kbytes = (long)(ulPhysMem / 1024);
#else
return MEMORY_CACHE_CAPACITY;
#endif
if (kbytes == 0) return 0;
if (kbytes < 0) kbytes = LONG_MAX; // cap overflows
double x = log(kbytes)/log(2) - 14;
if (x > 0) {
capacity = (PRInt32)(x * x - x + 2.001); // add .001 for rounding
capacity *= 1024;
} else {
capacity = 0;
}
return capacity;
}
/****************************************************************************** /******************************************************************************
* static methods for nsCacheEntryDescriptor * static methods for nsCacheEntryDescriptor
@ -1586,7 +1700,9 @@ nsCacheService::LogCacheStatistics()
CACHE_LOG_ALWAYS((" Max Meta Size = %d\n", mMaxMetaSize)); CACHE_LOG_ALWAYS((" Max Meta Size = %d\n", mMaxMetaSize));
CACHE_LOG_ALWAYS((" Max Data Size = %d\n", mMaxDataSize)); CACHE_LOG_ALWAYS((" Max Data Size = %d\n", mMaxDataSize));
CACHE_LOG_ALWAYS(("\n")); CACHE_LOG_ALWAYS(("\n"));
CACHE_LOG_ALWAYS((" Deactivate Failures = %d\n", mDeactivateFailures)); CACHE_LOG_ALWAYS((" Deactivate Failures = %d\n",
CACHE_LOG_ALWAYS((" Deactivated Unbound Entries = %d\n", mDeactivatedUnboundEntries)); mDeactivateFailures));
CACHE_LOG_ALWAYS((" Deactivated Unbound Entries = %d\n",
mDeactivatedUnboundEntries));
} }
#endif #endif

1
netwerk/cache/src/nsCacheService.h поставляемый
Просмотреть файл

@ -175,6 +175,7 @@ private:
void ClearActiveEntries(void); void ClearActiveEntries(void);
void DoomActiveEntries(void); void DoomActiveEntries(void);
PRInt32 CacheMemoryAvailable();
static static
PLDHashOperator PR_CALLBACK DeactivateAndClearEntry(PLDHashTable * table, PLDHashOperator PR_CALLBACK DeactivateAndClearEntry(PLDHashTable * table,

11
netwerk/cache/src/nsMemoryCacheDevice.cpp поставляемый
Просмотреть файл

@ -30,6 +30,7 @@
#include "nsICacheVisitor.h" #include "nsICacheVisitor.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsCache.h" #include "nsCache.h"
#include "nsReadableUtils.h"
// The memory cache implements a variation of the "LRU-SP" caching algorithm // The memory cache implements a variation of the "LRU-SP" caching algorithm
// described in "LRU-SP: A Size-Adjusted and Popularity-Aware LRU Replacement // described in "LRU-SP: A Size-Adjusted and Popularity-Aware LRU Replacement
@ -519,7 +520,15 @@ NS_IMETHODIMP
nsMemoryCacheDeviceInfo::GetUsageReport(char ** result) nsMemoryCacheDeviceInfo::GetUsageReport(char ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
*result = nsCRT::strdup("Memory cache usage report:"); nsCString buffer;
buffer.Assign("<table>\n");
buffer.Append("<tr><td><b>Inactive Storage:</b></td><td><tt> ");
buffer.AppendInt(mDevice->mInactiveSize / 1024);
buffer.Append(" k</tt></td></tr>\n");
buffer.Append("</table>\n");
*result = ToNewCString(buffer);
if (!*result) return NS_ERROR_OUT_OF_MEMORY; if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK; return NS_OK;
} }