speedups for large histories. from camino branch. (r=bryner/sr=sfraser, bug

180109)
This commit is contained in:
pinkerton%netscape.com 2003-10-09 01:01:44 +00:00
Родитель d0d000ff61
Коммит 1ddd219db3
2 изменённых файлов: 46 добавлений и 43 удалений

Просмотреть файл

@ -118,7 +118,7 @@ nsIPrefBranch* nsGlobalHistory::gPrefBranch = nsnull;
// the value of mLastNow expires every 3 seconds
#define HISTORY_EXPIRE_NOW_TIMEOUT (3 * PR_MSEC_PER_SEC)
#define MSECS_PER_DAY (PR_MSEC_PER_SEC * 60 * 60 * 24)
static const PRInt64 MSECS_PER_DAY = LL_INIT(20, 500654080); // (1000000LL * 60 * 60 * 24)
//----------------------------------------------------------------------
//
@ -145,8 +145,8 @@ struct matchSearchTerm_t {
searchTerm *term;
PRBool haveClosure; // are the rest of the fields valid?
PRInt64 now;
PRInt32 intValue;
nsGlobalHistory* globalHist;
};
struct matchQuery_t {
@ -259,53 +259,43 @@ CharsToPRInt64(const char* aBuf, PRUint32 aCount, PRInt64* aResult)
return NS_OK;
}
static PRTime
NormalizeTime(PRInt64 aTime)
PRTime
nsGlobalHistory::NormalizeTime(PRInt64 aTime)
{
// normalize both now and date to midnight of the day they occur on
PRExplodedTime explodedTime;
PR_ExplodeTime(aTime, PR_LocalTimeParameters, &explodedTime);
// we can optimize this by converting the time to local time, rounding
// down to the previous day boundary, and then converting back to UTC.
// This avoids two costly calls to localtime()
// set to midnight (0:00)
explodedTime.tm_min =
explodedTime.tm_hour =
explodedTime.tm_sec =
explodedTime.tm_usec = 0;
return PR_ImplodeTime(&explodedTime);
// we calculate (gmtTime - (gmtTime % MSECS_PER_DAY)) - mCachedGMTOffset
PRInt64 gmtTime;
LL_ADD(gmtTime, aTime, mCachedGMTOffset);
PRInt64 curDayUSec;
LL_MOD(curDayUSec, gmtTime, MSECS_PER_DAY);
PRInt64 gmtMidnight;
LL_SUB(gmtMidnight, gmtTime, curDayUSec);
PRInt64 localMidnight;
LL_SUB(localMidnight, gmtMidnight, mCachedGMTOffset);
return localMidnight;
}
// pass in a pre-normalized now and a date, and we'll find
// the difference since midnight on each of the days..
static PRInt32
GetAgeInDays(PRInt64 aNormalizedNow, PRInt64 aDate)
PRInt32
nsGlobalHistory::GetAgeInDays(PRInt64 aDate)
{
PRInt64 timeNow = GetNow();
PRInt64 dateMidnight = NormalizeTime(aDate);
PRInt64 diff;
LL_SUB(diff, aNormalizedNow, dateMidnight);
// two-step process since I can't seem to load
// MSECS_PER_DAY * PR_MSEC_PER_SEC into a PRInt64 at compile time
PRInt64 msecPerSec;
LL_I2L(msecPerSec, PR_MSEC_PER_SEC);
PRInt64 ageInSeconds;
LL_DIV(ageInSeconds, diff, msecPerSec);
PRInt32 ageSec; LL_L2I(ageSec, ageInSeconds);
PRInt64 msecPerDay;
LL_I2L(msecPerDay, MSECS_PER_DAY);
LL_SUB(diff, timeNow, dateMidnight);
PRInt64 ageInDays;
LL_DIV(ageInDays, ageInSeconds, msecPerDay);
LL_DIV(ageInDays, diff, MSECS_PER_DAY);
PRInt32 retval;
LL_L2I(retval, ageInDays);
return retval;
}
PRBool
nsGlobalHistory::MatchExpiration(nsIMdbRow *row, PRInt64* expirationDate)
{
@ -340,7 +330,6 @@ matchAgeInDaysCallback(nsIMdbRow *row, void *aClosure)
PRInt32 err;
// Need to create an nsAutoString to use ToInteger
matchSearchTerm->intValue = nsAutoString(term->text).ToInteger(&err);
matchSearchTerm->now = NormalizeTime(PR_Now());
if (err != 0) return PR_FALSE;
matchSearchTerm->haveClosure = PR_TRUE;
}
@ -358,7 +347,7 @@ matchAgeInDaysCallback(nsIMdbRow *row, void *aClosure)
CharsToPRInt64((const char*)yarn.mYarn_Buf, yarn.mYarn_Fill, &rowDate);
PRInt32 days = GetAgeInDays(matchSearchTerm->now, rowDate);
PRInt32 days = matchSearchTerm->globalHist->GetAgeInDays(rowDate);
if (term->method.Equals("is"))
return (days == matchSearchTerm->intValue);
@ -1686,7 +1675,7 @@ nsGlobalHistory::GetTarget(nsIRDFResource* aSource,
rv = GetRowValue(row, kToken_LastVisitDateColumn, &lastVisitDate);
if (NS_FAILED(rv)) return rv;
PRInt32 days = GetAgeInDays(NormalizeTime(GetNow()), lastVisitDate);
PRInt32 days = GetAgeInDays(lastVisitDate);
nsCOMPtr<nsIRDFInt> ageLiteral;
rv = gRDFService->GetIntLiteral(days, getter_AddRefs(ageLiteral));
@ -1810,6 +1799,15 @@ nsGlobalHistory::GetNow()
{
if (!mNowValid) { // not dirty, mLastNow is crufty
mLastNow = PR_Now();
// we also cache our offset from GMT, to optimize NormalizeTime()
// note that this cache is only valid if GetNow() is called before
// NormalizeTime(), but that is always the case here.
PRExplodedTime explodedNow;
PR_ExplodeTime(mLastNow, PR_LocalTimeParameters, &explodedNow);
mCachedGMTOffset = nsInt64(explodedNow.tm_params.tp_gmt_offset) * nsInt64((PRUint32)PR_USEC_PER_SEC) +
nsInt64(explodedNow.tm_params.tp_dst_offset) * nsInt64((PRUint32)PR_USEC_PER_SEC);
mNowValid = PR_TRUE;
if (!mExpireNowTimer)
mExpireNowTimer = do_CreateInstance("@mozilla.org/timer;1");
@ -3338,7 +3336,7 @@ nsGlobalHistory::NotifyFindAssertions(nsIRDFResource *aSource,
PRInt64 lastVisited;
GetRowValue(aRow, kToken_LastVisitDateColumn, &lastVisited);
PRInt32 ageInDays = GetAgeInDays(NormalizeTime(GetNow()), lastVisited);
PRInt32 ageInDays = GetAgeInDays(lastVisited);
nsCAutoString ageString; ageString.AppendInt(ageInDays);
nsCAutoString hostname;
@ -3430,7 +3428,7 @@ nsGlobalHistory::NotifyFindUnassertions(nsIRDFResource *aSource,
// first get age in days
PRInt64 lastVisited;
GetRowValue(aRow, kToken_LastVisitDateColumn, &lastVisited);
PRInt32 ageInDays = GetAgeInDays(NormalizeTime(GetNow()), lastVisited);
PRInt32 ageInDays = GetAgeInDays(lastVisited);
nsCAutoString ageString; ageString.AppendInt(ageInDays);
// now get hostname
@ -3814,7 +3812,7 @@ nsGlobalHistory::RowMatches(nsIMdbRow *aRow,
if (term->match) {
// queue up some values just in case callback needs it
// (how would we do this dynamically?)
matchSearchTerm_t matchSearchTerm = { mEnv, mStore, term , PR_FALSE};
matchSearchTerm_t matchSearchTerm = { mEnv, mStore, term, PR_FALSE, 0, this };
if (!term->match(aRow, (void *)&matchSearchTerm))
return PR_FALSE;
@ -3837,7 +3835,7 @@ nsGlobalHistory::RowMatches(nsIMdbRow *aRow,
if (err != 0 || !yarn.mYarn_Buf) return PR_FALSE;
const char* startPtr;
PRInt32 yarnLength = yarn.mYarn_Fill;;
PRInt32 yarnLength = yarn.mYarn_Fill;
nsCAutoString titleStr;
if (property_column == kToken_NameColumn) {
titleStr = NS_ConvertUCS2toUTF8((const PRUnichar*)yarn.mYarn_Buf, yarnLength);

Просмотреть файл

@ -153,6 +153,10 @@ public:
PRBool MatchHost(nsIMdbRow *row, matchHost_t *hostInfo);
PRBool RowMatches(nsIMdbRow* aRow, searchQuery *aQuery);
PRInt64 GetNow();
PRTime NormalizeTime(PRInt64 aTime);
PRInt32 GetAgeInDays(PRInt64 aDate);
protected:
//
@ -236,11 +240,12 @@ protected:
// caching of PR_Now() so we don't call it every time we do
// a history query
PRInt64 mLastNow; // cache the last PR_Now()
PRInt64 mCachedGMTOffset; // cached offset from GMT
PRInt32 mBatchesInProgress;
PRBool mNowValid; // is mLastNow valid?
nsCOMPtr<nsITimer> mExpireNowTimer;
PRInt64 GetNow();
void ExpireNow();
static void expireNowTimer(nsITimer *aTimer, void *aClosure)