| Index: chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
|
| diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
|
| index b999e8192269475e004922172c9845c7aae9d438..35cf0e028f2ec2880ee76d41d2b313abcda05925 100644
|
| --- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
|
| +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
|
| @@ -62,6 +62,14 @@
|
| // key: "IDS_BY_PATH_INDEX: " + <int64 'parent_tracker_id'> +
|
| // '\x00' + <string 'title'> + '\x00' + <int64 'tracker_id'>
|
| // value: <empty>
|
| +//
|
| +// # Dirty tracker IDs
|
| +// key: "DIRTY: " + <int64 'dirty_tracker_id'>
|
| +// value: <empty>
|
| +//
|
| +// # Demoted dirty tracker IDs
|
| +// key: "DEMOTED_DIRTY: " + <int64 'demoted_dirty_tracker_id'>
|
| +// value: <empty>
|
|
|
| namespace sync_file_system {
|
| namespace drive_backend {
|
| @@ -72,6 +80,14 @@ std::string GenerateAppRootIDByAppIDKey(const std::string& app_id) {
|
| return kAppRootIDByAppIDKeyPrefix + app_id;
|
| }
|
|
|
| +std::string GenerateDirtyIDKey(int64 tracker_id) {
|
| + return kDirtyIDKeyPrefix + base::Int64ToString(tracker_id);
|
| +}
|
| +
|
| +std::string GenerateDemotedDirtyIDKey(int64 tracker_id) {
|
| + return kDemotedDirtyIDKeyPrefix + base::Int64ToString(tracker_id);
|
| +}
|
| +
|
| } // namespace
|
|
|
| MetadataDatabaseIndexOnDisk::MetadataDatabaseIndexOnDisk(leveldb::DB* db)
|
| @@ -161,11 +177,13 @@ void MetadataDatabaseIndexOnDisk::StoreFileTracker(
|
| DVLOG(3) << "Adding new tracker: " << tracker->tracker_id()
|
| << " " << GetTrackerTitle(*tracker);
|
| AddToAppIDIndex(*tracker, batch);
|
| + AddToDirtyTrackerIndexes(*tracker, batch);
|
| // TODO(peria): Add other indexes.
|
| } else {
|
| DVLOG(3) << "Updating tracker: " << tracker->tracker_id()
|
| << " " << GetTrackerTitle(*tracker);
|
| UpdateInAppIDIndex(old_tracker, *tracker, batch);
|
| + UpdateInDirtyTrackerIndexes(old_tracker, *tracker, batch);
|
| // TODO(peria): Update other indexes.
|
| }
|
| }
|
| @@ -188,6 +206,7 @@ void MetadataDatabaseIndexOnDisk::RemoveFileTracker(
|
| DVLOG(3) << "Removing tracker: "
|
| << tracker.tracker_id() << " " << GetTrackerTitle(tracker);
|
| RemoveFromAppIDIndex(tracker, batch);
|
| + RemoveFromDirtyTrackerIndexes(tracker, batch);
|
| // TODO(peria): Remove from other indexes.
|
| }
|
|
|
| @@ -200,7 +219,7 @@ TrackerIDSet MetadataDatabaseIndexOnDisk::GetFileTrackerIDsByFileID(
|
|
|
| int64 MetadataDatabaseIndexOnDisk::GetAppRootTracker(
|
| const std::string& app_id) const {
|
| - const std::string key(GenerateAppRootIDByAppIDKey(app_id));
|
| + const std::string& key(GenerateAppRootIDByAppIDKey(app_id));
|
| std::string value;
|
| leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
|
|
|
| @@ -254,31 +273,89 @@ ParentIDAndTitle MetadataDatabaseIndexOnDisk::PickMultiBackingFilePath() const {
|
| }
|
|
|
| int64 MetadataDatabaseIndexOnDisk::PickDirtyTracker() const {
|
| - // TODO(peria): Implement here
|
| - NOTIMPLEMENTED();
|
| - return 0;
|
| + scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
|
| + itr->Seek(kDirtyIDKeyPrefix);
|
| + if (!itr->Valid())
|
| + return kInvalidTrackerID;
|
| +
|
| + const std::string& key(itr->key().ToString());
|
| + if (!StartsWithASCII(key, kDirtyIDKeyPrefix, true))
|
| + return kInvalidTrackerID;
|
| +
|
| + int64 tracker_id;
|
| + if (!base::StringToInt64(RemovePrefix(key, kDirtyIDKeyPrefix), &tracker_id))
|
| + return kInvalidTrackerID;
|
| +
|
| + return tracker_id;
|
| }
|
|
|
| -void MetadataDatabaseIndexOnDisk::DemoteDirtyTracker(int64 tracker_id) {
|
| - // TODO(peria): Implement here
|
| - NOTIMPLEMENTED();
|
| +void MetadataDatabaseIndexOnDisk::DemoteDirtyTracker(
|
| + int64 tracker_id, leveldb::WriteBatch* batch) {
|
| + const std::string& key(GenerateDirtyIDKey(tracker_id));
|
| +
|
| + std::string value;
|
| + leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
|
| + if (status.IsNotFound())
|
| + return;
|
| + if (!status.ok()) {
|
| + util::Log(logging::LOG_WARNING, FROM_HERE,
|
| + "LevelDB error (%s) in getting a dirty tracker for ID: %" PRId64,
|
| + status.ToString().c_str(),
|
| + tracker_id);
|
| + return;
|
| + }
|
| +
|
| + batch->Delete(key);
|
| + batch->Put(GenerateDemotedDirtyIDKey(tracker_id), "");
|
| }
|
|
|
| bool MetadataDatabaseIndexOnDisk::HasDemotedDirtyTracker() const {
|
| - // TODO(peria): Implement here
|
| - NOTIMPLEMENTED();
|
| - return true;
|
| + scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
|
| + itr->Seek(kDemotedDirtyIDKeyPrefix);
|
| + if (!itr->Valid())
|
| + return false;
|
| + const std::string& key(itr->key().ToString());
|
| + return StartsWithASCII(key, kDemotedDirtyIDKeyPrefix, true);
|
| }
|
|
|
| -void MetadataDatabaseIndexOnDisk::PromoteDemotedDirtyTrackers() {
|
| - // TODO(peria): Implement here
|
| - NOTIMPLEMENTED();
|
| +void MetadataDatabaseIndexOnDisk::PromoteDemotedDirtyTrackers(
|
| + leveldb::WriteBatch* batch) {
|
| + scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
|
| + for (itr->Seek(kDirtyIDKeyPrefix); itr->Valid(); itr->Next()) {
|
| + const std::string& key(itr->key().ToString());
|
| + if (!StartsWithASCII(key, kDirtyIDKeyPrefix, true))
|
| + break;
|
| +
|
| + int64 tracker_id;
|
| + if (!base::StringToInt64(RemovePrefix(key, kDirtyIDKeyPrefix), &tracker_id))
|
| + continue;
|
| +
|
| + batch->Delete(itr->key());
|
| + batch->Put(GenerateDemotedDirtyIDKey(tracker_id), "");
|
| + }
|
| }
|
|
|
| size_t MetadataDatabaseIndexOnDisk::CountDirtyTracker() const {
|
| - // TODO(peria): Implement here
|
| - NOTIMPLEMENTED();
|
| - return 0;
|
| + size_t num_dirty_trackers = 0;
|
| +
|
| + // TODO(peria): Store the number of dirty trackers, and do not iterate
|
| + // everytime.
|
| + scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
|
| + for (itr->Seek(kDirtyIDKeyPrefix); itr->Valid(); itr->Next()) {
|
| + const std::string& key(itr->key().ToString());
|
| + if (!StartsWithASCII(key, kDirtyIDKeyPrefix, true))
|
| + break;
|
| + ++num_dirty_trackers;
|
| + }
|
| +
|
| + for (itr->Seek(kDemotedDirtyIDKeyPrefix); itr->Valid(); itr->Next()) {
|
| + const std::string& key(itr->key().ToString());
|
| + if (!StartsWithASCII(key, kDemotedDirtyIDKeyPrefix, true))
|
| + break;
|
| + ++num_dirty_trackers;
|
| + }
|
| +
|
| + return num_dirty_trackers;
|
| }
|
|
|
| size_t MetadataDatabaseIndexOnDisk::CountFileMetadata() const {
|
| @@ -328,7 +405,7 @@ void MetadataDatabaseIndexOnDisk::AddToAppIDIndex(
|
|
|
| DVLOG(1) << " Add to app_root_by_app_id: " << tracker.app_id();
|
|
|
| - const std::string db_key(GenerateAppRootIDByAppIDKey(tracker.app_id()));
|
| + const std::string& db_key(GenerateAppRootIDByAppIDKey(tracker.app_id()));
|
| DCHECK(tracker.active());
|
| DCHECK(!DBHasKey(db_key));
|
| batch->Put(db_key, base::Int64ToString(tracker.tracker_id()));
|
| @@ -343,19 +420,19 @@ void MetadataDatabaseIndexOnDisk::UpdateInAppIDIndex(
|
| if (IsAppRoot(old_tracker) && !IsAppRoot(new_tracker)) {
|
| DCHECK(old_tracker.active());
|
| DCHECK(!new_tracker.active());
|
| - const std::string db_key(GenerateAppRootIDByAppIDKey(old_tracker.app_id()));
|
| - DCHECK(DBHasKey(db_key));
|
| + const std::string& key(GenerateAppRootIDByAppIDKey(old_tracker.app_id()));
|
| + DCHECK(DBHasKey(key));
|
|
|
| DVLOG(1) << " Remove from app_root_by_app_id: " << old_tracker.app_id();
|
| - batch->Delete(db_key);
|
| + batch->Delete(key);
|
| } else if (!IsAppRoot(old_tracker) && IsAppRoot(new_tracker)) {
|
| DCHECK(!old_tracker.active());
|
| DCHECK(new_tracker.active());
|
| - const std::string db_key(GenerateAppRootIDByAppIDKey(new_tracker.app_id()));
|
| - DCHECK(!DBHasKey(db_key));
|
| + const std::string& key(GenerateAppRootIDByAppIDKey(new_tracker.app_id()));
|
| + DCHECK(!DBHasKey(key));
|
|
|
| DVLOG(1) << " Add to app_root_by_app_id: " << new_tracker.app_id();
|
| - batch->Put(db_key, base::Int64ToString(new_tracker.tracker_id()));
|
| + batch->Put(key, base::Int64ToString(new_tracker.tracker_id()));
|
| }
|
| }
|
|
|
| @@ -367,11 +444,65 @@ void MetadataDatabaseIndexOnDisk::RemoveFromAppIDIndex(
|
| }
|
|
|
| DCHECK(tracker.active());
|
| - const std::string db_key(GenerateAppRootIDByAppIDKey(tracker.app_id()));
|
| - DCHECK(DBHasKey(db_key));
|
| + const std::string& key(GenerateAppRootIDByAppIDKey(tracker.app_id()));
|
| + DCHECK(DBHasKey(key));
|
|
|
| DVLOG(1) << " Remove from app_root_by_app_id: " << tracker.app_id();
|
| - batch->Delete(db_key);
|
| + batch->Delete(key);
|
| +}
|
| +
|
| +void MetadataDatabaseIndexOnDisk::AddToDirtyTrackerIndexes(
|
| + const FileTracker& new_tracker,
|
| + leveldb::WriteBatch* batch) {
|
| + const std::string& dirty_key(GenerateDirtyIDKey(new_tracker.tracker_id()));
|
| + DCHECK(!DBHasKey(dirty_key));
|
| + DCHECK(!DBHasKey(GenerateDemotedDirtyIDKey(new_tracker.tracker_id())));
|
| +
|
| + if (new_tracker.dirty()) {
|
| + DVLOG(1) << " Add to dirty tracker IDs: " << new_tracker.tracker_id();
|
| + batch->Put(dirty_key, "");
|
| + }
|
| +}
|
| +
|
| +void MetadataDatabaseIndexOnDisk::UpdateInDirtyTrackerIndexes(
|
| + const FileTracker& old_tracker,
|
| + const FileTracker& new_tracker,
|
| + leveldb::WriteBatch* batch) {
|
| + DCHECK_EQ(old_tracker.tracker_id(), new_tracker.tracker_id());
|
| +
|
| + int64 tracker_id = new_tracker.tracker_id();
|
| + const std::string& dirty_key(GenerateDirtyIDKey(tracker_id));
|
| + const std::string& demoted_key(GenerateDemotedDirtyIDKey(tracker_id));
|
| + if (old_tracker.dirty() && !new_tracker.dirty()) {
|
| + DCHECK(DBHasKey(dirty_key) || DBHasKey(demoted_key));
|
| +
|
| + DVLOG(1) << " Remove from dirty trackers IDs: " << tracker_id;
|
| +
|
| + batch->Delete(dirty_key);
|
| + batch->Delete(demoted_key);
|
| + } else if (!old_tracker.dirty() && new_tracker.dirty()) {
|
| + DCHECK(!DBHasKey(dirty_key));
|
| + DCHECK(!DBHasKey(demoted_key));
|
| +
|
| + DVLOG(1) << " Add to dirty tracker IDs: " << tracker_id;
|
| +
|
| + batch->Put(dirty_key, "");
|
| + }
|
| +}
|
| +
|
| +void MetadataDatabaseIndexOnDisk::RemoveFromDirtyTrackerIndexes(
|
| + const FileTracker& tracker,
|
| + leveldb::WriteBatch* batch) {
|
| + if (tracker.dirty()) {
|
| + int64 tracker_id = tracker.tracker_id();
|
| + const std::string& dirty_key(GenerateDirtyIDKey(tracker_id));
|
| + const std::string& demoted_key(GenerateDemotedDirtyIDKey(tracker_id));
|
| + DCHECK(DBHasKey(dirty_key) || DBHasKey(demoted_key));
|
| +
|
| + DVLOG(1) << " Remove from dirty tracker IDs: " << tracker_id;
|
| + batch->Delete(dirty_key);
|
| + batch->Delete(demoted_key);
|
| + }
|
| }
|
|
|
| bool MetadataDatabaseIndexOnDisk::DBHasKey(const std::string& key) {
|
|
|