Chromium Code Reviews| Index: chrome/browser/sync/engine/get_commit_ids_command.h |
| =================================================================== |
| --- chrome/browser/sync/engine/get_commit_ids_command.h (revision 0) |
| +++ chrome/browser/sync/engine/get_commit_ids_command.h (revision 0) |
| @@ -0,0 +1,202 @@ |
| +// 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 <vector> |
| +#include <utility> |
| + |
| +#include "chrome/browser/sync/engine/syncer_command.h" |
| +#include "chrome/browser/sync/engine/syncer_util.h" |
| +#include "chrome/browser/sync/engine/syncer_session.h" |
|
idana
2009/09/10 05:44:37
syncer_session.h should come before syncer_util.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(); |
| + |
| + virtual void ExecuteImpl(SyncerSession *session); |
|
idana
2009/09/10 05:44:37
"SyncerSession *session" -> "SyncerSession* sessio
|
| + |
| + // Returns a vector of IDs that should be committed. |
| + void BuildCommitIds(SyncerSession *session); |
| + |
| + // These classes are public for testing. |
| + // TODO(ncarter): This code is more generic than just Commit and can |
| + // be reused elsewhere (e.g. PositionalRunBuilder, ChangeReorderBuffer |
| + // do similar things). Merge all these implementations. |
| + class OrderedCommitSet { |
| + public: |
| + // TODO(chron): Reserve space according to batch size? |
| + OrderedCommitSet() {} |
| + ~OrderedCommitSet() {} |
| + |
| + bool HaveCommitItem(const int64 metahandle) const { |
| + return inserted_metahandles_.count(metahandle) > 0; |
| + } |
| + |
| + void AddCommitItem(const int64 metahandle, const syncable::Id& commit_id) { |
| + if (!HaveCommitItem(metahandle)) { |
| + inserted_metahandles_.insert(metahandle); |
| + metahandle_order_.push_back(metahandle); |
| + commit_ids_.push_back(commit_id); |
| + } |
| + } |
| + |
| + const vector<syncable::Id>& GetCommitIds() const { |
| + return commit_ids_; |
| + } |
| + |
| + pair<int64, syncable::Id> GetCommitItemAt(const int position) const { |
| + DCHECK(position < Size()); |
| + return pair<int64, syncable::Id> ( |
| + metahandle_order_[position], commit_ids_[position]); |
| + } |
| + |
| + int Size() const { |
| + return commit_ids_.size(); |
| + } |
| + |
| + void AppendReverse(const OrderedCommitSet& other) { |
| + for (int i = other.Size() - 1; i >= 0; i--) { |
| + pair<int64, syncable::Id> item = other.GetCommitItemAt(i); |
| + AddCommitItem(item.first, item.second); |
| + } |
| + } |
| + |
| + void Truncate(size_t max_size) { |
| + if (max_size < metahandle_order_.size()) { |
| + for (size_t i = max_size; i < metahandle_order_.size(); ++i) { |
| + inserted_metahandles_.erase(metahandle_order_[i]); |
| + } |
| + commit_ids_.resize(max_size); |
| + metahandle_order_.resize(max_size); |
| + } |
| + } |
| + |
| + private: |
| + // These three lists are different views of the same data; e.g they are |
| + // isomorphic. |
| + syncable::MetahandleSet inserted_metahandles_; |
| + vector<syncable::Id> commit_ids_; |
| + vector<int64> metahandle_order_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OrderedCommitSet); |
| + }; |
| + |
| + |
| + // 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) as well as add things to the blocked |
| + // session list. Refactor this out later. |
| + class CommitMetahandleIterator { |
| + public: |
| + // TODO(chron): Cache ValidateCommitEntry responses across iterators to save |
| + // UTF8 conversion and filename checking |
| + CommitMetahandleIterator(SyncerSession* session, |
| + OrderedCommitSet* commit_set) |
| + : session_(session), |
| + commit_set_(commit_set) { |
| + handle_iterator_ = session->unsynced_handles().begin(); |
| + |
| + // TODO(chron): Remove writes from this iterator. |
| + DCHECK(session->has_open_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_ != session_->unsynced_handles().end(); |
| + ++handle_iterator_) { |
| + if (ValidateMetahandleForCommit(*handle_iterator_)) |
| + return true; |
| + } |
| + |
| + return false; |
| + } |
| + |
| + bool Valid() const { |
| + return !(handle_iterator_ == session_->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. ValidateCommitEntry writes to the DB, and we add the |
| + // blocked items. We should move that somewhere else later. |
| + syncable::MutableEntry entry(session_->write_transaction(), |
| + syncable::GET_BY_HANDLE, metahandle); |
| + VerifyCommitResult verify_result = |
| + SyncerUtil::ValidateCommitEntry(&entry); |
| + if (verify_result == VERIFY_BLOCKED) { |
| + session_->AddBlockedItem(entry.Get(syncable::ID)); // TODO(chron): Ew. |
| + } else if (verify_result == VERIFY_UNSYNCABLE) { |
| + // drop unsyncable entries. |
| + entry.Put(syncable::IS_UNSYNCED, false); |
| + } |
| + return verify_result == VERIFY_OK; |
| + } |
| + |
| + SyncerSession* session_; |
| + vector<int64>::const_iterator handle_iterator_; |
| + OrderedCommitSet* commit_set_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(CommitMetahandleIterator); |
| + }; |
| + |
| + private: |
| + void AddUncommittedParentsAndTheirPredecessors( |
| + syncable::BaseTransaction* trans, |
| + syncable::Id parent_id); |
| + |
| + // 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, OrderedCommitSet* result); |
| + bool AddItemThenPredecessors(syncable::BaseTransaction* trans, |
| + syncable::Entry* item, |
| + syncable::IndexedBitField inclusion_filter, |
| + OrderedCommitSet* result); |
| + void AddPredecessorsThenItem(syncable::BaseTransaction* trans, |
| + syncable::Entry* item, |
| + syncable::IndexedBitField inclusion_filter); |
| + |
| + bool IsCommitBatchFull(); |
| + |
| + void AddCreatesAndMoves(SyncerSession *session); |
| + |
| + void AddDeletes(SyncerSession *session); |
| + |
| + 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_ |
| Property changes on: chrome\browser\sync\engine\get_commit_ids_command.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |