Bug 1261386 - Avoid history flooding from repeated reloads. r=adw
MozReview-Commit-ID: FhU8nOoNUHb
This commit is contained in:
@@ -476,16 +476,22 @@ namespace places {
|
||||
uint32_t numEntries;
|
||||
nsresult rv = aArguments->GetNumEntries(&numEntries);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(numEntries > 0, "unexpected number of arguments");
|
||||
MOZ_ASSERT(numEntries == 1, "unexpected number of arguments");
|
||||
|
||||
int64_t pageId = aArguments->AsInt64(0);
|
||||
int32_t typed = numEntries > 1 ? aArguments->AsInt32(1) : 0;
|
||||
int32_t fullVisitCount = numEntries > 2 ? aArguments->AsInt32(2) : 0;
|
||||
int64_t bookmarkId = numEntries > 3 ? aArguments->AsInt64(3) : 0;
|
||||
MOZ_ASSERT(pageId > 0, "Should always pass a valid page id");
|
||||
if (pageId <= 0) {
|
||||
NS_ADDREF(*_result = new IntegerVariant(0));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t typed = 0;
|
||||
int32_t visitCount = 0;
|
||||
int32_t hidden = 0;
|
||||
bool hasBookmark = false;
|
||||
int32_t isQuery = 0;
|
||||
float pointsForSampledVisits = 0.0;
|
||||
int32_t numSampledVisits = 0;
|
||||
int32_t bonus = 0;
|
||||
|
||||
// This is a const version of the history object for thread-safety.
|
||||
const nsNavHistory* history = nsNavHistory::GetConstHistoryService();
|
||||
@@ -493,14 +499,12 @@ namespace places {
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
|
||||
if (pageId > 0) {
|
||||
// The page is already in the database, and we can fetch current
|
||||
// params from the database.
|
||||
|
||||
// Fetch the page stats from the database.
|
||||
{
|
||||
RefPtr<mozIStorageStatement> getPageInfo = DB->GetStatement(
|
||||
"SELECT typed, hidden, visit_count, "
|
||||
"(SELECT count(*) FROM moz_historyvisits WHERE place_id = :page_id), "
|
||||
"EXISTS (SELECT 1 FROM moz_bookmarks WHERE fk = :page_id), "
|
||||
"(url > 'place:' AND url < 'place;') "
|
||||
"SELECT typed, visit_count, foreign_count, "
|
||||
"(substr(url, 0, 7) = 'place:') "
|
||||
"FROM moz_places "
|
||||
"WHERE id = :page_id "
|
||||
);
|
||||
@@ -510,29 +514,26 @@ namespace places {
|
||||
rv = getPageInfo->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), pageId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool hasResult;
|
||||
bool hasResult = false;
|
||||
rv = getPageInfo->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(hasResult, NS_ERROR_UNEXPECTED);
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && hasResult, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rv = getPageInfo->GetInt32(0, &typed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = getPageInfo->GetInt32(1, &hidden);
|
||||
rv = getPageInfo->GetInt32(1, &visitCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = getPageInfo->GetInt32(2, &visitCount);
|
||||
int32_t foreignCount = 0;
|
||||
rv = getPageInfo->GetInt32(2, &foreignCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = getPageInfo->GetInt32(3, &fullVisitCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = getPageInfo->GetInt64(4, &bookmarkId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = getPageInfo->GetInt32(5, &isQuery);
|
||||
hasBookmark = foreignCount > 0;
|
||||
rv = getPageInfo->GetInt32(3, &isQuery);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// NOTE: This is not limited to visits with "visit_type NOT IN (0,4,7,8)"
|
||||
// because otherwise it would not return any visit for those transitions
|
||||
// causing an incorrect frecency, see CalculateFrecencyInternal().
|
||||
if (visitCount > 0) {
|
||||
// Get a sample of the last visits to the page, to calculate its weight.
|
||||
// In case of a temporary or permanent redirect, calculate the frecency
|
||||
// as if the original page was visited.
|
||||
// Get a sample of the last visits to the page, to calculate its weight.
|
||||
nsCOMPtr<mozIStorageStatement> getVisits = DB->GetStatement(
|
||||
NS_LITERAL_CSTRING(
|
||||
"/* do not warn (bug 659740 - SQLite may ignore index if few visits exist) */"
|
||||
@@ -551,12 +552,11 @@ namespace places {
|
||||
);
|
||||
NS_ENSURE_STATE(getVisits);
|
||||
mozStorageStatementScoper visitsScoper(getVisits);
|
||||
|
||||
rv = getVisits->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), pageId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fetch only a limited number of recent visits.
|
||||
int32_t numSampledVisits = 0;
|
||||
bool hasResult = false;
|
||||
for (int32_t maxVisits = history->GetNumVisitsForFrecency();
|
||||
numSampledVisits < maxVisits &&
|
||||
NS_SUCCEEDED(getVisits->ExecuteStep(&hasResult)) && hasResult;
|
||||
@@ -564,10 +564,10 @@ namespace places {
|
||||
int32_t visitType;
|
||||
rv = getVisits->GetInt32(1, &visitType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
int32_t bonus = history->GetFrecencyTransitionBonus(visitType, true);
|
||||
bonus = history->GetFrecencyTransitionBonus(visitType, true);
|
||||
|
||||
// Always add the bookmark visit bonus.
|
||||
if (bookmarkId) {
|
||||
// Add the bookmark visit bonus.
|
||||
if (hasBookmark) {
|
||||
bonus += history->GetFrecencyTransitionBonus(nsINavHistoryService::TRANSITION_BOOKMARK, true);
|
||||
}
|
||||
|
||||
@@ -578,56 +578,49 @@ namespace places {
|
||||
pointsForSampledVisits += (float)(weight * (bonus / 100.0));
|
||||
}
|
||||
}
|
||||
|
||||
// If we found some visits for this page, use the calculated weight.
|
||||
if (numSampledVisits) {
|
||||
// fix for bug #412219
|
||||
if (!pointsForSampledVisits) {
|
||||
// For URIs with zero points in the sampled recent visits
|
||||
// but "browsing" type visits outside the sampling range, set
|
||||
// frecency to -visit_count, so they're still shown in autocomplete.
|
||||
NS_ADDREF(*_result = new IntegerVariant(-visitCount));
|
||||
}
|
||||
else {
|
||||
// Estimate frecency using the last few visits.
|
||||
// Use ceilf() so that we don't round down to 0, which
|
||||
// would cause us to completely ignore the place during autocomplete.
|
||||
NS_ADDREF(*_result = new IntegerVariant((int32_t) ceilf(fullVisitCount * ceilf(pointsForSampledVisits) / numSampledVisits)));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// This page is unknown or has no visits. It could have just been added, so
|
||||
// use passed in or default values.
|
||||
// If we sampled some visits for this page, use the calculated weight.
|
||||
if (numSampledVisits) {
|
||||
// We were unable to calculate points, maybe cause all the visits in the
|
||||
// sample had a zero bonus. Though, we know the page has some past valid
|
||||
// visit, or visit_count would be zero. Thus we set the frecency to
|
||||
// -1, so they are still shown in autocomplete.
|
||||
if (!pointsForSampledVisits) {
|
||||
NS_ADDREF(*_result = new IntegerVariant(-1));
|
||||
}
|
||||
else {
|
||||
// Estimate frecency using the sampled visits.
|
||||
// Use ceilf() so that we don't round down to 0, which
|
||||
// would cause us to completely ignore the place during autocomplete.
|
||||
NS_ADDREF(*_result = new IntegerVariant((int32_t) ceilf(visitCount * ceilf(pointsForSampledVisits) / numSampledVisits)));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The code below works well for guessing the frecency on import, and we'll
|
||||
// correct later once we have visits.
|
||||
// TODO: What if we don't have visits and we never visit? We could end up
|
||||
// with a really high value that keeps coming up in ac results? Should we
|
||||
// only do this on import? Have to figure it out.
|
||||
int32_t bonus = 0;
|
||||
// Otherwise this page has no visits, it may be bookmarked.
|
||||
if (!hasBookmark || isQuery) {
|
||||
NS_ADDREF(*_result = new IntegerVariant(0));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For unvisited bookmarks, produce a non-zero frecency, so that they show
|
||||
// up in URL bar autocomplete.
|
||||
visitCount = 1;
|
||||
|
||||
// Make it so something bookmarked and typed will have a higher frecency
|
||||
// than something just typed or just bookmarked.
|
||||
if (bookmarkId && !isQuery) {
|
||||
bonus += history->GetFrecencyTransitionBonus(nsINavHistoryService::TRANSITION_BOOKMARK, false);;
|
||||
// For unvisited bookmarks, produce a non-zero frecency, so that they show
|
||||
// up in URL bar autocomplete.
|
||||
fullVisitCount = 1;
|
||||
}
|
||||
|
||||
bonus += history->GetFrecencyTransitionBonus(nsINavHistoryService::TRANSITION_BOOKMARK, false);
|
||||
if (typed) {
|
||||
bonus += history->GetFrecencyTransitionBonus(nsINavHistoryService::TRANSITION_TYPED, false);
|
||||
}
|
||||
|
||||
// Assume "now" as our ageInDays, so use the first bucket.
|
||||
pointsForSampledVisits = history->GetFrecencyBucketWeight(1) * (bonus / (float)100.0);
|
||||
pointsForSampledVisits = history->GetFrecencyBucketWeight(1) * (bonus / (float)100.0);
|
||||
|
||||
// use ceilf() so that we don't round down to 0, which
|
||||
// would cause us to completely ignore the place during autocomplete
|
||||
NS_ADDREF(*_result = new IntegerVariant((int32_t) ceilf(fullVisitCount * ceilf(pointsForSampledVisits))));
|
||||
NS_ADDREF(*_result = new IntegerVariant((int32_t) ceilf(visitCount * ceilf(pointsForSampledVisits))));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user