зеркало из https://github.com/mozilla/gecko-dev.git
speedups for large histories. from camino branch. (r=bryner/sr=sfraser, bug
180109)
This commit is contained in:
Родитель
d0d000ff61
Коммит
1ddd219db3
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче