Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Unified Diff: net/cookies/cookie_monster.cc

Issue 1767513004: Clean up cookie eviction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/cookies/cookie_monster.h ('k') | net/cookies/cookie_monster_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cookies/cookie_monster.cc
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index 1d3814649ac9781444b8d54e0808a4cce547eef7..79a29bc9912b9d9f68b3884d6ebf20457fd37918 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -162,13 +162,10 @@ bool CookieSorter(CanonicalCookie* cc1, CanonicalCookie* cc2) {
bool LRACookieSorter(const CookieMonster::CookieMap::iterator& it1,
const CookieMonster::CookieMap::iterator& it2) {
- // Cookies accessed less recently should be deleted first.
if (it1->second->LastAccessDate() != it2->second->LastAccessDate())
return it1->second->LastAccessDate() < it2->second->LastAccessDate();
- // In rare cases we might have two cookies with identical last access times.
- // To preserve the stability of the sort, in these cases prefer to delete
- // older cookies over newer ones. CreationDate() is guaranteed to be unique.
+ // Ensure stability for == last access times by falling back to creation.
return it1->second->CreationDate() < it2->second->CreationDate();
}
@@ -250,30 +247,6 @@ void SplitCookieVectorIntoSecureAndNonSecure(
}
}
-// Predicate to support PartitionCookieByPriority().
-struct CookiePriorityEqualsTo
- : std::unary_function<const CookieMonster::CookieMap::iterator, bool> {
- explicit CookiePriorityEqualsTo(CookiePriority priority)
- : priority_(priority) {}
-
- bool operator()(const CookieMonster::CookieMap::iterator it) const {
- return it->second->Priority() == priority_;
- }
-
- const CookiePriority priority_;
-};
-
-// For a CookieItVector iterator range [|it_begin|, |it_end|),
-// moves all cookies with a given |priority| to the beginning of the list.
-// Returns: An iterator in [it_begin, it_end) to the first element with
-// priority != |priority|, or |it_end| if all have priority == |priority|.
-CookieMonster::CookieItVector::iterator PartitionCookieByPriority(
- CookieMonster::CookieItVector::iterator it_begin,
- CookieMonster::CookieItVector::iterator it_end,
- CookiePriority priority) {
- return std::partition(it_begin, it_end, CookiePriorityEqualsTo(priority));
-}
-
bool LowerBoundAccessDateComparator(const CookieMonster::CookieMap::iterator it,
const Time& access_date) {
return it->second->LastAccessDate() < access_date;
@@ -1875,6 +1848,7 @@ size_t CookieMonster::GarbageCollect(const Time& current,
num_deleted +=
GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its);
+ // TODO(mkwst): Soften this.
CookieItVector secure_cookie_its;
if (enforce_strict_secure && cookie_its->size() > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "Garbage collecting non-Secure cookies.";
@@ -1889,56 +1863,26 @@ size_t CookieMonster::GarbageCollect(const Time& current,
cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies);
DCHECK(purge_goal > kDomainPurgeCookies);
- // Boundary iterators into |cookie_its| for different priorities.
- CookieItVector::iterator it_bdd[4];
- // Intialize |it_bdd| while sorting |cookie_its| by priorities.
- // Schematic: [MLLHMHHLMM] => [LLL|MMMM|HHH], with 4 boundaries.
- it_bdd[0] = cookie_its->begin();
- it_bdd[3] = cookie_its->end();
- it_bdd[1] =
- PartitionCookieByPriority(it_bdd[0], it_bdd[3], COOKIE_PRIORITY_LOW);
- it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
- COOKIE_PRIORITY_MEDIUM);
- size_t quota[3] = {kDomainCookiesQuotaLow,
- kDomainCookiesQuotaMedium,
- kDomainCookiesQuotaHigh};
-
- // Purge domain cookies in 3 rounds.
- // Round 1: consider low-priority cookies only: evict least-recently
- // accessed, while protecting quota[0] of these from deletion.
- // Round 2: consider {low, medium}-priority cookies, evict least-recently
- // accessed, while protecting quota[0] + quota[1].
- // Round 3: consider all cookies, evict least-recently accessed.
- size_t accumulated_quota = 0;
- CookieItVector::iterator it_purge_begin = it_bdd[0];
- for (int i = 0; i < 3 && purge_goal > 0; ++i) {
- accumulated_quota += quota[i];
-
- size_t num_considered = it_bdd[i + 1] - it_purge_begin;
- if (num_considered <= accumulated_quota)
- continue;
-
- // Number of cookies that will be purged in this round.
- size_t round_goal =
- std::min(purge_goal, num_considered - accumulated_quota);
- purge_goal -= round_goal;
-
- SortLeastRecentlyAccessed(it_purge_begin, it_bdd[i + 1], round_goal);
- // Cookies accessed on or after |safe_date| would have been safe from
- // global purge, and we want to keep track of this.
- CookieItVector::iterator it_purge_end = it_purge_begin + round_goal;
- CookieItVector::iterator it_purge_middle =
- LowerBoundAccessDate(it_purge_begin, it_purge_end, safe_date);
- // Delete cookies accessed before |safe_date|.
- num_deleted += GarbageCollectDeleteRange(
- current, DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE, it_purge_begin,
- it_purge_middle);
- // Delete cookies accessed on or after |safe_date|.
- num_deleted += GarbageCollectDeleteRange(
- current, DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE, it_purge_middle,
- it_purge_end);
- it_purge_begin = it_purge_end;
+ // Sort the cookies by access date, from least-recent to most-recent.
+ std::sort(cookie_its->begin(), cookie_its->end(), LRACookieSorter);
+
+ // Remove all but the kDomainCookiesQuotaLow most-recently accessed
+ // cookies with low-priority. Then, if we still need to remove cookies,
+ // bump the quota and remove low- and medium-priority. Then, if we
+ // _still_ need to remove cookies, bump the quota and remove cookies
+ // with any priority.
+ size_t quotas[3] = {kDomainCookiesQuotaLow, kDomainCookiesQuotaMedium,
+ kDomainCookiesQuotaHigh};
+ size_t quota = 0;
+ for (size_t i = 0; i < arraysize(quotas) && purge_goal; i++) {
+ quota += quotas[i];
+ size_t just_deleted =
+ PurgeLeastRecentMatches(cookie_its, static_cast<CookiePriority>(i),
+ quota, purge_goal, safe_date);
+ purge_goal -= just_deleted;
+ num_deleted += just_deleted;
}
+
DCHECK_EQ(0U, purge_goal);
}
}
@@ -1986,6 +1930,38 @@ size_t CookieMonster::GarbageCollect(const Time& current,
return num_deleted;
}
+size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
mmenke 2016/03/04 16:17:57 Do we still need the CookieItVector, or could we j
mmenke 2016/03/04 16:20:19 If we take enum that indicates the secure value we
Mike West 2016/03/04 16:34:23 We'd need to scope it to the key involved, but we
Mike West 2016/03/07 10:22:28 Looking at this again, if we use `cookies_` we'll
+ CookiePriority priority,
+ size_t to_protect,
+ size_t purge_goal,
+ const base::Time& safe_date) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ size_t matches = std::count_if(cookies->begin(), cookies->end(),
+ [priority](const CookieMap::iterator& it) {
+ return it->second->Priority() <= priority;
+ });
+ if (to_protect > matches)
+ return 0;
+
+ size_t to_remove = std::min(purge_goal, matches - to_protect);
+ size_t removed = 0;
+ for (auto it = cookies->begin();
+ it != cookies->end() && removed < to_remove;) {
+ if ((*it)->second->Priority() <= priority) {
+ InternalDeleteCookie(*it, true,
+ (*it)->second->LastAccessDate() > safe_date
+ ? DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE
+ : DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE);
Mike West 2016/03/04 16:34:23 Is anyone looking at these metrics? If not (and I'
mmenke 2016/03/04 16:47:44 You mean the deletion cause? We pass that on to t
Mike West 2016/03/07 10:22:28 I was more specifically referring to the distincti
mmenke 2016/03/07 17:46:03 Ah, right, didn't realize we're pushing a simpler
Mike West 2016/03/08 08:58:28 https://codereview.chromium.org/1769023003
+ it = cookies->erase(it);
+ removed++;
+ } else {
+ it++;
+ }
+ }
+ return removed;
mmenke 2016/03/04 16:17:57 I think this entire method can be simpler: for (a
Mike West 2016/03/04 16:34:23 We need to protect the X most-recently used cookie
mmenke 2016/03/04 16:40:51 Oh, right, I forgot about purge_goal...So we'd nee
Mike West 2016/03/04 16:46:28 Oh, that's clever. So we'd walk down to the |to_pr
mmenke 2016/03/04 16:48:29 Yes, that's exactly what I mean.
+}
+
size_t CookieMonster::GarbageCollectExpired(const Time& current,
const CookieMapItPair& itpair,
CookieItVector* cookie_its) {
« no previous file with comments | « net/cookies/cookie_monster.h ('k') | net/cookies/cookie_monster_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698