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