// 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_ #pragma once #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" 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_