Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: chrome/browser/sync/engine/get_commit_ids_command.cc

Issue 8631021: [Sync] Prevent uploading throttled datatypes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For review. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/engine/get_commit_ids_command.h" 5 #include "chrome/browser/sync/engine/get_commit_ids_command.h"
6 6
7 #include <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 25 matching lines...) Expand all
36 SyncerUtil::GetUnsyncedEntries(session->write_transaction(), 36 SyncerUtil::GetUnsyncedEntries(session->write_transaction(),
37 &all_unsynced_handles); 37 &all_unsynced_handles);
38 38
39 Cryptographer* cryptographer = 39 Cryptographer* cryptographer =
40 session->context()->directory_manager()->GetCryptographer( 40 session->context()->directory_manager()->GetCryptographer(
41 session->write_transaction()); 41 session->write_transaction());
42 if (cryptographer) { 42 if (cryptographer) {
43 encrypted_types_ = cryptographer->GetEncryptedTypes(); 43 encrypted_types_ = cryptographer->GetEncryptedTypes();
44 passphrase_missing_ = cryptographer->has_pending_keys(); 44 passphrase_missing_ = cryptographer->has_pending_keys();
45 }; 45 };
46
47 syncable::ModelTypeSet throttled_types =
akalin 2011/11/23 03:44:33 may as well make this a const ref
48 session->context()->GetThrottledTypes();
46 // We filter out all unready entries from the set of unsynced handles to 49 // We filter out all unready entries from the set of unsynced handles to
47 // ensure we don't trigger useless sync cycles attempting to retry due to 50 // ensure we don't trigger useless sync cycles attempting to retry due to
48 // there being work to do. (see ScheduleNextSync in sync_scheduler) 51 // there being work to do. (see ScheduleNextSync in sync_scheduler)
49 FilterUnreadyEntries(session->write_transaction(), 52 FilterUnreadyEntries(session->write_transaction(),
53 throttled_types,
50 &all_unsynced_handles); 54 &all_unsynced_handles);
51 55
52 StatusController* status = session->status_controller(); 56 StatusController* status = session->status_controller();
53 status->set_unsynced_handles(all_unsynced_handles); 57 status->set_unsynced_handles(all_unsynced_handles);
54 BuildCommitIds(status->unsynced_handles(), session->write_transaction(), 58 BuildCommitIds(status->unsynced_handles(), session->write_transaction(),
55 session->routing_info()); 59 session->routing_info(), throttled_types);
56 60
57 const vector<syncable::Id>& verified_commit_ids = 61 const vector<syncable::Id>& verified_commit_ids =
58 ordered_commit_set_->GetAllCommitIds(); 62 ordered_commit_set_->GetAllCommitIds();
59 63
60 for (size_t i = 0; i < verified_commit_ids.size(); i++) 64 for (size_t i = 0; i < verified_commit_ids.size(); i++)
61 VLOG(1) << "Debug commit batch result:" << verified_commit_ids[i]; 65 VLOG(1) << "Debug commit batch result:" << verified_commit_ids[i];
62 66
63 status->set_commit_set(*ordered_commit_set_.get()); 67 status->set_commit_set(*ordered_commit_set_.get());
64 } 68 }
65 69
66 namespace { 70 namespace {
67 71
68 // An entry ready for commit is defined as one not in conflict (SERVER_VERSION 72 // An entry ready for commit is defined as:
69 // == BASE_VERSION || SERVER_VERSION == 0) and not requiring encryption 73 // 1. Not in conflict (SERVER_VERSION == BASE_VERSION || SERVER_VERSION == 0)
70 // (any entry containing an encrypted datatype while the cryptographer requires 74 // and not requiring encryption (any entry containing an encrypted datatype
71 // a passphrase is not ready for commit.) 75 // while the cryptographer requires a passphrase is not ready for commit.)
76 // 2. Its type is not currently throttled.
72 bool IsEntryReadyForCommit(const syncable::ModelTypeSet& encrypted_types, 77 bool IsEntryReadyForCommit(const syncable::ModelTypeSet& encrypted_types,
73 bool passphrase_missing, 78 bool passphrase_missing,
74 const syncable::Entry& entry) { 79 const syncable::Entry& entry,
80 const syncable::ModelTypeSet& throttled_types) {
75 if (!entry.Get(syncable::IS_UNSYNCED)) 81 if (!entry.Get(syncable::IS_UNSYNCED))
76 return false; 82 return false;
77 83
78 if (entry.Get(syncable::SERVER_VERSION) > 0 && 84 if (entry.Get(syncable::SERVER_VERSION) > 0 &&
79 (entry.Get(syncable::SERVER_VERSION) > 85 (entry.Get(syncable::SERVER_VERSION) >
80 entry.Get(syncable::BASE_VERSION))) { 86 entry.Get(syncable::BASE_VERSION))) {
81 // The local and server versions don't match. The item must be in 87 // The local and server versions don't match. The item must be in
82 // conflict, so there's no point in attempting to commit. 88 // conflict, so there's no point in attempting to commit.
83 DCHECK(entry.Get(syncable::IS_UNAPPLIED_UPDATE)); // In conflict. 89 DCHECK(entry.Get(syncable::IS_UNAPPLIED_UPDATE)); // In conflict.
84 // TODO(zea): switch this to DVLOG once it's clear bug 100660 is fixed. 90 // TODO(zea): switch this to DVLOG once it's clear bug 100660 is fixed.
85 VLOG(1) << "Excluding entry from commit due to version mismatch " 91 VLOG(1) << "Excluding entry from commit due to version mismatch "
86 << entry; 92 << entry;
87 return false; 93 return false;
88 } 94 }
89 95
90 if (encrypted_types.count(entry.GetModelType()) > 0 && 96 syncable::ModelType type = entry.GetModelType();
97 if (encrypted_types.count(type) > 0 &&
91 (passphrase_missing || 98 (passphrase_missing ||
92 syncable::EntryNeedsEncryption(encrypted_types, entry))) { 99 syncable::EntryNeedsEncryption(encrypted_types, entry))) {
93 // This entry requires encryption but is not properly encrypted (possibly 100 // This entry requires encryption but is not properly encrypted (possibly
94 // due to the cryptographer not being initialized or the user hasn't 101 // due to the cryptographer not being initialized or the user hasn't
95 // provided the most recent passphrase). 102 // provided the most recent passphrase).
96 // TODO(zea): switch this to DVLOG once it's clear bug 100660 is fixed. 103 // TODO(zea): switch this to DVLOG once it's clear bug 100660 is fixed.
97 VLOG(1) << "Excluding entry from commit due to lack of encryption " 104 VLOG(1) << "Excluding entry from commit due to lack of encryption "
98 << entry; 105 << entry;
99 return false; 106 return false;
100 } 107 }
101 108
109 // Look at the throttled types.
110 if (throttled_types.count(type) > 0)
111 return false;
112
102 return true; 113 return true;
103 } 114 }
104 115
105 } // namespace 116 } // namespace
106 117
107 void GetCommitIdsCommand::FilterUnreadyEntries( 118 void GetCommitIdsCommand::FilterUnreadyEntries(
108 syncable::BaseTransaction* trans, 119 syncable::BaseTransaction* trans,
120 const syncable::ModelTypeSet& throttled_types,
109 syncable::Directory::UnsyncedMetaHandles* unsynced_handles) { 121 syncable::Directory::UnsyncedMetaHandles* unsynced_handles) {
110 syncable::Directory::UnsyncedMetaHandles::iterator iter; 122 syncable::Directory::UnsyncedMetaHandles::iterator iter;
111 syncable::Directory::UnsyncedMetaHandles new_unsynced_handles; 123 syncable::Directory::UnsyncedMetaHandles new_unsynced_handles;
112 new_unsynced_handles.reserve(unsynced_handles->size()); 124 new_unsynced_handles.reserve(unsynced_handles->size());
113 for (iter = unsynced_handles->begin(); 125 for (iter = unsynced_handles->begin();
114 iter != unsynced_handles->end(); 126 iter != unsynced_handles->end();
115 ++iter) { 127 ++iter) {
116 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, *iter); 128 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, *iter);
117 if (IsEntryReadyForCommit(encrypted_types_, passphrase_missing_, entry)) 129 if (IsEntryReadyForCommit(encrypted_types_,
130 passphrase_missing_,
131 entry,
132 throttled_types))
118 new_unsynced_handles.push_back(*iter); 133 new_unsynced_handles.push_back(*iter);
119 } 134 }
120 if (new_unsynced_handles.size() != unsynced_handles->size()) 135 if (new_unsynced_handles.size() != unsynced_handles->size())
121 unsynced_handles->swap(new_unsynced_handles); 136 unsynced_handles->swap(new_unsynced_handles);
122 } 137 }
123 138
124 void GetCommitIdsCommand::AddUncommittedParentsAndTheirPredecessors( 139 void GetCommitIdsCommand::AddUncommittedParentsAndTheirPredecessors(
125 syncable::BaseTransaction* trans, 140 syncable::BaseTransaction* trans,
126 syncable::Id parent_id, 141 syncable::Id parent_id,
127 const ModelSafeRoutingInfo& routes) { 142 const ModelSafeRoutingInfo& routes,
143 const syncable::ModelTypeSet& throttled_types) {
128 OrderedCommitSet item_dependencies(routes); 144 OrderedCommitSet item_dependencies(routes);
129 145
130 // Climb the tree adding entries leaf -> root. 146 // Climb the tree adding entries leaf -> root.
131 while (!parent_id.ServerKnows()) { 147 while (!parent_id.ServerKnows()) {
132 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id); 148 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id);
133 CHECK(parent.good()) << "Bad user-only parent in item path."; 149 CHECK(parent.good()) << "Bad user-only parent in item path.";
134 int64 handle = parent.Get(syncable::META_HANDLE); 150 int64 handle = parent.Get(syncable::META_HANDLE);
135 if (ordered_commit_set_->HaveCommitItem(handle) || 151 if (ordered_commit_set_->HaveCommitItem(handle) ||
136 item_dependencies.HaveCommitItem(handle)) { 152 item_dependencies.HaveCommitItem(handle)) {
137 break; 153 break;
138 } 154 }
139 if (!AddItemThenPredecessors(trans, &parent, syncable::IS_UNSYNCED, 155 if (!AddItemThenPredecessors(trans, throttled_types, &parent,
156 syncable::IS_UNSYNCED,
140 &item_dependencies)) { 157 &item_dependencies)) {
141 break; // Parent was already present in the set. 158 break; // Parent was already present in the set.
142 } 159 }
143 parent_id = parent.Get(syncable::PARENT_ID); 160 parent_id = parent.Get(syncable::PARENT_ID);
144 } 161 }
145 162
146 // Reverse what we added to get the correct order. 163 // Reverse what we added to get the correct order.
147 ordered_commit_set_->AppendReverse(item_dependencies); 164 ordered_commit_set_->AppendReverse(item_dependencies);
148 } 165 }
149 166
150 bool GetCommitIdsCommand::AddItem(syncable::Entry* item, 167 bool GetCommitIdsCommand::AddItem(syncable::Entry* item,
151 OrderedCommitSet* result) { 168 const syncable::ModelTypeSet& throttled_types,
152 if (!IsEntryReadyForCommit(encrypted_types_, passphrase_missing_, *item)) 169 OrderedCommitSet* result) {
170 if (!IsEntryReadyForCommit(encrypted_types_, passphrase_missing_, *item,
171 throttled_types))
153 return false; 172 return false;
154 int64 item_handle = item->Get(syncable::META_HANDLE); 173 int64 item_handle = item->Get(syncable::META_HANDLE);
155 if (result->HaveCommitItem(item_handle) || 174 if (result->HaveCommitItem(item_handle) ||
156 ordered_commit_set_->HaveCommitItem(item_handle)) { 175 ordered_commit_set_->HaveCommitItem(item_handle)) {
157 return false; 176 return false;
158 } 177 }
159 result->AddCommitItem(item_handle, item->Get(syncable::ID), 178 result->AddCommitItem(item_handle, item->Get(syncable::ID),
160 item->GetModelType()); 179 item->GetModelType());
161 return true; 180 return true;
162 } 181 }
163 182
164 bool GetCommitIdsCommand::AddItemThenPredecessors( 183 bool GetCommitIdsCommand::AddItemThenPredecessors(
165 syncable::BaseTransaction* trans, 184 syncable::BaseTransaction* trans,
185 const syncable::ModelTypeSet& throttled_types,
166 syncable::Entry* item, 186 syncable::Entry* item,
167 syncable::IndexedBitField inclusion_filter, 187 syncable::IndexedBitField inclusion_filter,
168 OrderedCommitSet* result) { 188 OrderedCommitSet* result) {
169 if (!AddItem(item, result)) 189 if (!AddItem(item, throttled_types, result))
170 return false; 190 return false;
171 if (item->Get(syncable::IS_DEL)) 191 if (item->Get(syncable::IS_DEL))
172 return true; // Deleted items have no predecessors. 192 return true; // Deleted items have no predecessors.
173 193
174 syncable::Id prev_id = item->Get(syncable::PREV_ID); 194 syncable::Id prev_id = item->Get(syncable::PREV_ID);
175 while (!prev_id.IsRoot()) { 195 while (!prev_id.IsRoot()) {
176 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id); 196 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id);
177 CHECK(prev.good()) << "Bad id when walking predecessors."; 197 CHECK(prev.good()) << "Bad id when walking predecessors.";
178 if (!prev.Get(inclusion_filter)) 198 if (!prev.Get(inclusion_filter))
179 break; 199 break;
180 if (!AddItem(&prev, result)) 200 if (!AddItem(&prev, throttled_types, result))
181 break; 201 break;
182 prev_id = prev.Get(syncable::PREV_ID); 202 prev_id = prev.Get(syncable::PREV_ID);
183 } 203 }
184 return true; 204 return true;
185 } 205 }
186 206
187 void GetCommitIdsCommand::AddPredecessorsThenItem( 207 void GetCommitIdsCommand::AddPredecessorsThenItem(
188 syncable::BaseTransaction* trans, 208 syncable::BaseTransaction* trans,
209 const syncable::ModelTypeSet& throttled_types,
189 syncable::Entry* item, 210 syncable::Entry* item,
190 syncable::IndexedBitField inclusion_filter, 211 syncable::IndexedBitField inclusion_filter,
191 const ModelSafeRoutingInfo& routes) { 212 const ModelSafeRoutingInfo& routes) {
192 OrderedCommitSet item_dependencies(routes); 213 OrderedCommitSet item_dependencies(routes);
193 AddItemThenPredecessors(trans, item, inclusion_filter, &item_dependencies); 214 AddItemThenPredecessors(trans, throttled_types, item, inclusion_filter,
215 &item_dependencies);
194 216
195 // Reverse what we added to get the correct order. 217 // Reverse what we added to get the correct order.
196 ordered_commit_set_->AppendReverse(item_dependencies); 218 ordered_commit_set_->AppendReverse(item_dependencies);
197 } 219 }
198 220
199 bool GetCommitIdsCommand::IsCommitBatchFull() { 221 bool GetCommitIdsCommand::IsCommitBatchFull() {
200 return ordered_commit_set_->Size() >= requested_commit_batch_size_; 222 return ordered_commit_set_->Size() >= requested_commit_batch_size_;
201 } 223 }
202 224
203 void GetCommitIdsCommand::AddCreatesAndMoves( 225 void GetCommitIdsCommand::AddCreatesAndMoves(
204 const vector<int64>& unsynced_handles, 226 const vector<int64>& unsynced_handles,
205 syncable::WriteTransaction* write_transaction, 227 syncable::WriteTransaction* write_transaction,
206 const ModelSafeRoutingInfo& routes) { 228 const ModelSafeRoutingInfo& routes,
229 const syncable::ModelTypeSet& throttled_types) {
207 // Add moves and creates, and prepend their uncommitted parents. 230 // Add moves and creates, and prepend their uncommitted parents.
208 for (CommitMetahandleIterator iterator(unsynced_handles, write_transaction, 231 for (CommitMetahandleIterator iterator(unsynced_handles, write_transaction,
209 ordered_commit_set_.get()); 232 ordered_commit_set_.get());
210 !IsCommitBatchFull() && iterator.Valid(); 233 !IsCommitBatchFull() && iterator.Valid();
211 iterator.Increment()) { 234 iterator.Increment()) {
212 int64 metahandle = iterator.Current(); 235 int64 metahandle = iterator.Current();
213 236
214 syncable::Entry entry(write_transaction, 237 syncable::Entry entry(write_transaction,
215 syncable::GET_BY_HANDLE, 238 syncable::GET_BY_HANDLE,
216 metahandle); 239 metahandle);
217 if (!entry.Get(syncable::IS_DEL)) { 240 if (!entry.Get(syncable::IS_DEL)) {
218 AddUncommittedParentsAndTheirPredecessors(write_transaction, 241 AddUncommittedParentsAndTheirPredecessors(write_transaction,
219 entry.Get(syncable::PARENT_ID), routes); 242 entry.Get(syncable::PARENT_ID), routes, throttled_types);
220 AddPredecessorsThenItem(write_transaction, &entry, 243 AddPredecessorsThenItem(write_transaction, throttled_types, &entry,
221 syncable::IS_UNSYNCED, routes); 244 syncable::IS_UNSYNCED, routes);
222 } 245 }
223 } 246 }
224 247
225 // It's possible that we overcommitted while trying to expand dependent 248 // It's possible that we overcommitted while trying to expand dependent
226 // items. If so, truncate the set down to the allowed size. 249 // items. If so, truncate the set down to the allowed size.
227 ordered_commit_set_->Truncate(requested_commit_batch_size_); 250 ordered_commit_set_->Truncate(requested_commit_batch_size_);
228 } 251 }
229 252
230 void GetCommitIdsCommand::AddDeletes(const vector<int64>& unsynced_handles, 253 void GetCommitIdsCommand::AddDeletes(const vector<int64>& unsynced_handles,
231 syncable::WriteTransaction* write_transaction) { 254 syncable::WriteTransaction* write_transaction) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 if (legal_delete_parents.count(parent_id)) { 329 if (legal_delete_parents.count(parent_id)) {
307 ordered_commit_set_->AddCommitItem(metahandle, entry.Get(syncable::ID), 330 ordered_commit_set_->AddCommitItem(metahandle, entry.Get(syncable::ID),
308 entry.GetModelType()); 331 entry.GetModelType());
309 } 332 }
310 } 333 }
311 } 334 }
312 } 335 }
313 336
314 void GetCommitIdsCommand::BuildCommitIds(const vector<int64>& unsynced_handles, 337 void GetCommitIdsCommand::BuildCommitIds(const vector<int64>& unsynced_handles,
315 syncable::WriteTransaction* write_transaction, 338 syncable::WriteTransaction* write_transaction,
316 const ModelSafeRoutingInfo& routes) { 339 const ModelSafeRoutingInfo& routes,
340 const syncable::ModelTypeSet& throttled_types) {
317 ordered_commit_set_.reset(new OrderedCommitSet(routes)); 341 ordered_commit_set_.reset(new OrderedCommitSet(routes));
318 // Commits follow these rules: 342 // Commits follow these rules:
319 // 1. Moves or creates are preceded by needed folder creates, from 343 // 1. Moves or creates are preceded by needed folder creates, from
320 // root to leaf. For folders whose contents are ordered, moves 344 // root to leaf. For folders whose contents are ordered, moves
321 // and creates appear in order. 345 // and creates appear in order.
322 // 2. Moves/Creates before deletes. 346 // 2. Moves/Creates before deletes.
323 // 3. Deletes, collapsed. 347 // 3. Deletes, collapsed.
324 // We commit deleted moves under deleted items as moves when collapsing 348 // We commit deleted moves under deleted items as moves when collapsing
325 // delete trees. 349 // delete trees.
326 350
327 // Add moves and creates, and prepend their uncommitted parents. 351 // Add moves and creates, and prepend their uncommitted parents.
328 AddCreatesAndMoves(unsynced_handles, write_transaction, routes); 352 AddCreatesAndMoves(unsynced_handles, write_transaction, routes,
353 throttled_types);
329 354
330 // Add all deletes. 355 // Add all deletes.
331 AddDeletes(unsynced_handles, write_transaction); 356 AddDeletes(unsynced_handles, write_transaction);
332 } 357 }
333 358
334 } // namespace browser_sync 359 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698