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

Side by Side Diff: chrome/browser/sync_file_system/drive_backend/metadata_database.cc

Issue 71233003: [SyncFS] Delete local file on rename and reorganize completion (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@00_completion
Patch Set: fix Created 7 years, 1 month 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <stack> 8 #include <stack>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 tracker->clear_synced_details(); 879 tracker->clear_synced_details();
880 tracker->set_dirty(true); 880 tracker->set_dirty(true);
881 tracker->set_active(false); 881 tracker->set_active(false);
882 PutTrackerToBatch(*tracker, batch.get()); 882 PutTrackerToBatch(*tracker, batch.get());
883 } 883 }
884 884
885 WriteToDatabase(batch.Pass(), callback); 885 WriteToDatabase(batch.Pass(), callback);
886 return; 886 return;
887 } 887 }
888 888
889 // Check if the tracker was retitled. If it was, update the title and its 889 // Check if the tracker's parent is still in |parent_tracker_ids|.
890 // index in advance. 890 // If not, there should exist another tracker for the new parent, so delete
891 if (!tracker->has_synced_details() || 891 // old tracker.
892 tracker->synced_details().title() != updated_details.title()) { 892 DCHECK(ContainsKey(tracker_by_id_, tracker->parent_tracker_id()));
893 UpdateTrackerTitle(tracker, updated_details.title(), batch.get()); 893 FileTracker* parent_tracker = tracker_by_id_[tracker->parent_tracker_id()];
894 if (!HasFileAsParent(updated_details, parent_tracker->file_id())) {
895 RemoveTracker(tracker->tracker_id(), batch.get());
896 WriteToDatabase(batch.Pass(), callback);
897 return;
898 }
899
900 if (tracker->has_synced_details()) {
901 // Check if the tracker was retitled. If it was, there should exist another
902 // tracker for the new title, so delete old tracker.
903 if (tracker->synced_details().title() != updated_details.title()) {
904 RemoveTracker(tracker->tracker_id(), batch.get());
905 WriteToDatabase(batch.Pass(), callback);
906 return;
907 }
908 } else {
909 int64 parent_tracker_id = parent_tracker->tracker_id();
910 const std::string& title = updated_details.title();
911 trackers_by_parent_and_title_[parent_tracker_id][title].Insert(
912 parent_tracker);
894 } 913 }
895 914
896 *tracker->mutable_synced_details() = updated_details; 915 *tracker->mutable_synced_details() = updated_details;
897 916
898 // Activate the tracker if: 917 // Activate the tracker if:
899 // - There is no active tracker that tracks |tracker->file_id()|. 918 // - There is no active tracker that tracks |tracker->file_id()|.
900 // - There is no active tracker that has the same |parent| and |title|. 919 // - There is no active tracker that has the same |parent| and |title|.
901 if (!tracker->active() && CanActivateTracker(*tracker)) 920 if (!tracker->active() && CanActivateTracker(*tracker))
902 MakeTrackerActive(tracker->tracker_id(), batch.get()); 921 MakeTrackerActive(tracker->tracker_id(), batch.get());
903 if (tracker->dirty() && !ShouldKeepDirty(*tracker)) { 922 if (tracker->dirty() && !ShouldKeepDirty(*tracker)) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 MarkTrackersDirtyByPath(tracker->parent_tracker_id(), 1228 MarkTrackersDirtyByPath(tracker->parent_tracker_id(),
1210 GetTrackerTitle(*tracker), 1229 GetTrackerTitle(*tracker),
1211 batch); 1230 batch);
1212 } 1231 }
1213 PutTrackerDeletionToBatch(tracker_id, batch); 1232 PutTrackerDeletionToBatch(tracker_id, batch);
1214 } 1233 }
1215 1234
1216 void MetadataDatabase::MaybeAddTrackersForNewFile( 1235 void MetadataDatabase::MaybeAddTrackersForNewFile(
1217 const FileMetadata& file, 1236 const FileMetadata& file,
1218 leveldb::WriteBatch* batch) { 1237 leveldb::WriteBatch* batch) {
1219 std::set<int64> known_parents; 1238 std::set<int64> parents_to_exclude;
1220 TrackersByFileID::iterator found = trackers_by_file_id_.find(file.file_id()); 1239 TrackersByFileID::iterator found = trackers_by_file_id_.find(file.file_id());
1221 if (found != trackers_by_file_id_.end()) { 1240 if (found != trackers_by_file_id_.end()) {
1222 for (TrackerSet::const_iterator itr = found->second.begin(); 1241 for (TrackerSet::const_iterator itr = found->second.begin();
1223 itr != found->second.end(); ++itr) { 1242 itr != found->second.end(); ++itr) {
1224 int64 parent_tracker_id = (*itr)->parent_tracker_id(); 1243 const FileTracker& tracker = **itr;
1225 if (parent_tracker_id) 1244 int64 parent_tracker_id = tracker.parent_tracker_id();
1226 known_parents.insert(parent_tracker_id); 1245 if (!parent_tracker_id)
1246 continue;
1247
1248 // Exclude |parent_tracker_id| if it already has a tracker that has
1249 // unknown title or has the same title with |file|.
1250 if (!tracker.has_synced_details() ||
1251 tracker.synced_details().title() == file.details().title()) {
1252 parents_to_exclude.insert(parent_tracker_id);
1253 }
1227 } 1254 }
1228 } 1255 }
1229 1256
1230 for (int i = 0; i < file.details().parent_folder_ids_size(); ++i) { 1257 for (int i = 0; i < file.details().parent_folder_ids_size(); ++i) {
1231 std::string parent_folder_id = file.details().parent_folder_ids(i); 1258 std::string parent_folder_id = file.details().parent_folder_ids(i);
1232 TrackersByFileID::iterator found = 1259 TrackersByFileID::iterator found =
1233 trackers_by_file_id_.find(parent_folder_id); 1260 trackers_by_file_id_.find(parent_folder_id);
1234 if (found == trackers_by_file_id_.end()) 1261 if (found == trackers_by_file_id_.end())
1235 continue; 1262 continue;
1236 1263
1237 for (TrackerSet::const_iterator itr = found->second.begin(); 1264 for (TrackerSet::const_iterator itr = found->second.begin();
1238 itr != found->second.end(); ++itr) { 1265 itr != found->second.end(); ++itr) {
1239 FileTracker* parent_tracker = *itr; 1266 FileTracker* parent_tracker = *itr;
1240 int64 parent_tracker_id = parent_tracker->tracker_id(); 1267 int64 parent_tracker_id = parent_tracker->tracker_id();
1241 if (!parent_tracker->active()) 1268 if (!parent_tracker->active())
1242 continue; 1269 continue;
1243 1270
1244 if (ContainsKey(known_parents, parent_tracker_id)) 1271 if (ContainsKey(parents_to_exclude, parent_tracker_id))
1245 continue; 1272 continue;
1246 1273
1247 CreateTrackerForParentAndFileID(*parent_tracker, file.file_id(), batch); 1274 CreateTrackerForParentAndFileID(*parent_tracker, file.file_id(), batch);
1248 } 1275 }
1249 } 1276 }
1250 } 1277 }
1251 1278
1252 void MetadataDatabase::RemoveAllDescendantTrackers(int64 root_tracker_id, 1279 void MetadataDatabase::RemoveAllDescendantTrackers(int64 root_tracker_id,
1253 leveldb::WriteBatch* batch) { 1280 leveldb::WriteBatch* batch) {
1254 std::vector<int64> pending_trackers; 1281 std::vector<int64> pending_trackers;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 TrackersByFileID::iterator found = trackers_by_file_id_.find(file_id); 1354 TrackersByFileID::iterator found = trackers_by_file_id_.find(file_id);
1328 if (found != trackers_by_file_id_.end()) 1355 if (found != trackers_by_file_id_.end())
1329 MarkTrackerSetDirty(&found->second, batch); 1356 MarkTrackerSetDirty(&found->second, batch);
1330 } 1357 }
1331 1358
1332 void MetadataDatabase::MarkTrackersDirtyByPath(int64 parent_tracker_id, 1359 void MetadataDatabase::MarkTrackersDirtyByPath(int64 parent_tracker_id,
1333 const std::string& title, 1360 const std::string& title,
1334 leveldb::WriteBatch* batch) { 1361 leveldb::WriteBatch* batch) {
1335 TrackersByParentAndTitle::iterator found = 1362 TrackersByParentAndTitle::iterator found =
1336 trackers_by_parent_and_title_.find(parent_tracker_id); 1363 trackers_by_parent_and_title_.find(parent_tracker_id);
1337 if (found == trackers_by_parent_and_title_.end()) { 1364 if (found == trackers_by_parent_and_title_.end())
1338 NOTREACHED() << "parent: " << parent_tracker_id
1339 << ", title: " << title;
1340 return; 1365 return;
1341 }
1342 1366
1343 TrackersByTitle::iterator itr = found->second.find(title); 1367 TrackersByTitle::iterator itr = found->second.find(title);
1344 if (itr != found->second.end()) 1368 if (itr != found->second.end())
1345 MarkTrackerSetDirty(&itr->second, batch); 1369 MarkTrackerSetDirty(&itr->second, batch);
1346 } 1370 }
1347 1371
1348 int64 MetadataDatabase::GetNextTrackerID(leveldb::WriteBatch* batch) { 1372 int64 MetadataDatabase::GetNextTrackerID(leveldb::WriteBatch* batch) {
1349 int64 tracker_id = service_metadata_->next_tracker_id(); 1373 int64 tracker_id = service_metadata_->next_tracker_id();
1350 service_metadata_->set_next_tracker_id(tracker_id + 1); 1374 service_metadata_->set_next_tracker_id(tracker_id + 1);
1351 PutServiceMetadataToBatch(*service_metadata_, batch); 1375 PutServiceMetadataToBatch(*service_metadata_, batch);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 TrackersByParentAndTitle::const_iterator found_by_parent = 1467 TrackersByParentAndTitle::const_iterator found_by_parent =
1444 trackers_by_parent_and_title_.find(parent_tracker_id); 1468 trackers_by_parent_and_title_.find(parent_tracker_id);
1445 if (found_by_parent == trackers_by_parent_and_title_.end()) 1469 if (found_by_parent == trackers_by_parent_and_title_.end())
1446 return false; 1470 return false;
1447 1471
1448 const TrackersByTitle& trackers_by_title = found_by_parent->second; 1472 const TrackersByTitle& trackers_by_title = found_by_parent->second;
1449 TrackersByTitle::const_iterator found = trackers_by_title.find(title); 1473 TrackersByTitle::const_iterator found = trackers_by_title.find(title);
1450 return found != trackers_by_title.end() && found->second.has_active(); 1474 return found != trackers_by_title.end() && found->second.has_active();
1451 } 1475 }
1452 1476
1453 void MetadataDatabase::UpdateTrackerTitle(FileTracker* tracker,
1454 const std::string& new_title,
1455 leveldb::WriteBatch* batch) {
1456 int64 parent_id = tracker->parent_tracker_id();
1457 std::string old_title = GetTrackerTitle(*tracker);
1458 DCHECK_NE(old_title, new_title);
1459 DCHECK(!new_title.empty());
1460
1461 TrackersByTitle* trackers_by_title =
1462 &trackers_by_parent_and_title_[parent_id];
1463 TrackerSet* old_siblings = &(*trackers_by_title)[old_title];
1464 TrackerSet* new_siblings = &(*trackers_by_title)[new_title];
1465
1466 old_siblings->Erase(tracker);
1467 if (old_siblings->empty())
1468 trackers_by_title->erase(old_title);
1469 else
1470 MarkTrackerSetDirty(old_siblings, batch);
1471
1472 if (tracker->active() && new_siblings->has_active()) {
1473 // Inactivate existing active tracker.
1474 FileTracker* obstacle = new_siblings->active_tracker();
1475 new_siblings->Inactivate(obstacle);
1476 DCHECK_EQ(TRACKER_KIND_REGULAR, obstacle->tracker_kind());
1477
1478 TrackerSet* same_file_id_trackers_to_obstacle =
1479 &trackers_by_file_id_[obstacle->file_id()];
1480 same_file_id_trackers_to_obstacle->Inactivate(obstacle);
1481 MarkTrackerSetDirty(same_file_id_trackers_to_obstacle, batch);
1482
1483 obstacle->set_active(false);
1484 PutTrackerToBatch(*obstacle, batch);
1485
1486 RemoveAllDescendantTrackers(obstacle->tracker_id(), batch);
1487 }
1488
1489 tracker->mutable_synced_details()->set_title(new_title);
1490 new_siblings->Insert(tracker);
1491 PutTrackerToBatch(*tracker, batch);
1492 }
1493
1494 void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch, 1477 void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
1495 const SyncStatusCallback& callback) { 1478 const SyncStatusCallback& callback) {
1496 base::PostTaskAndReplyWithResult( 1479 base::PostTaskAndReplyWithResult(
1497 task_runner_.get(), 1480 task_runner_.get(),
1498 FROM_HERE, 1481 FROM_HERE,
1499 base::Bind(&leveldb::DB::Write, 1482 base::Bind(&leveldb::DB::Write,
1500 base::Unretained(db_.get()), 1483 base::Unretained(db_.get()),
1501 leveldb::WriteOptions(), 1484 leveldb::WriteOptions(),
1502 base::Owned(batch.release())), 1485 base::Owned(batch.release())),
1503 base::Bind(&AdaptLevelDBStatusToSyncStatusCode, callback)); 1486 base::Bind(&AdaptLevelDBStatusToSyncStatusCode, callback));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 file->Set("details", details); 1538 file->Set("details", details);
1556 1539
1557 files->Append(file); 1540 files->Append(file);
1558 } 1541 }
1559 1542
1560 return files.Pass(); 1543 return files.Pass();
1561 } 1544 }
1562 1545
1563 } // namespace drive_backend 1546 } // namespace drive_backend
1564 } // namespace sync_file_system 1547 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698