Chromium Code Reviews| 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..f61493fececa55c111f4aaf799b343df4c5d9a61 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. |
| } |
| @@ -254,31 +273,87 @@ 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(kDemotedDirtyIDKeyPrefix + base::Int64ToString(tracker_id), ""); |
|
nhiroki
2014/07/07 09:52:29
GenerateDemotedDirtyIDKey()
peria
2014/07/08 03:05:07
Done.
Nice catch!
|
| } |
| 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(kDemotedDirtyIDKeyPrefix + base::Int64ToString(tracker_id), ""); |
| + } |
| } |
| size_t MetadataDatabaseIndexOnDisk::CountDirtyTracker() const { |
|
nhiroki
2014/07/07 09:52:29
To avoid iterating, are we able to cache the numbe
tzik
2014/07/07 14:28:47
... Or just leave a comment for that.
peria
2014/07/08 03:05:07
Done.
Let me leave a TODO comment.
|
| - // TODO(peria): Implement here |
| - NOTIMPLEMENTED(); |
| - return 0; |
| + size_t num_dirty_trackers = 0; |
| + |
| + 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 { |
| @@ -374,6 +449,60 @@ void MetadataDatabaseIndexOnDisk::RemoveFromAppIDIndex( |
| batch->Delete(db_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_trackers_: " << 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_: " << 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_trackers_: " << 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_trackers_: " << tracker_id; |
| + batch->Delete(dirty_key); |
| + batch->Delete(demoted_key); |
| + } |
| +} |
| + |
| bool MetadataDatabaseIndexOnDisk::DBHasKey(const std::string& key) { |
| scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| itr->Seek(key); |