| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |