| // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_ |
| #define CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_ |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "chrome/browser/sync/engine/syncer_command.h" |
| #include "chrome/browser/sync/engine/syncer_util.h" |
| #include "chrome/browser/sync/sessions/ordered_commit_set.h" |
| #include "chrome/browser/sync/sessions/sync_session.h" |
| #include "chrome/browser/sync/util/sync_types.h" |
| |
| using std::pair; |
| using std::vector; |
| |
| namespace browser_sync { |
| |
| class GetCommitIdsCommand : public SyncerCommand { |
| friend class SyncerTest; |
| |
| public: |
| explicit GetCommitIdsCommand(int commit_batch_size); |
| virtual ~GetCommitIdsCommand(); |
| |
| // SyncerCommand implementation. |
| virtual void ExecuteImpl(sessions::SyncSession* session); |
| |
| // Builds a vector of IDs that should be committed. |
| void BuildCommitIds(const vector<int64>& unsynced_handles, |
| syncable::WriteTransaction* write_transaction, |
| const ModelSafeRoutingInfo& routes); |
| |
| // TODO(chron): Remove writes from this iterator. As a warning, this |
| // iterator causes writes to entries and so isn't a pure iterator. |
| // It will do Put(IS_UNSYNCED). Refactor this out later. |
| class CommitMetahandleIterator { |
| public: |
| // TODO(chron): Cache ValidateCommitEntry responses across iterators to save |
| // UTF8 conversion and filename checking |
| CommitMetahandleIterator(const vector<int64>& unsynced_handles, |
| syncable::WriteTransaction* write_transaction, |
| sessions::OrderedCommitSet* commit_set) |
| : write_transaction_(write_transaction), |
| handle_iterator_(unsynced_handles.begin()), |
| unsynced_handles_end_(unsynced_handles.end()), |
| commit_set_(commit_set) { |
| |
| // TODO(chron): Remove writes from this iterator. |
| DCHECK(write_transaction_); |
| |
| if (Valid() && !ValidateMetahandleForCommit(*handle_iterator_)) |
| Increment(); |
| } |
| ~CommitMetahandleIterator() {} |
| |
| int64 Current() const { |
| DCHECK(Valid()); |
| return *handle_iterator_; |
| } |
| |
| bool Increment() { |
| if (!Valid()) |
| return false; |
| |
| for (++handle_iterator_; |
| handle_iterator_ != unsynced_handles_end_; |
| ++handle_iterator_) { |
| if (ValidateMetahandleForCommit(*handle_iterator_)) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool Valid() const { |
| return !(handle_iterator_ == unsynced_handles_end_); |
| } |
| |
| private: |
| bool ValidateMetahandleForCommit(int64 metahandle) { |
| if (commit_set_->HaveCommitItem(metahandle)) |
| return false; |
| |
| // We should really not WRITE in this iterator, but we can fix that |
| // later. We should move that somewhere else later. |
| syncable::MutableEntry entry(write_transaction_, |
| syncable::GET_BY_HANDLE, metahandle); |
| VerifyCommitResult verify_result = |
| SyncerUtil::ValidateCommitEntry(&entry); |
| if (verify_result == VERIFY_UNSYNCABLE) { |
| // Drop unsyncable entries. |
| entry.Put(syncable::IS_UNSYNCED, false); |
| } |
| return verify_result == VERIFY_OK; |
| } |
| |
| syncable::WriteTransaction* const write_transaction_; |
| vector<int64>::const_iterator handle_iterator_; |
| vector<int64>::const_iterator unsynced_handles_end_; |
| sessions::OrderedCommitSet* commit_set_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CommitMetahandleIterator); |
| }; |
| |
| private: |
| void AddUncommittedParentsAndTheirPredecessors( |
| syncable::BaseTransaction* trans, |
| syncable::Id parent_id, |
| const ModelSafeRoutingInfo& routes); |
| |
| // OrderedCommitSet helpers for adding predecessors in order. |
| // TODO(ncarter): Refactor these so that the |result| parameter goes away, |
| // and AddItem doesn't need to consider two OrderedCommitSets. |
| bool AddItem(syncable::Entry* item, sessions::OrderedCommitSet* result); |
| bool AddItemThenPredecessors(syncable::BaseTransaction* trans, |
| syncable::Entry* item, |
| syncable::IndexedBitField inclusion_filter, |
| sessions::OrderedCommitSet* result); |
| void AddPredecessorsThenItem(syncable::BaseTransaction* trans, |
| syncable::Entry* item, |
| syncable::IndexedBitField inclusion_filter, |
| const ModelSafeRoutingInfo& routes); |
| |
| bool IsCommitBatchFull(); |
| |
| void AddCreatesAndMoves(const vector<int64>& unsynced_handles, |
| syncable::WriteTransaction* write_transaction, |
| const ModelSafeRoutingInfo& routes); |
| |
| void AddDeletes(const vector<int64>& unsynced_handles, |
| syncable::WriteTransaction* write_transaction); |
| |
| scoped_ptr<sessions::OrderedCommitSet> ordered_commit_set_; |
| |
| int requested_commit_batch_size_; |
| |
| DISALLOW_COPY_AND_ASSIGN(GetCommitIdsCommand); |
| }; |
| |
| } // namespace browser_sync |
| |
| #endif // CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_ |