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

Side by Side Diff: components/sync_sessions/sessions_sync_manager.cc

Issue 2958303002: [Sync] Maintain a global_id mapping to update UserEvents that references navigations (Closed)
Patch Set: Hopefully fix iOS compile issue. Created 3 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/sync_sessions/sessions_sync_manager.h" 5 #include "components/sync_sessions/sessions_sync_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/format_macros.h" 10 #include "base/format_macros.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 const int kMaxSyncNavigationCount = 6; 44 const int kMaxSyncNavigationCount = 6;
45 45
46 // The URL at which the set of synced tabs is displayed. We treat it differently 46 // The URL at which the set of synced tabs is displayed. We treat it differently
47 // from all other URL's as accessing it triggers a sync refresh of Sessions. 47 // from all other URL's as accessing it triggers a sync refresh of Sessions.
48 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; 48 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs";
49 49
50 // Default number of days without activity after which a session is considered 50 // Default number of days without activity after which a session is considered
51 // stale and becomes a candidate for garbage collection. 51 // stale and becomes a candidate for garbage collection.
52 const int kDefaultStaleSessionThresholdDays = 14; // 2 weeks. 52 const int kDefaultStaleSessionThresholdDays = 14; // 2 weeks.
53 53
54 // Clean up navigation tracking when we have over this many global_ids.
55 const size_t kNavigationTrackingCleanupThreshold = 100;
56
57 // When we clean up navigation tracking, delete this many global_ids.
58 const int kNavigationTrackingCleanupAmount = 10;
59
54 // Comparator function for use with std::sort that will sort tabs by 60 // Comparator function for use with std::sort that will sort tabs by
55 // descending timestamp (i.e., most recent first). 61 // descending timestamp (i.e., most recent first).
56 bool TabsRecencyComparator(const sessions::SessionTab* t1, 62 bool TabsRecencyComparator(const sessions::SessionTab* t1,
57 const sessions::SessionTab* t2) { 63 const sessions::SessionTab* t2) {
58 return t1->timestamp > t2->timestamp; 64 return t1->timestamp > t2->timestamp;
59 } 65 }
60 66
61 // Comparator function for use with std::sort that will sort sessions by 67 // Comparator function for use with std::sort that will sort sessions by
62 // descending modified_time (i.e., most recent first). 68 // descending modified_time (i.e., most recent first).
63 bool SessionsRecencyComparator(const SyncedSession* s1, 69 bool SessionsRecencyComparator(const SyncedSession* s1,
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 GURL virtual_url = 577 GURL virtual_url =
572 modified_tab->GetVirtualURLAtIndex(modified_tab->GetCurrentEntryIndex()); 578 modified_tab->GetVirtualURLAtIndex(modified_tab->GetCurrentEntryIndex());
573 if (virtual_url.is_valid() && 579 if (virtual_url.is_valid() &&
574 virtual_url.spec() == kNTPOpenTabSyncURL) { 580 virtual_url.spec() == kNTPOpenTabSyncURL) {
575 DVLOG(1) << "Triggering sync refresh for sessions datatype."; 581 DVLOG(1) << "Triggering sync refresh for sessions datatype.";
576 if (!datatype_refresh_callback_.is_null()) 582 if (!datatype_refresh_callback_.is_null())
577 datatype_refresh_callback_.Run(); 583 datatype_refresh_callback_.Run();
578 } 584 }
579 } 585 }
580 586
587 sessions::SerializedNavigationEntry current;
588 modified_tab->GetSerializedNavigationAtIndex(
589 modified_tab->GetCurrentEntryIndex(), &current);
590 TrackNavigationIds(current);
591
581 if (local_tab_pool_out_of_sync_) { 592 if (local_tab_pool_out_of_sync_) {
582 // If our tab pool is corrupt, pay the price of a full re-association to 593 // If our tab pool is corrupt, pay the price of a full re-association to
583 // fix things up. This takes care of the new tab modification as well. 594 // fix things up. This takes care of the new tab modification as well.
584 bool rebuild_association_succeeded = RebuildAssociations(); 595 bool rebuild_association_succeeded = RebuildAssociations();
585 DCHECK(!rebuild_association_succeeded || !local_tab_pool_out_of_sync_); 596 DCHECK(!rebuild_association_succeeded || !local_tab_pool_out_of_sync_);
586 return; 597 return;
587 } 598 }
588 599
589 syncer::SyncChangeList changes; 600 syncer::SyncChangeList changes;
590 AssociateTab(modified_tab, &changes); 601 AssociateTab(modified_tab, &changes);
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 DVLOG(1) << "Found stale session " << session_tag << " with age " 1289 DVLOG(1) << "Found stale session " << session_tag << " with age "
1279 << session_age_in_days << ", deleting."; 1290 << session_age_in_days << ", deleting.";
1280 DeleteForeignSessionInternal(session_tag, &changes); 1291 DeleteForeignSessionInternal(session_tag, &changes);
1281 } 1292 }
1282 } 1293 }
1283 1294
1284 if (!changes.empty()) 1295 if (!changes.empty())
1285 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 1296 sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
1286 } 1297 }
1287 1298
1299 void SessionsSyncManager::AddGlobalIdChangeObserver(
1300 syncer::GlobalIdChange callback) {
1301 global_id_change_observers_.push_back(std::move(callback));
1302 }
1303
1304 int64_t SessionsSyncManager::GetLatestGlobalId(int64_t global_id) {
1305 auto g2u_iter = global_to_unique_.find(global_id);
1306 if (g2u_iter != global_to_unique_.end()) {
Patrick Noland 2017/06/28 22:44:37 This might look better as if (auto g2u_iter = ...
skym 2017/07/05 19:14:28 Acknowledged.
1307 auto u2g_iter = unique_to_current_global_.find(g2u_iter->second);
1308 if (u2g_iter != unique_to_current_global_.end()) {
1309 return u2g_iter->second;
1310 }
1311 }
1312 return global_id;
1313 }
1314
1288 // static 1315 // static
1289 std::string SessionsSyncManager::TagHashFromSpecifics( 1316 std::string SessionsSyncManager::TagHashFromSpecifics(
1290 const sync_pb::SessionSpecifics& specifics) { 1317 const sync_pb::SessionSpecifics& specifics) {
1291 return syncer::GenerateSyncableHash(syncer::SESSIONS, 1318 return syncer::GenerateSyncableHash(syncer::SESSIONS,
1292 TagFromSpecifics(specifics)); 1319 TagFromSpecifics(specifics));
1293 } 1320 }
1294 1321
1322 void SessionsSyncManager::TrackNavigationIds(
1323 const sessions::SerializedNavigationEntry& current) {
1324 // The expectation is that global_id will update for a given unique_id, which
1325 // should accurately and uniquely represent a single navigation. It is
1326 // theoretically possible for two unique_ids to map to the same global_id, but
1327 // hopefully rare enough that it doesn't cause much harm. Lets record metrics
1328 // verify this theory.
1329 int64_t global_id = current.timestamp().ToInternalValue();
1330 // It is possible that the global_id has not been set yet for this navigation.
1331 // In this case there's nothing here for us to track yet.
1332 if (global_id == 0) {
1333 return;
1334 }
1335
1336 int unique_id = current.unique_id();
1337 DCHECK_NE(0, unique_id);
1338
1339 auto g2u_iter = global_to_unique_.find(global_id);
1340 if (g2u_iter == global_to_unique_.end()) {
1341 global_to_unique_.insert(g2u_iter, std::make_pair(global_id, unique_id));
1342 } else if (g2u_iter->second != unique_id) {
1343 UMA_HISTOGRAM_COUNTS("Sync.GlobalIdConflict", 1);
Steven Holte 2017/06/28 18:59:45 UMA_HISTOGRAM_COUNTS is an alias for UMA_HISTOGRAM
skym 2017/07/05 19:14:28 Done, switched to UMA_HISTOGRAM_ENUMERATION. Wasn'
1344 }
1345
1346 auto u2g_iter = unique_to_current_global_.find(unique_id);
1347 if (u2g_iter == unique_to_current_global_.end()) {
1348 unique_to_current_global_.insert(u2g_iter,
Patrick Noland 2017/06/28 22:44:37 if you use base::flat_map (see https://cs.chromium
skym 2017/07/05 19:14:28 I think it'd be a bit confusing to have these two
1349 std::make_pair(unique_id, global_id));
1350 } else if (u2g_iter->second != global_id) {
1351 // Remember the old_global_id before we insert and invalidate out iter.
1352 int64_t old_global_id = u2g_iter->second;
1353
1354 // TODO(skym): Use insert_or_assign with hint once on C++17.
1355 unique_to_current_global_[unique_id] = global_id;
1356
1357 // This should be done after updating unique_to_current_global_ in case one
1358 // of our observers calls into GetLatestGlobalId().
1359 for (auto& observer : global_id_change_observers_) {
1360 observer.Run(old_global_id, global_id);
1361 }
1362 }
1363
1364 CleanupNavigationTracking();
1365 }
1366
1367 void SessionsSyncManager::CleanupNavigationTracking() {
1368 DCHECK(kNavigationTrackingCleanupThreshold >
1369 kNavigationTrackingCleanupAmount);
1370
1371 // |global_to_unique_| is implicitly ordered by least recently created, which
1372 // means we can drop from the beginning.
1373 if (global_to_unique_.size() > kNavigationTrackingCleanupThreshold) {
Patrick Noland 2017/06/28 22:44:37 Can you use the range-based erase here?
skym 2017/07/05 19:14:28 Done.
1374 for (int i = 0; i < kNavigationTrackingCleanupAmount; ++i) {
1375 global_to_unique_.erase(global_to_unique_.begin());
1376 }
1377
1378 // While |unique_id|s do get bigger for the most part, this isn't a great
1379 // thing to make assumptions about, and an old tab may get refreshed often
1380 // and still be very important. So instead just delete anything that's
1381 // orphaned from |global_to_unique_|.
1382 auto u2g_iter = unique_to_current_global_.begin();
1383 while (u2g_iter != unique_to_current_global_.end()) {
Patrick Noland 2017/06/28 22:44:37 I think you can use base::EraseIf here
skym 2017/07/05 19:14:28 Done.
1384 if (global_to_unique_.find(u2g_iter->second) == global_to_unique_.end()) {
1385 u2g_iter = unique_to_current_global_.erase(u2g_iter);
1386 } else {
1387 ++u2g_iter;
1388 }
1389 }
1390 }
1391 }
1392
1295 }; // namespace sync_sessions 1393 }; // namespace sync_sessions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698