1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <utility>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncer_command.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncer_util.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/ordered_commit_set.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/sync_session.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::pair;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::vector;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GetCommitIdsCommand : public SyncerCommand {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class SyncerTest;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit GetCommitIdsCommand(int commit_batch_size);
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~GetCommitIdsCommand();
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SyncerCommand implementation.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ExecuteImpl(sessions::SyncSession* session);
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Builds a vector of IDs that should be committed.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void BuildCommitIds(const vector<int64>& unsynced_handles,
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      syncable::WriteTransaction* write_transaction,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const ModelSafeRoutingInfo& routes);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(chron): Remove writes from this iterator. As a warning, this
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // iterator causes writes to entries and so isn't a pure iterator.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // It will do Put(IS_UNSYNCED). Refactor this out later.
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class CommitMetahandleIterator {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(chron): Cache ValidateCommitEntry responses across iterators to save
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // UTF8 conversion and filename checking
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CommitMetahandleIterator(const vector<int64>& unsynced_handles,
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             syncable::WriteTransaction* write_transaction,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sessions::OrderedCommitSet* commit_set)
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        : write_transaction_(write_transaction),
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          handle_iterator_(unsynced_handles.begin()),
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          unsynced_handles_end_(unsynced_handles.end()),
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          commit_set_(commit_set) {
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(chron): Remove writes from this iterator.
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(write_transaction_);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (Valid() && !ValidateMetahandleForCommit(*handle_iterator_))
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        Increment();
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ~CommitMetahandleIterator() {}
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 Current() const {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(Valid());
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return *handle_iterator_;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool Increment() {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!Valid())
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return false;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (++handle_iterator_;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           handle_iterator_ != unsynced_handles_end_;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           ++handle_iterator_) {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (ValidateMetahandleForCommit(*handle_iterator_))
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return true;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool Valid() const {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return !(handle_iterator_ == unsynced_handles_end_);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    private:
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     bool ValidateMetahandleForCommit(int64 metahandle) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       if (commit_set_->HaveCommitItem(metahandle))
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return false;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       // We should really not WRITE in this iterator, but we can fix that
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       // later. We should move that somewhere else later.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       syncable::MutableEntry entry(write_transaction_,
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           syncable::GET_BY_HANDLE, metahandle);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       VerifyCommitResult verify_result =
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           SyncerUtil::ValidateCommitEntry(&entry);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       if (verify_result == VERIFY_UNSYNCABLE) {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         // Drop unsyncable entries.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         entry.Put(syncable::IS_UNSYNCED, false);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       return verify_result == VERIFY_OK;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     }
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     syncable::WriteTransaction* const write_transaction_;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     vector<int64>::const_iterator handle_iterator_;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     vector<int64>::const_iterator unsynced_handles_end_;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     sessions::OrderedCommitSet* commit_set_;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     DISALLOW_COPY_AND_ASSIGN(CommitMetahandleIterator);
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddUncommittedParentsAndTheirPredecessors(
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      syncable::BaseTransaction* trans,
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      syncable::Id parent_id,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const ModelSafeRoutingInfo& routes);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OrderedCommitSet helpers for adding predecessors in order.
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(ncarter): Refactor these so that the |result| parameter goes away,
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and AddItem doesn't need to consider two OrderedCommitSets.
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool AddItem(syncable::Entry* item, sessions::OrderedCommitSet* result);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool AddItemThenPredecessors(syncable::BaseTransaction* trans,
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               syncable::Entry* item,
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               syncable::IndexedBitField inclusion_filter,
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               sessions::OrderedCommitSet* result);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddPredecessorsThenItem(syncable::BaseTransaction* trans,
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               syncable::Entry* item,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               syncable::IndexedBitField inclusion_filter,
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const ModelSafeRoutingInfo& routes);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool IsCommitBatchFull();
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddCreatesAndMoves(const vector<int64>& unsynced_handles,
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          syncable::WriteTransaction* write_transaction,
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const ModelSafeRoutingInfo& routes);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddDeletes(const vector<int64>& unsynced_handles,
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  syncable::WriteTransaction* write_transaction);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<sessions::OrderedCommitSet> ordered_commit_set_;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int requested_commit_batch_size_;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(GetCommitIdsCommand);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
147