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

Side by Side Diff: chrome/browser/sync_file_system/drive_backend/metadata_database.cc

Issue 428063002: [SyncFS] Replace leveldb classes with LevelDBWrapper (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on cl/437943002 Created 6 years, 4 months 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_file_system/drive_backend/metadata_database.h" 5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <stack> 8 #include <stack>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/memory/scoped_vector.h" 15 #include "base/memory/scoped_vector.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
22 #include "base/thread_task_runner_handle.h" 22 #include "base/thread_task_runner_handle.h"
23 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
24 #include "chrome/browser/drive/drive_api_util.h" 24 #include "chrome/browser/drive/drive_api_util.h"
25 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants. h" 25 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants. h"
26 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 26 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
27 #include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
27 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 28 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
28 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index. h" 29 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index. h"
29 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_ interface.h" 30 #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_ interface.h"
30 #include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_ut il.h" 31 #include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_ut il.h"
31 #include "chrome/browser/sync_file_system/logger.h" 32 #include "chrome/browser/sync_file_system/logger.h"
32 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" 33 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
33 #include "google_apis/drive/drive_api_parser.h" 34 #include "google_apis/drive/drive_api_parser.h"
34 #include "third_party/leveldatabase/src/include/leveldb/db.h" 35 #include "third_party/leveldatabase/src/include/leveldb/db.h"
35 #include "third_party/leveldatabase/src/include/leveldb/env.h" 36 #include "third_party/leveldatabase/src/include/leveldb/env.h"
36 #include "third_party/leveldatabase/src/include/leveldb/status.h" 37 #include "third_party/leveldatabase/src/include/leveldb/status.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 return app_root_tracker.Pass(); 186 return app_root_tracker.Pass();
186 } 187 }
187 188
188 scoped_ptr<FileTracker> CloneFileTracker(const FileTracker* obj) { 189 scoped_ptr<FileTracker> CloneFileTracker(const FileTracker* obj) {
189 if (!obj) 190 if (!obj)
190 return scoped_ptr<FileTracker>(); 191 return scoped_ptr<FileTracker>();
191 return scoped_ptr<FileTracker>(new FileTracker(*obj)); 192 return scoped_ptr<FileTracker>(new FileTracker(*obj));
192 } 193 }
193 194
194 // Returns true if |db| has no content. 195 // Returns true if |db| has no content.
195 bool IsDatabaseEmpty(leveldb::DB* db) { 196 bool IsDatabaseEmpty(LevelDBWrapper* db) {
196 DCHECK(db); 197 DCHECK(db);
197 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 198 scoped_ptr<LevelDBWrapper::Iterator> itr(db->NewIterator());
198 itr->SeekToFirst(); 199 itr->SeekToFirst();
199 return !itr->Valid(); 200 return !itr->Valid();
200 } 201 }
201 202
202 SyncStatusCode OpenDatabase(const base::FilePath& path, 203 SyncStatusCode OpenDatabase(const base::FilePath& path,
203 leveldb::Env* env_override, 204 leveldb::Env* env_override,
204 scoped_ptr<leveldb::DB>* db_out, 205 scoped_ptr<LevelDBWrapper>* db_out,
205 bool* created) { 206 bool* created) {
206 base::ThreadRestrictions::AssertIOAllowed(); 207 base::ThreadRestrictions::AssertIOAllowed();
207 DCHECK(db_out); 208 DCHECK(db_out);
208 DCHECK(created); 209 DCHECK(created);
209 DCHECK(path.IsAbsolute()); 210 DCHECK(path.IsAbsolute());
210 211
211 leveldb::Options options; 212 leveldb::Options options;
212 options.max_open_files = 0; // Use minimum. 213 options.max_open_files = 0; // Use minimum.
213 options.create_if_missing = true; 214 options.create_if_missing = true;
214 if (env_override) 215 if (env_override)
215 options.env = env_override; 216 options.env = env_override;
216 leveldb::DB* db = NULL; 217 leveldb::DB* db = NULL;
217 leveldb::Status db_status = 218 leveldb::Status db_status =
218 leveldb::DB::Open(options, path.AsUTF8Unsafe(), &db); 219 leveldb::DB::Open(options, path.AsUTF8Unsafe(), &db);
219 SyncStatusCode status = LevelDBStatusToSyncStatusCode(db_status); 220 SyncStatusCode status = LevelDBStatusToSyncStatusCode(db_status);
220 if (status != SYNC_STATUS_OK) { 221 if (status != SYNC_STATUS_OK) {
221 delete db; 222 delete db;
222 return status; 223 return status;
223 } 224 }
224 225
225 *created = IsDatabaseEmpty(db); 226 db_out->reset(new LevelDBWrapper(make_scoped_ptr(db)));
226 db_out->reset(db); 227 *created = IsDatabaseEmpty(db_out->get());
227 return status; 228 return status;
228 } 229 }
229 230
230 SyncStatusCode MigrateDatabaseIfNeeded(leveldb::DB* db) { 231 SyncStatusCode MigrateDatabaseIfNeeded(LevelDBWrapper* db) {
231 // See metadata_database_index.cc for the database schema. 232 // See metadata_database_index.cc for the database schema.
232 base::ThreadRestrictions::AssertIOAllowed(); 233 base::ThreadRestrictions::AssertIOAllowed();
233 DCHECK(db); 234 DCHECK(db);
234 std::string value; 235 std::string value;
235 leveldb::Status status = 236 leveldb::Status status = db->Get(kDatabaseVersionKey, &value);
236 db->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value);
237 int64 version = 0; 237 int64 version = 0;
238 if (status.ok()) { 238 if (status.ok()) {
239 if (!base::StringToInt64(value, &version)) 239 if (!base::StringToInt64(value, &version))
240 return SYNC_DATABASE_ERROR_FAILED; 240 return SYNC_DATABASE_ERROR_FAILED;
241 } else { 241 } else {
242 if (!status.IsNotFound()) 242 if (!status.IsNotFound())
243 return SYNC_DATABASE_ERROR_FAILED; 243 return SYNC_DATABASE_ERROR_FAILED;
244 } 244 }
245 245
246 switch (version) { 246 switch (version) {
247 case 0: 247 case 0:
248 drive_backend::MigrateDatabaseFromV0ToV1(db); 248 drive_backend::MigrateDatabaseFromV0ToV1(db->GetLevelDB());
249 // fall-through 249 // fall-through
250 case 1: 250 case 1:
251 drive_backend::MigrateDatabaseFromV1ToV2(db); 251 drive_backend::MigrateDatabaseFromV1ToV2(db->GetLevelDB());
252 // fall-through 252 // fall-through
253 case 2: 253 case 2:
254 // TODO(tzik): Migrate database from version 2 to 3. 254 // TODO(tzik): Migrate database from version 2 to 3.
255 // * Add sync-root folder as active, dirty and needs_folder_listing 255 // * Add sync-root folder as active, dirty and needs_folder_listing
256 // folder. 256 // folder.
257 // * Add app-root folders for each origins. Each app-root folder for 257 // * Add app-root folders for each origins. Each app-root folder for
258 // an enabled origin should be a active, dirty and 258 // an enabled origin should be a active, dirty and
259 // needs_folder_listing folder. And Each app-root folder for a 259 // needs_folder_listing folder. And Each app-root folder for a
260 // disabled origin should be an inactive, dirty and 260 // disabled origin should be an inactive, dirty and
261 // non-needs_folder_listing folder. 261 // non-needs_folder_listing folder.
262 // * Add a file metadata for each file in previous version. 262 // * Add a file metadata for each file in previous version.
263 NOTIMPLEMENTED(); 263 NOTIMPLEMENTED();
264 return SYNC_DATABASE_ERROR_FAILED; 264 return SYNC_DATABASE_ERROR_FAILED;
265 // fall-through 265 // fall-through
266 case 3: 266 case 3:
267 DCHECK_EQ(3, kCurrentDatabaseVersion); 267 DCHECK_EQ(3, kCurrentDatabaseVersion);
268 return SYNC_STATUS_OK; 268 return SYNC_STATUS_OK;
269 default: 269 default:
270 return SYNC_DATABASE_ERROR_FAILED; 270 return SYNC_DATABASE_ERROR_FAILED;
271 } 271 }
272 } 272 }
273 273
274 bool HasInvalidTitle(const std::string& title) { 274 bool HasInvalidTitle(const std::string& title) {
275 return title.empty() || 275 return title.empty() ||
276 title.find('/') != std::string::npos || 276 title.find('/') != std::string::npos ||
277 title.find('\\') != std::string::npos; 277 title.find('\\') != std::string::npos;
278 } 278 }
279 279
280 void MarkTrackerSetDirty(const TrackerIDSet& trackers, 280 void MarkTrackerSetDirty(const TrackerIDSet& trackers,
281 MetadataDatabaseIndexInterface* index, 281 MetadataDatabaseIndexInterface* index) {
282 leveldb::WriteBatch* batch) {
283 for (TrackerIDSet::const_iterator itr = trackers.begin(); 282 for (TrackerIDSet::const_iterator itr = trackers.begin();
284 itr != trackers.end(); ++itr) { 283 itr != trackers.end(); ++itr) {
285 scoped_ptr<FileTracker> tracker(new FileTracker); 284 scoped_ptr<FileTracker> tracker(new FileTracker);
286 index->GetFileTracker(*itr, tracker.get()); 285 index->GetFileTracker(*itr, tracker.get());
287 if (tracker->dirty()) 286 if (tracker->dirty())
288 continue; 287 continue;
289 tracker->set_dirty(true); 288 tracker->set_dirty(true);
290 index->StoreFileTracker(tracker.Pass(), batch); 289 index->StoreFileTracker(tracker.Pass());
291 } 290 }
292 } 291 }
293 292
294 void MarkTrackersDirtyByPath(int64 parent_tracker_id, 293 void MarkTrackersDirtyByPath(int64 parent_tracker_id,
295 const std::string& title, 294 const std::string& title,
296 MetadataDatabaseIndexInterface* index, 295 MetadataDatabaseIndexInterface* index) {
297 leveldb::WriteBatch* batch) {
298 if (parent_tracker_id == kInvalidTrackerID || title.empty()) 296 if (parent_tracker_id == kInvalidTrackerID || title.empty())
299 return; 297 return;
300 MarkTrackerSetDirty( 298 MarkTrackerSetDirty(
301 index->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title), 299 index->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title),
302 index, batch); 300 index);
303 } 301 }
304 302
305 void MarkTrackersDirtyByFileID(const std::string& file_id, 303 void MarkTrackersDirtyByFileID(const std::string& file_id,
306 MetadataDatabaseIndexInterface* index, 304 MetadataDatabaseIndexInterface* index) {
307 leveldb::WriteBatch* batch) { 305 MarkTrackerSetDirty(index->GetFileTrackerIDsByFileID(file_id), index);
308 MarkTrackerSetDirty(index->GetFileTrackerIDsByFileID(file_id),
309 index, batch);
310 } 306 }
311 307
312 void MarkTrackersDirtyRecursively(int64 root_tracker_id, 308 void MarkTrackersDirtyRecursively(int64 root_tracker_id,
313 MetadataDatabaseIndexInterface* index, 309 MetadataDatabaseIndexInterface* index) {
314 leveldb::WriteBatch* batch) {
315 std::vector<int64> stack; 310 std::vector<int64> stack;
316 stack.push_back(root_tracker_id); 311 stack.push_back(root_tracker_id);
317 while (!stack.empty()) { 312 while (!stack.empty()) {
318 int64 tracker_id = stack.back(); 313 int64 tracker_id = stack.back();
319 stack.pop_back(); 314 stack.pop_back();
320 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), &stack); 315 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), &stack);
321 316
322 scoped_ptr<FileTracker> tracker(new FileTracker); 317 scoped_ptr<FileTracker> tracker(new FileTracker);
323 index->GetFileTracker(tracker_id, tracker.get()); 318 index->GetFileTracker(tracker_id, tracker.get());
324 tracker->set_dirty(true); 319 tracker->set_dirty(true);
325 320
326 index->StoreFileTracker(tracker.Pass(), batch); 321 index->StoreFileTracker(tracker.Pass());
327 } 322 }
328 } 323 }
329 324
330 void RemoveAllDescendantTrackers(int64 root_tracker_id, 325 void RemoveAllDescendantTrackers(int64 root_tracker_id,
331 MetadataDatabaseIndexInterface* index, 326 MetadataDatabaseIndexInterface* index) {
332 leveldb::WriteBatch* batch) {
333 std::vector<int64> pending_trackers; 327 std::vector<int64> pending_trackers;
334 AppendContents(index->GetFileTrackerIDsByParent(root_tracker_id), 328 AppendContents(index->GetFileTrackerIDsByParent(root_tracker_id),
335 &pending_trackers); 329 &pending_trackers);
336 330
337 std::vector<int64> to_be_removed; 331 std::vector<int64> to_be_removed;
338 332
339 // List trackers to remove. 333 // List trackers to remove.
340 while (!pending_trackers.empty()) { 334 while (!pending_trackers.empty()) {
341 int64 tracker_id = pending_trackers.back(); 335 int64 tracker_id = pending_trackers.back();
342 pending_trackers.pop_back(); 336 pending_trackers.pop_back();
343 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), 337 AppendContents(index->GetFileTrackerIDsByParent(tracker_id),
344 &pending_trackers); 338 &pending_trackers);
345 to_be_removed.push_back(tracker_id); 339 to_be_removed.push_back(tracker_id);
346 } 340 }
347 341
348 // Remove trackers in the reversed order. 342 // Remove trackers in the reversed order.
349 base::hash_set<std::string> affected_file_ids; 343 base::hash_set<std::string> affected_file_ids;
350 for (std::vector<int64>::reverse_iterator itr = to_be_removed.rbegin(); 344 for (std::vector<int64>::reverse_iterator itr = to_be_removed.rbegin();
351 itr != to_be_removed.rend(); ++itr) { 345 itr != to_be_removed.rend(); ++itr) {
352 FileTracker tracker; 346 FileTracker tracker;
353 index->GetFileTracker(*itr, &tracker); 347 index->GetFileTracker(*itr, &tracker);
354 affected_file_ids.insert(tracker.file_id()); 348 affected_file_ids.insert(tracker.file_id());
355 index->RemoveFileTracker(*itr, batch); 349 index->RemoveFileTracker(*itr);
356 } 350 }
357 351
358 for (base::hash_set<std::string>::iterator itr = affected_file_ids.begin(); 352 for (base::hash_set<std::string>::iterator itr = affected_file_ids.begin();
359 itr != affected_file_ids.end(); ++itr) { 353 itr != affected_file_ids.end(); ++itr) {
360 TrackerIDSet trackers = index->GetFileTrackerIDsByFileID(*itr); 354 TrackerIDSet trackers = index->GetFileTrackerIDsByFileID(*itr);
361 if (trackers.empty()) { 355 if (trackers.empty()) {
362 // Remove metadata that no longer has any tracker. 356 // Remove metadata that no longer has any tracker.
363 index->RemoveFileMetadata(*itr, batch); 357 index->RemoveFileMetadata(*itr);
364 } else { 358 } else {
365 MarkTrackerSetDirty(trackers, index, batch); 359 MarkTrackerSetDirty(trackers, index);
366 } 360 }
367 } 361 }
368 } 362 }
369 363
370 bool FilterFileTrackersByParent( 364 bool FilterFileTrackersByParent(
371 const MetadataDatabaseIndexInterface* index, 365 const MetadataDatabaseIndexInterface* index,
372 const TrackerIDSet& trackers, 366 const TrackerIDSet& trackers,
373 int64 parent_tracker_id, 367 int64 parent_tracker_id,
374 FileTracker* tracker_out) { 368 FileTracker* tracker_out) {
375 FileTracker tracker; 369 FileTracker tracker;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 443
450 enum DirtyingOption { 444 enum DirtyingOption {
451 MARK_NOTHING_DIRTY = 0, 445 MARK_NOTHING_DIRTY = 0,
452 MARK_ITSELF_DIRTY = 1 << 0, 446 MARK_ITSELF_DIRTY = 1 << 0,
453 MARK_SAME_FILE_ID_TRACKERS_DIRTY = 1 << 1, 447 MARK_SAME_FILE_ID_TRACKERS_DIRTY = 1 << 1,
454 MARK_SAME_PATH_TRACKERS_DIRTY = 1 << 2, 448 MARK_SAME_PATH_TRACKERS_DIRTY = 1 << 2,
455 }; 449 };
456 450
457 void ActivateFileTracker(int64 tracker_id, 451 void ActivateFileTracker(int64 tracker_id,
458 int dirtying_options, 452 int dirtying_options,
459 MetadataDatabaseIndexInterface* index, 453 MetadataDatabaseIndexInterface* index) {
460 leveldb::WriteBatch* batch) {
461 DCHECK(dirtying_options == MARK_NOTHING_DIRTY || 454 DCHECK(dirtying_options == MARK_NOTHING_DIRTY ||
462 dirtying_options == MARK_ITSELF_DIRTY); 455 dirtying_options == MARK_ITSELF_DIRTY);
463 456
464 scoped_ptr<FileTracker> tracker(new FileTracker); 457 scoped_ptr<FileTracker> tracker(new FileTracker);
465 index->GetFileTracker(tracker_id, tracker.get()); 458 index->GetFileTracker(tracker_id, tracker.get());
466 tracker->set_active(true); 459 tracker->set_active(true);
467 if (dirtying_options & MARK_ITSELF_DIRTY) { 460 if (dirtying_options & MARK_ITSELF_DIRTY) {
468 tracker->set_dirty(true); 461 tracker->set_dirty(true);
469 tracker->set_needs_folder_listing( 462 tracker->set_needs_folder_listing(
470 tracker->has_synced_details() && 463 tracker->has_synced_details() &&
471 tracker->synced_details().file_kind() == FILE_KIND_FOLDER); 464 tracker->synced_details().file_kind() == FILE_KIND_FOLDER);
472 } else { 465 } else {
473 tracker->set_dirty(false); 466 tracker->set_dirty(false);
474 tracker->set_needs_folder_listing(false); 467 tracker->set_needs_folder_listing(false);
475 } 468 }
476 469
477 index->StoreFileTracker(tracker.Pass(), batch); 470 index->StoreFileTracker(tracker.Pass());
478 } 471 }
479 472
480 void DeactivateFileTracker(int64 tracker_id, 473 void DeactivateFileTracker(int64 tracker_id,
481 int dirtying_options, 474 int dirtying_options,
482 MetadataDatabaseIndexInterface* index, 475 MetadataDatabaseIndexInterface* index) {
483 leveldb::WriteBatch* batch) { 476 RemoveAllDescendantTrackers(tracker_id, index);
484 RemoveAllDescendantTrackers(tracker_id, index, batch);
485 477
486 scoped_ptr<FileTracker> tracker(new FileTracker); 478 scoped_ptr<FileTracker> tracker(new FileTracker);
487 index->GetFileTracker(tracker_id, tracker.get()); 479 index->GetFileTracker(tracker_id, tracker.get());
488 480
489 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY) 481 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY)
490 MarkTrackersDirtyByFileID(tracker->file_id(), index, batch); 482 MarkTrackersDirtyByFileID(tracker->file_id(), index);
491 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) { 483 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) {
492 MarkTrackersDirtyByPath(tracker->parent_tracker_id(), 484 MarkTrackersDirtyByPath(tracker->parent_tracker_id(),
493 GetTrackerTitle(*tracker), 485 GetTrackerTitle(*tracker), index);
494 index, batch);
495 } 486 }
496 487
497 tracker->set_dirty(dirtying_options & MARK_ITSELF_DIRTY); 488 tracker->set_dirty(dirtying_options & MARK_ITSELF_DIRTY);
498 tracker->set_active(false); 489 tracker->set_active(false);
499 index->StoreFileTracker(tracker.Pass(), batch); 490 index->StoreFileTracker(tracker.Pass());
500 } 491 }
501 492
502 void RemoveFileTracker(int64 tracker_id, 493 void RemoveFileTracker(int64 tracker_id,
503 int dirtying_options, 494 int dirtying_options,
504 MetadataDatabaseIndexInterface* index, 495 MetadataDatabaseIndexInterface* index) {
505 leveldb::WriteBatch* batch) {
506 DCHECK(!(dirtying_options & MARK_ITSELF_DIRTY)); 496 DCHECK(!(dirtying_options & MARK_ITSELF_DIRTY));
507 497
508 FileTracker tracker; 498 FileTracker tracker;
509 if (!index->GetFileTracker(tracker_id, &tracker)) 499 if (!index->GetFileTracker(tracker_id, &tracker))
510 return; 500 return;
511 501
512 std::string file_id = tracker.file_id(); 502 std::string file_id = tracker.file_id();
513 int64 parent_tracker_id = tracker.parent_tracker_id(); 503 int64 parent_tracker_id = tracker.parent_tracker_id();
514 std::string title = GetTrackerTitle(tracker); 504 std::string title = GetTrackerTitle(tracker);
515 505
516 RemoveAllDescendantTrackers(tracker_id, index, batch); 506 RemoveAllDescendantTrackers(tracker_id, index);
517 index->RemoveFileTracker(tracker_id, batch); 507 index->RemoveFileTracker(tracker_id);
518 508
519 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY) 509 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY)
520 MarkTrackersDirtyByFileID(file_id, index, batch); 510 MarkTrackersDirtyByFileID(file_id, index);
521 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) 511 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY)
522 MarkTrackersDirtyByPath(parent_tracker_id, title, index, batch); 512 MarkTrackersDirtyByPath(parent_tracker_id, title, index);
523 513
524 if (index->GetFileTrackerIDsByFileID(file_id).empty()) { 514 if (index->GetFileTrackerIDsByFileID(file_id).empty()) {
525 index->RemoveFileMetadata(file_id, batch); 515 index->RemoveFileMetadata(file_id);
526 } 516 }
527 } 517 }
528 518
529 } // namespace 519 } // namespace
530 520
531 struct MetadataDatabase::CreateParam { 521 struct MetadataDatabase::CreateParam {
532 scoped_refptr<base::SequencedTaskRunner> worker_task_runner; 522 scoped_refptr<base::SequencedTaskRunner> worker_task_runner;
533 base::FilePath database_path; 523 base::FilePath database_path;
534 leveldb::Env* env_override; 524 leveldb::Env* env_override;
535 525
(...skipping 15 matching lines...) Expand all
551 &MetadataDatabase::CreateOnWorkerTaskRunner, 541 &MetadataDatabase::CreateOnWorkerTaskRunner,
552 base::Passed(make_scoped_ptr(new CreateParam( 542 base::Passed(make_scoped_ptr(new CreateParam(
553 worker_task_runner, 543 worker_task_runner,
554 database_path, 544 database_path,
555 env_override))), 545 env_override))),
556 callback)); 546 callback));
557 } 547 }
558 548
559 // static 549 // static
560 SyncStatusCode MetadataDatabase::CreateForTesting( 550 SyncStatusCode MetadataDatabase::CreateForTesting(
561 scoped_ptr<leveldb::DB> db, 551 scoped_ptr<LevelDBWrapper> db,
562 scoped_ptr<MetadataDatabase>* metadata_database_out) { 552 scoped_ptr<MetadataDatabase>* metadata_database_out) {
563 scoped_ptr<MetadataDatabase> metadata_database( 553 scoped_ptr<MetadataDatabase> metadata_database(
564 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(), 554 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(),
565 base::FilePath(), NULL)); 555 base::FilePath(), NULL));
566 metadata_database->db_ = db.Pass(); 556 metadata_database->db_ = db.Pass();
567 SyncStatusCode status = metadata_database->Initialize(); 557 SyncStatusCode status = metadata_database->Initialize();
568 if (status == SYNC_STATUS_OK) 558 if (status == SYNC_STATUS_OK)
569 *metadata_database_out = metadata_database.Pass(); 559 *metadata_database_out = metadata_database.Pass();
570 return status; 560 return status;
571 } 561 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 return index_->GetSyncRootTrackerID() != kInvalidTrackerID; 607 return index_->GetSyncRootTrackerID() != kInvalidTrackerID;
618 } 608 }
619 609
620 void MetadataDatabase::PopulateInitialData( 610 void MetadataDatabase::PopulateInitialData(
621 int64 largest_change_id, 611 int64 largest_change_id,
622 const google_apis::FileResource& sync_root_folder, 612 const google_apis::FileResource& sync_root_folder,
623 const ScopedVector<google_apis::FileResource>& app_root_folders, 613 const ScopedVector<google_apis::FileResource>& app_root_folders,
624 const SyncStatusCallback& callback) { 614 const SyncStatusCallback& callback) {
625 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 615 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
626 616
627 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 617 index_->SetLargestChangeID(largest_change_id);
628 index_->SetLargestChangeID(largest_change_id, batch.get());
629 UpdateLargestKnownChangeID(largest_change_id); 618 UpdateLargestKnownChangeID(largest_change_id);
630 619
631 AttachSyncRoot(sync_root_folder, batch.get()); 620 AttachSyncRoot(sync_root_folder);
632 for (size_t i = 0; i < app_root_folders.size(); ++i) 621 for (size_t i = 0; i < app_root_folders.size(); ++i)
633 AttachInitialAppRoot(*app_root_folders[i], batch.get()); 622 AttachInitialAppRoot(*app_root_folders[i]);
634 623
635 WriteToDatabase(batch.Pass(), callback); 624 WriteToDatabase(callback);
636 } 625 }
637 626
638 bool MetadataDatabase::IsAppEnabled(const std::string& app_id) const { 627 bool MetadataDatabase::IsAppEnabled(const std::string& app_id) const {
639 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 628 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
640 629
641 int64 tracker_id = index_->GetAppRootTracker(app_id); 630 int64 tracker_id = index_->GetAppRootTracker(app_id);
642 if (tracker_id == kInvalidTrackerID) 631 if (tracker_id == kInvalidTrackerID)
643 return false; 632 return false;
644 633
645 FileTracker tracker; 634 FileTracker tracker;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 680
692 scoped_ptr<FileTracker> tracker(new FileTracker); 681 scoped_ptr<FileTracker> tracker(new FileTracker);
693 if (!FilterFileTrackersByParent(index_.get(), trackers, 682 if (!FilterFileTrackersByParent(index_.get(), trackers,
694 sync_root_tracker_id, tracker.get())) { 683 sync_root_tracker_id, tracker.get())) {
695 worker_task_runner_->PostTask( 684 worker_task_runner_->PostTask(
696 FROM_HERE, 685 FROM_HERE,
697 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND)); 686 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
698 return; 687 return;
699 } 688 }
700 689
701 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
702 tracker->set_app_id(app_id); 690 tracker->set_app_id(app_id);
703 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT); 691 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
704 tracker->set_active(true); 692 tracker->set_active(true);
705 tracker->set_needs_folder_listing(true); 693 tracker->set_needs_folder_listing(true);
706 tracker->set_dirty(true); 694 tracker->set_dirty(true);
707 695
708 index_->StoreFileTracker(tracker.Pass(), batch.get()); 696 index_->StoreFileTracker(tracker.Pass());
709 WriteToDatabase(batch.Pass(), callback); 697 WriteToDatabase(callback);
710 } 698 }
711 699
712 void MetadataDatabase::DisableApp(const std::string& app_id, 700 void MetadataDatabase::DisableApp(const std::string& app_id,
713 const SyncStatusCallback& callback) { 701 const SyncStatusCallback& callback) {
714 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 702 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
715 703
716 int64 tracker_id = index_->GetAppRootTracker(app_id); 704 int64 tracker_id = index_->GetAppRootTracker(app_id);
717 scoped_ptr<FileTracker> tracker(new FileTracker); 705 scoped_ptr<FileTracker> tracker(new FileTracker);
718 if (!index_->GetFileTracker(tracker_id, tracker.get())) { 706 if (!index_->GetFileTracker(tracker_id, tracker.get())) {
719 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND); 707 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND);
720 return; 708 return;
721 } 709 }
722 710
723 if (tracker->tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT) { 711 if (tracker->tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT) {
724 callback.Run(SYNC_STATUS_OK); 712 callback.Run(SYNC_STATUS_OK);
725 return; 713 return;
726 } 714 }
727 715
728 DCHECK_EQ(TRACKER_KIND_APP_ROOT, tracker->tracker_kind()); 716 DCHECK_EQ(TRACKER_KIND_APP_ROOT, tracker->tracker_kind());
729 DCHECK(tracker->active()); 717 DCHECK(tracker->active());
730 718
731 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
732
733 // Keep the app-root tracker active (but change the tracker_kind) so that 719 // Keep the app-root tracker active (but change the tracker_kind) so that
734 // other conflicting trackers won't become active. 720 // other conflicting trackers won't become active.
735 tracker->set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT); 721 tracker->set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT);
736 722
737 index_->StoreFileTracker(tracker.Pass(), batch.get()); 723 index_->StoreFileTracker(tracker.Pass());
738 WriteToDatabase(batch.Pass(), callback); 724 WriteToDatabase(callback);
739 } 725 }
740 726
741 void MetadataDatabase::EnableApp(const std::string& app_id, 727 void MetadataDatabase::EnableApp(const std::string& app_id,
742 const SyncStatusCallback& callback) { 728 const SyncStatusCallback& callback) {
743 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 729 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
744 730
745 int64 tracker_id = index_->GetAppRootTracker(app_id); 731 int64 tracker_id = index_->GetAppRootTracker(app_id);
746 scoped_ptr<FileTracker> tracker(new FileTracker); 732 scoped_ptr<FileTracker> tracker(new FileTracker);
747 if (!index_->GetFileTracker(tracker_id, tracker.get())) { 733 if (!index_->GetFileTracker(tracker_id, tracker.get())) {
748 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND); 734 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND);
749 return; 735 return;
750 } 736 }
751 737
752 if (tracker->tracker_kind() == TRACKER_KIND_APP_ROOT) { 738 if (tracker->tracker_kind() == TRACKER_KIND_APP_ROOT) {
753 callback.Run(SYNC_STATUS_OK); 739 callback.Run(SYNC_STATUS_OK);
754 return; 740 return;
755 } 741 }
756 742
757 DCHECK_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker->tracker_kind()); 743 DCHECK_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker->tracker_kind());
758 DCHECK(tracker->active()); 744 DCHECK(tracker->active());
759 745
760 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 746 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
747 index_->StoreFileTracker(tracker.Pass());
761 748
762 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT); 749 MarkTrackersDirtyRecursively(tracker_id, index_.get());
763 index_->StoreFileTracker(tracker.Pass(), batch.get()); 750 WriteToDatabase(callback);
764
765 MarkTrackersDirtyRecursively(tracker_id, index_.get(), batch.get());
766 WriteToDatabase(batch.Pass(), callback);
767 } 751 }
768 752
769 void MetadataDatabase::UnregisterApp(const std::string& app_id, 753 void MetadataDatabase::UnregisterApp(const std::string& app_id,
770 const SyncStatusCallback& callback) { 754 const SyncStatusCallback& callback) {
771 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 755 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
772 756
773 int64 tracker_id = index_->GetAppRootTracker(app_id); 757 int64 tracker_id = index_->GetAppRootTracker(app_id);
774 scoped_ptr<FileTracker> tracker(new FileTracker); 758 scoped_ptr<FileTracker> tracker(new FileTracker);
775 if (!index_->GetFileTracker(tracker_id, tracker.get()) || 759 if (!index_->GetFileTracker(tracker_id, tracker.get()) ||
776 tracker->tracker_kind() == TRACKER_KIND_REGULAR) { 760 tracker->tracker_kind() == TRACKER_KIND_REGULAR) {
777 worker_task_runner_->PostTask( 761 worker_task_runner_->PostTask(
778 FROM_HERE, 762 FROM_HERE,
779 base::Bind(callback, SYNC_STATUS_OK)); 763 base::Bind(callback, SYNC_STATUS_OK));
780 return; 764 return;
781 } 765 }
782 766
783 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 767 RemoveAllDescendantTrackers(tracker_id, index_.get());
784 RemoveAllDescendantTrackers(tracker_id, index_.get(), batch.get());
785 768
786 tracker->clear_app_id(); 769 tracker->clear_app_id();
787 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); 770 tracker->set_tracker_kind(TRACKER_KIND_REGULAR);
788 tracker->set_active(false); 771 tracker->set_active(false);
789 tracker->set_dirty(true); 772 tracker->set_dirty(true);
790 773
791 index_->StoreFileTracker(tracker.Pass(), batch.get()); 774 index_->StoreFileTracker(tracker.Pass());
792 WriteToDatabase(batch.Pass(), callback); 775 WriteToDatabase(callback);
793 } 776 }
794 777
795 bool MetadataDatabase::FindAppRootTracker(const std::string& app_id, 778 bool MetadataDatabase::FindAppRootTracker(const std::string& app_id,
796 FileTracker* tracker_out) const { 779 FileTracker* tracker_out) const {
797 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 780 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
798 781
799 int64 app_root_tracker_id = index_->GetAppRootTracker(app_id); 782 int64 app_root_tracker_id = index_->GetAppRootTracker(app_id);
800 if (!app_root_tracker_id) 783 if (!app_root_tracker_id)
801 return false; 784 return false;
802 785
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 return true; 922 return true;
940 } 923 }
941 924
942 void MetadataDatabase::UpdateByChangeList( 925 void MetadataDatabase::UpdateByChangeList(
943 int64 largest_change_id, 926 int64 largest_change_id,
944 ScopedVector<google_apis::ChangeResource> changes, 927 ScopedVector<google_apis::ChangeResource> changes,
945 const SyncStatusCallback& callback) { 928 const SyncStatusCallback& callback) {
946 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 929 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
947 DCHECK_LE(index_->GetLargestChangeID(), largest_change_id); 930 DCHECK_LE(index_->GetLargestChangeID(), largest_change_id);
948 931
949 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
950
951 for (size_t i = 0; i < changes.size(); ++i) { 932 for (size_t i = 0; i < changes.size(); ++i) {
952 const google_apis::ChangeResource& change = *changes[i]; 933 const google_apis::ChangeResource& change = *changes[i];
953 if (HasNewerFileMetadata(change.file_id(), change.change_id())) 934 if (HasNewerFileMetadata(change.file_id(), change.change_id()))
954 continue; 935 continue;
955 936
956 scoped_ptr<FileMetadata> metadata( 937 scoped_ptr<FileMetadata> metadata(
957 CreateFileMetadataFromChangeResource(change)); 938 CreateFileMetadataFromChangeResource(change));
958 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 939 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
959 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 940 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
960 batch.get());
961 } 941 }
962 942
963 UpdateLargestKnownChangeID(largest_change_id); 943 UpdateLargestKnownChangeID(largest_change_id);
964 index_->SetLargestChangeID(largest_change_id, batch.get()); 944 index_->SetLargestChangeID(largest_change_id);
965 WriteToDatabase(batch.Pass(), callback); 945 WriteToDatabase(callback);
966 } 946 }
967 947
968 void MetadataDatabase::UpdateByFileResource( 948 void MetadataDatabase::UpdateByFileResource(
969 const google_apis::FileResource& resource, 949 const google_apis::FileResource& resource,
970 const SyncStatusCallback& callback) { 950 const SyncStatusCallback& callback) {
971 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 951 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
972 952
973 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
974
975 scoped_ptr<FileMetadata> metadata( 953 scoped_ptr<FileMetadata> metadata(
976 CreateFileMetadataFromFileResource( 954 CreateFileMetadataFromFileResource(
977 GetLargestKnownChangeID(), resource)); 955 GetLargestKnownChangeID(), resource));
978 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 956 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
979 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 957 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
980 batch.get()); 958 WriteToDatabase(callback);
981 WriteToDatabase(batch.Pass(), callback);
982 } 959 }
983 960
984 void MetadataDatabase::UpdateByFileResourceList( 961 void MetadataDatabase::UpdateByFileResourceList(
985 ScopedVector<google_apis::FileResource> resources, 962 ScopedVector<google_apis::FileResource> resources,
986 const SyncStatusCallback& callback) { 963 const SyncStatusCallback& callback) {
987 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 964 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
988 965
989 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
990
991 for (size_t i = 0; i < resources.size(); ++i) { 966 for (size_t i = 0; i < resources.size(); ++i) {
992 scoped_ptr<FileMetadata> metadata( 967 scoped_ptr<FileMetadata> metadata(
993 CreateFileMetadataFromFileResource( 968 CreateFileMetadataFromFileResource(
994 GetLargestKnownChangeID(), *resources[i])); 969 GetLargestKnownChangeID(), *resources[i]));
995 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 970 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
996 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 971 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
997 batch.get());
998 } 972 }
999 WriteToDatabase(batch.Pass(), callback); 973 WriteToDatabase(callback);
1000 } 974 }
1001 975
1002 void MetadataDatabase::UpdateByDeletedRemoteFile( 976 void MetadataDatabase::UpdateByDeletedRemoteFile(
1003 const std::string& file_id, 977 const std::string& file_id,
1004 const SyncStatusCallback& callback) { 978 const SyncStatusCallback& callback) {
1005 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 979 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1006 980
1007 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1008 scoped_ptr<FileMetadata> metadata( 981 scoped_ptr<FileMetadata> metadata(
1009 CreateDeletedFileMetadata(GetLargestKnownChangeID(), file_id)); 982 CreateDeletedFileMetadata(GetLargestKnownChangeID(), file_id));
1010 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 983 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
1011 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 984 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1012 batch.get()); 985 WriteToDatabase(callback);
1013 WriteToDatabase(batch.Pass(), callback);
1014 } 986 }
1015 987
1016 void MetadataDatabase::UpdateByDeletedRemoteFileList( 988 void MetadataDatabase::UpdateByDeletedRemoteFileList(
1017 const FileIDList& file_ids, 989 const FileIDList& file_ids,
1018 const SyncStatusCallback& callback) { 990 const SyncStatusCallback& callback) {
1019 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 991 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1020 992
1021 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1022 for (FileIDList::const_iterator itr = file_ids.begin(); 993 for (FileIDList::const_iterator itr = file_ids.begin();
1023 itr != file_ids.end(); ++itr) { 994 itr != file_ids.end(); ++itr) {
1024 scoped_ptr<FileMetadata> metadata( 995 scoped_ptr<FileMetadata> metadata(
1025 CreateDeletedFileMetadata(GetLargestKnownChangeID(), *itr)); 996 CreateDeletedFileMetadata(GetLargestKnownChangeID(), *itr));
1026 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 997 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
1027 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 998 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1028 batch.get());
1029 } 999 }
1030 WriteToDatabase(batch.Pass(), callback); 1000 WriteToDatabase(callback);
1031 } 1001 }
1032 1002
1033 void MetadataDatabase::ReplaceActiveTrackerWithNewResource( 1003 void MetadataDatabase::ReplaceActiveTrackerWithNewResource(
1034 int64 parent_tracker_id, 1004 int64 parent_tracker_id,
1035 const google_apis::FileResource& resource, 1005 const google_apis::FileResource& resource,
1036 const SyncStatusCallback& callback) { 1006 const SyncStatusCallback& callback) {
1037 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1007 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1038 1008
1039 DCHECK(!index_->GetFileMetadata(resource.file_id(), NULL)); 1009 DCHECK(!index_->GetFileMetadata(resource.file_id(), NULL));
1040 DCHECK(index_->GetFileTracker(parent_tracker_id, NULL)); 1010 DCHECK(index_->GetFileTracker(parent_tracker_id, NULL));
1041 1011
1042 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1043 UpdateByFileMetadata( 1012 UpdateByFileMetadata(
1044 FROM_HERE, 1013 FROM_HERE,
1045 CreateFileMetadataFromFileResource(GetLargestKnownChangeID(), resource), 1014 CreateFileMetadataFromFileResource(GetLargestKnownChangeID(), resource),
1046 UPDATE_TRACKER_FOR_SYNCED_FILE, 1015 UPDATE_TRACKER_FOR_SYNCED_FILE);
1047 batch.get());
1048 1016
1049 DCHECK(index_->GetFileMetadata(resource.file_id(), NULL)); 1017 DCHECK(index_->GetFileMetadata(resource.file_id(), NULL));
1050 DCHECK(!index_->GetFileTrackerIDsByFileID(resource.file_id()).has_active()); 1018 DCHECK(!index_->GetFileTrackerIDsByFileID(resource.file_id()).has_active());
1051 1019
1052 TrackerIDSet same_path_trackers = 1020 TrackerIDSet same_path_trackers =
1053 index_->GetFileTrackerIDsByParentAndTitle( 1021 index_->GetFileTrackerIDsByParentAndTitle(
1054 parent_tracker_id, resource.title()); 1022 parent_tracker_id, resource.title());
1055 FileTracker to_be_activated; 1023 FileTracker to_be_activated;
1056 if (!FilterFileTrackersByFileID(index_.get(), same_path_trackers, 1024 if (!FilterFileTrackersByFileID(index_.get(), same_path_trackers,
1057 resource.file_id(), &to_be_activated)) { 1025 resource.file_id(), &to_be_activated)) {
1058 NOTREACHED(); 1026 NOTREACHED();
1059 worker_task_runner_->PostTask( 1027 worker_task_runner_->PostTask(
1060 FROM_HERE, 1028 FROM_HERE,
1061 base::Bind(callback, SYNC_STATUS_FAILED)); 1029 base::Bind(callback, SYNC_STATUS_FAILED));
1062 return; 1030 return;
1063 } 1031 }
1064 1032
1065 int64 tracker_id = to_be_activated.tracker_id(); 1033 int64 tracker_id = to_be_activated.tracker_id();
1066 if (same_path_trackers.has_active()) { 1034 if (same_path_trackers.has_active()) {
1067 DeactivateFileTracker(same_path_trackers.active_tracker(), 1035 DeactivateFileTracker(same_path_trackers.active_tracker(),
1068 MARK_ITSELF_DIRTY | 1036 MARK_ITSELF_DIRTY |
1069 MARK_SAME_FILE_ID_TRACKERS_DIRTY, 1037 MARK_SAME_FILE_ID_TRACKERS_DIRTY,
1070 index_.get(), batch.get()); 1038 index_.get());
1071 } 1039 }
1072 1040
1073 ActivateFileTracker(tracker_id, MARK_NOTHING_DIRTY, 1041 ActivateFileTracker(tracker_id, MARK_NOTHING_DIRTY, index_.get());
1074 index_.get(), batch.get()); 1042 WriteToDatabase(callback);
1075 WriteToDatabase(batch.Pass(), callback);
1076 } 1043 }
1077 1044
1078 void MetadataDatabase::PopulateFolderByChildList( 1045 void MetadataDatabase::PopulateFolderByChildList(
1079 const std::string& folder_id, 1046 const std::string& folder_id,
1080 const FileIDList& child_file_ids, 1047 const FileIDList& child_file_ids,
1081 const SyncStatusCallback& callback) { 1048 const SyncStatusCallback& callback) {
1082 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1049 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1083 1050
1084 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(folder_id); 1051 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(folder_id);
1085 if (!trackers.has_active()) { 1052 if (!trackers.has_active()) {
(...skipping 22 matching lines...) Expand all
1108 index_->GetFileTrackerIDsByParent(folder_tracker->tracker_id()); 1075 index_->GetFileTrackerIDsByParent(folder_tracker->tracker_id());
1109 for (size_t i = 0; i < known_children.size(); ++i) { 1076 for (size_t i = 0; i < known_children.size(); ++i) {
1110 FileTracker tracker; 1077 FileTracker tracker;
1111 if (!index_->GetFileTracker(known_children[i], &tracker)) { 1078 if (!index_->GetFileTracker(known_children[i], &tracker)) {
1112 NOTREACHED(); 1079 NOTREACHED();
1113 continue; 1080 continue;
1114 } 1081 }
1115 children.erase(tracker.file_id()); 1082 children.erase(tracker.file_id());
1116 } 1083 }
1117 1084
1118 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1119 for (base::hash_set<std::string>::const_iterator itr = children.begin(); 1085 for (base::hash_set<std::string>::const_iterator itr = children.begin();
1120 itr != children.end(); ++itr) 1086 itr != children.end(); ++itr)
1121 CreateTrackerForParentAndFileID(*folder_tracker, *itr, batch.get()); 1087 CreateTrackerForParentAndFileID(*folder_tracker, *itr);
1122 folder_tracker->set_needs_folder_listing(false); 1088 folder_tracker->set_needs_folder_listing(false);
1123 if (folder_tracker->dirty() && !ShouldKeepDirty(*folder_tracker)) 1089 if (folder_tracker->dirty() && !ShouldKeepDirty(*folder_tracker))
1124 folder_tracker->set_dirty(false); 1090 folder_tracker->set_dirty(false);
1125 index_->StoreFileTracker(folder_tracker.Pass(), batch.get()); 1091 index_->StoreFileTracker(folder_tracker.Pass());
1126 1092
1127 WriteToDatabase(batch.Pass(), callback); 1093 WriteToDatabase(callback);
1128 } 1094 }
1129 1095
1130 void MetadataDatabase::UpdateTracker(int64 tracker_id, 1096 void MetadataDatabase::UpdateTracker(int64 tracker_id,
1131 const FileDetails& updated_details, 1097 const FileDetails& updated_details,
1132 const SyncStatusCallback& callback) { 1098 const SyncStatusCallback& callback) {
1133 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1099 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1134 1100
1135 FileTracker tracker; 1101 FileTracker tracker;
1136 if (!index_->GetFileTracker(tracker_id, &tracker)) { 1102 if (!index_->GetFileTracker(tracker_id, &tracker)) {
1137 worker_task_runner_->PostTask( 1103 worker_task_runner_->PostTask(
1138 FROM_HERE, 1104 FROM_HERE,
1139 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND)); 1105 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
1140 return; 1106 return;
1141 } 1107 }
1142 1108
1143 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1144
1145 // Check if the tracker is to be deleted. 1109 // Check if the tracker is to be deleted.
1146 if (updated_details.missing()) { 1110 if (updated_details.missing()) {
1147 FileMetadata metadata; 1111 FileMetadata metadata;
1148 if (!index_->GetFileMetadata(tracker.file_id(), &metadata) || 1112 if (!index_->GetFileMetadata(tracker.file_id(), &metadata) ||
1149 metadata.details().missing()) { 1113 metadata.details().missing()) {
1150 // Both the tracker and metadata have the missing flag, now it's safe to 1114 // Both the tracker and metadata have the missing flag, now it's safe to
1151 // delete the |tracker|. 1115 // delete the |tracker|.
1152 RemoveFileTracker(tracker_id, 1116 RemoveFileTracker(tracker_id,
1153 MARK_SAME_FILE_ID_TRACKERS_DIRTY | 1117 MARK_SAME_FILE_ID_TRACKERS_DIRTY |
1154 MARK_SAME_PATH_TRACKERS_DIRTY, 1118 MARK_SAME_PATH_TRACKERS_DIRTY,
1155 index_.get(), batch.get()); 1119 index_.get());
1156 WriteToDatabase(batch.Pass(), callback); 1120 WriteToDatabase(callback);
1157 return; 1121 return;
1158 } 1122 }
1159 } 1123 }
1160 1124
1161 // Sync-root deletion should be handled separately by SyncEngine. 1125 // Sync-root deletion should be handled separately by SyncEngine.
1162 DCHECK(tracker_id != GetSyncRootTrackerID() || 1126 DCHECK(tracker_id != GetSyncRootTrackerID() ||
1163 (tracker.has_synced_details() && 1127 (tracker.has_synced_details() &&
1164 tracker.synced_details().title() == updated_details.title() && 1128 tracker.synced_details().title() == updated_details.title() &&
1165 !updated_details.missing())); 1129 !updated_details.missing()));
1166 1130
1167 if (tracker_id != GetSyncRootTrackerID()) { 1131 if (tracker_id != GetSyncRootTrackerID()) {
1168 // Check if the tracker's parent is still in |parent_tracker_ids|. 1132 // Check if the tracker's parent is still in |parent_tracker_ids|.
1169 // If not, there should exist another tracker for the new parent, so delete 1133 // If not, there should exist another tracker for the new parent, so delete
1170 // old tracker. 1134 // old tracker.
1171 FileTracker parent_tracker; 1135 FileTracker parent_tracker;
1172 index_->GetFileTracker(tracker.parent_tracker_id(), &parent_tracker); 1136 index_->GetFileTracker(tracker.parent_tracker_id(), &parent_tracker);
1173 1137
1174 if (!HasFileAsParent(updated_details, parent_tracker.file_id())) { 1138 if (!HasFileAsParent(updated_details, parent_tracker.file_id())) {
1175 RemoveFileTracker(tracker.tracker_id(), 1139 RemoveFileTracker(tracker.tracker_id(),
1176 MARK_SAME_PATH_TRACKERS_DIRTY, 1140 MARK_SAME_PATH_TRACKERS_DIRTY,
1177 index_.get(), batch.get()); 1141 index_.get());
1178 WriteToDatabase(batch.Pass(), callback); 1142 WriteToDatabase(callback);
1179 return; 1143 return;
1180 } 1144 }
1181 1145
1182 if (tracker.has_synced_details()) { 1146 if (tracker.has_synced_details()) {
1183 // Check if the tracker was retitled. If it was, there should exist 1147 // Check if the tracker was retitled. If it was, there should exist
1184 // another tracker for the new title, so delete the tracker being updated. 1148 // another tracker for the new title, so delete the tracker being updated.
1185 if (tracker.synced_details().title() != updated_details.title()) { 1149 if (tracker.synced_details().title() != updated_details.title()) {
1186 RemoveFileTracker(tracker.tracker_id(), 1150 RemoveFileTracker(tracker.tracker_id(),
1187 MARK_SAME_FILE_ID_TRACKERS_DIRTY, 1151 MARK_SAME_FILE_ID_TRACKERS_DIRTY,
1188 index_.get(), batch.get()); 1152 index_.get());
1189 WriteToDatabase(batch.Pass(), callback); 1153 WriteToDatabase(callback);
1190 return; 1154 return;
1191 } 1155 }
1192 } else { 1156 } else {
1193 // Check if any other tracker exists has the same parent, title and 1157 // Check if any other tracker exists has the same parent, title and
1194 // file_id to the updated tracker. If it exists, delete the tracker being 1158 // file_id to the updated tracker. If it exists, delete the tracker being
1195 // updated. 1159 // updated.
1196 if (FilterFileTrackersByFileID( 1160 if (FilterFileTrackersByFileID(
1197 index_.get(), 1161 index_.get(),
1198 index_->GetFileTrackerIDsByParentAndTitle( 1162 index_->GetFileTrackerIDsByParentAndTitle(
1199 parent_tracker.tracker_id(), 1163 parent_tracker.tracker_id(),
1200 updated_details.title()), 1164 updated_details.title()),
1201 tracker.file_id(), 1165 tracker.file_id(),
1202 NULL)) { 1166 NULL)) {
1203 RemoveFileTracker(tracker.tracker_id(), 1167 RemoveFileTracker(tracker.tracker_id(),
1204 MARK_NOTHING_DIRTY, 1168 MARK_NOTHING_DIRTY,
1205 index_.get(), batch.get()); 1169 index_.get());
1206 WriteToDatabase(batch.Pass(), callback); 1170 WriteToDatabase(callback);
1207 return; 1171 return;
1208 } 1172 }
1209 } 1173 }
1210 } 1174 }
1211 1175
1212 scoped_ptr<FileTracker> updated_tracker = CloneFileTracker(&tracker); 1176 scoped_ptr<FileTracker> updated_tracker = CloneFileTracker(&tracker);
1213 *updated_tracker->mutable_synced_details() = updated_details; 1177 *updated_tracker->mutable_synced_details() = updated_details;
1214 1178
1215 // Activate the tracker if: 1179 // Activate the tracker if:
1216 // - There is no active tracker that tracks |tracker->file_id()|. 1180 // - There is no active tracker that tracks |tracker->file_id()|.
1217 // - There is no active tracker that has the same |parent| and |title|. 1181 // - There is no active tracker that has the same |parent| and |title|.
1218 if (!tracker.active() && CanActivateTracker(tracker)) { 1182 if (!tracker.active() && CanActivateTracker(tracker)) {
1219 updated_tracker->set_active(true); 1183 updated_tracker->set_active(true);
1220 updated_tracker->set_dirty(true); 1184 updated_tracker->set_dirty(true);
1221 updated_tracker->set_needs_folder_listing( 1185 updated_tracker->set_needs_folder_listing(
1222 tracker.synced_details().file_kind() == FILE_KIND_FOLDER); 1186 tracker.synced_details().file_kind() == FILE_KIND_FOLDER);
1223 } else if (tracker.dirty() && !ShouldKeepDirty(tracker)) { 1187 } else if (tracker.dirty() && !ShouldKeepDirty(tracker)) {
1224 updated_tracker->set_dirty(false); 1188 updated_tracker->set_dirty(false);
1225 } 1189 }
1226 index_->StoreFileTracker(updated_tracker.Pass(), batch.get()); 1190 index_->StoreFileTracker(updated_tracker.Pass());
1227 1191
1228 WriteToDatabase(batch.Pass(), callback); 1192 WriteToDatabase(callback);
1229 } 1193 }
1230 1194
1231 MetadataDatabase::ActivationStatus MetadataDatabase::TryActivateTracker( 1195 MetadataDatabase::ActivationStatus MetadataDatabase::TryActivateTracker(
1232 int64 parent_tracker_id, 1196 int64 parent_tracker_id,
1233 const std::string& file_id, 1197 const std::string& file_id,
1234 const SyncStatusCallback& callback) { 1198 const SyncStatusCallback& callback) {
1235 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1199 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1236 1200
1237 FileMetadata metadata; 1201 FileMetadata metadata;
1238 if (!index_->GetFileMetadata(file_id, &metadata)) { 1202 if (!index_->GetFileMetadata(file_id, &metadata)) {
(...skipping 12 matching lines...) Expand all
1251 FilterFileTrackersByParentAndTitle( 1215 FilterFileTrackersByParentAndTitle(
1252 index_.get(), same_file_id_trackers, parent_tracker_id, 1216 index_.get(), same_file_id_trackers, parent_tracker_id,
1253 title, tracker_to_be_activated.get()); 1217 title, tracker_to_be_activated.get());
1254 1218
1255 // Check if there is another active tracker that tracks |file_id|. 1219 // Check if there is another active tracker that tracks |file_id|.
1256 // This can happen when the tracked file has multiple parents. 1220 // This can happen when the tracked file has multiple parents.
1257 // In this case, report the failure to the caller. 1221 // In this case, report the failure to the caller.
1258 if (!tracker_to_be_activated->active() && same_file_id_trackers.has_active()) 1222 if (!tracker_to_be_activated->active() && same_file_id_trackers.has_active())
1259 return ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER; 1223 return ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER;
1260 1224
1261 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1262
1263 if (!tracker_to_be_activated->active()) { 1225 if (!tracker_to_be_activated->active()) {
1264 // Check if there exists another active tracker that has the same path to 1226 // Check if there exists another active tracker that has the same path to
1265 // the tracker. If there is, deactivate it, assuming the caller already 1227 // the tracker. If there is, deactivate it, assuming the caller already
1266 // overrides local file with newly added file, 1228 // overrides local file with newly added file,
1267 TrackerIDSet same_title_trackers = 1229 TrackerIDSet same_title_trackers =
1268 index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title); 1230 index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title);
1269 if (same_title_trackers.has_active()) { 1231 if (same_title_trackers.has_active()) {
1270 RemoveAllDescendantTrackers(same_title_trackers.active_tracker(), 1232 RemoveAllDescendantTrackers(same_title_trackers.active_tracker(),
1271 index_.get(), batch.get()); 1233 index_.get());
1272 1234
1273 scoped_ptr<FileTracker> tracker_to_be_deactivated(new FileTracker); 1235 scoped_ptr<FileTracker> tracker_to_be_deactivated(new FileTracker);
1274 if (index_->GetFileTracker(same_title_trackers.active_tracker(), 1236 if (index_->GetFileTracker(same_title_trackers.active_tracker(),
1275 tracker_to_be_deactivated.get())) { 1237 tracker_to_be_deactivated.get())) {
1276 const std::string file_id = tracker_to_be_deactivated->file_id(); 1238 const std::string file_id = tracker_to_be_deactivated->file_id();
1277 tracker_to_be_deactivated->set_active(false); 1239 tracker_to_be_deactivated->set_active(false);
1278 index_->StoreFileTracker(tracker_to_be_deactivated.Pass(), batch.get()); 1240 index_->StoreFileTracker(tracker_to_be_deactivated.Pass());
1279 1241
1280 MarkTrackersDirtyByFileID(file_id, index_.get(), batch.get()); 1242 MarkTrackersDirtyByFileID(file_id, index_.get());
1281 } else { 1243 } else {
1282 NOTREACHED(); 1244 NOTREACHED();
1283 } 1245 }
1284 } 1246 }
1285 } 1247 }
1286 1248
1287 tracker_to_be_activated->set_dirty(false); 1249 tracker_to_be_activated->set_dirty(false);
1288 tracker_to_be_activated->set_active(true); 1250 tracker_to_be_activated->set_active(true);
1289 *tracker_to_be_activated->mutable_synced_details() = metadata.details(); 1251 *tracker_to_be_activated->mutable_synced_details() = metadata.details();
1290 if (tracker_to_be_activated->synced_details().file_kind() == 1252 if (tracker_to_be_activated->synced_details().file_kind() ==
1291 FILE_KIND_FOLDER) { 1253 FILE_KIND_FOLDER) {
1292 tracker_to_be_activated->set_needs_folder_listing(true); 1254 tracker_to_be_activated->set_needs_folder_listing(true);
1293 } 1255 }
1294 tracker_to_be_activated->set_dirty(false); 1256 tracker_to_be_activated->set_dirty(false);
1295 1257
1296 index_->StoreFileTracker(tracker_to_be_activated.Pass(), batch.get()); 1258 index_->StoreFileTracker(tracker_to_be_activated.Pass());
1297 1259
1298 WriteToDatabase(batch.Pass(), callback); 1260 WriteToDatabase(callback);
1299 return ACTIVATION_PENDING; 1261 return ACTIVATION_PENDING;
1300 } 1262 }
1301 1263
1302 void MetadataDatabase::LowerTrackerPriority(int64 tracker_id) { 1264 void MetadataDatabase::LowerTrackerPriority(int64 tracker_id) {
1303 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1265 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1304 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 1266 index_->DemoteDirtyTracker(tracker_id);
1305 index_->DemoteDirtyTracker(tracker_id, batch.get()); 1267 WriteToDatabase(base::Bind(&EmptyStatusCallback));
1306 WriteToDatabase(batch.Pass(), base::Bind(&EmptyStatusCallback));
1307 } 1268 }
1308 1269
1309 void MetadataDatabase::PromoteLowerPriorityTrackersToNormal() { 1270 void MetadataDatabase::PromoteLowerPriorityTrackersToNormal() {
1310 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1271 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1311 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 1272 index_->PromoteDemotedDirtyTrackers();
1312 index_->PromoteDemotedDirtyTrackers(batch.get()); 1273 WriteToDatabase(base::Bind(&EmptyStatusCallback));
1313 WriteToDatabase(batch.Pass(), base::Bind(&EmptyStatusCallback));
1314 } 1274 }
1315 1275
1316 bool MetadataDatabase::GetNormalPriorityDirtyTracker( 1276 bool MetadataDatabase::GetNormalPriorityDirtyTracker(
1317 FileTracker* tracker_out) const { 1277 FileTracker* tracker_out) const {
1318 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1278 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1319 1279
1320 int64 dirty_tracker_id = index_->PickDirtyTracker(); 1280 int64 dirty_tracker_id = index_->PickDirtyTracker();
1321 if (!dirty_tracker_id) 1281 if (!dirty_tracker_id)
1322 return false; 1282 return false;
1323 1283
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 if (status != SYNC_STATUS_OK) 1406 if (status != SYNC_STATUS_OK)
1447 return status; 1407 return status;
1448 } 1408 }
1449 1409
1450 if (!created) { 1410 if (!created) {
1451 status = MigrateDatabaseIfNeeded(db_.get()); 1411 status = MigrateDatabaseIfNeeded(db_.get());
1452 if (status != SYNC_STATUS_OK) 1412 if (status != SYNC_STATUS_OK)
1453 return status; 1413 return status;
1454 } 1414 }
1455 1415
1456 leveldb::WriteBatch batch; 1416 index_ = MetadataDatabaseIndex::Create(db_.get());
1457 index_ = MetadataDatabaseIndex::Create(db_.get(), &batch);
1458 1417
1459 status = LevelDBStatusToSyncStatusCode( 1418 status = LevelDBStatusToSyncStatusCode(db_->Commit());
1460 db_->Write(leveldb::WriteOptions(), &batch));
1461 if (status != SYNC_STATUS_OK) 1419 if (status != SYNC_STATUS_OK)
1462 return status; 1420 return status;
1463 1421
1464 UpdateLargestKnownChangeID(index_->GetLargestChangeID()); 1422 UpdateLargestKnownChangeID(index_->GetLargestChangeID());
1465 1423
1466 return status; 1424 return status;
1467 } 1425 }
1468 1426
1469 void MetadataDatabase::CreateTrackerForParentAndFileID( 1427 void MetadataDatabase::CreateTrackerForParentAndFileID(
1470 const FileTracker& parent_tracker, 1428 const FileTracker& parent_tracker,
1471 const std::string& file_id, 1429 const std::string& file_id) {
1472 leveldb::WriteBatch* batch) {
1473 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1430 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1474 CreateTrackerInternal(parent_tracker, file_id, NULL, 1431 CreateTrackerInternal(parent_tracker, file_id, NULL,
1475 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 1432 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1476 batch);
1477 } 1433 }
1478 1434
1479 void MetadataDatabase::CreateTrackerForParentAndFileMetadata( 1435 void MetadataDatabase::CreateTrackerForParentAndFileMetadata(
1480 const FileTracker& parent_tracker, 1436 const FileTracker& parent_tracker,
1481 const FileMetadata& file_metadata, 1437 const FileMetadata& file_metadata,
1482 UpdateOption option, 1438 UpdateOption option) {
1483 leveldb::WriteBatch* batch) {
1484 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1439 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1485 DCHECK(file_metadata.has_details()); 1440 DCHECK(file_metadata.has_details());
1486 CreateTrackerInternal(parent_tracker, 1441 CreateTrackerInternal(parent_tracker,
1487 file_metadata.file_id(), 1442 file_metadata.file_id(),
1488 &file_metadata.details(), 1443 &file_metadata.details(),
1489 option, 1444 option);
1490 batch);
1491 } 1445 }
1492 1446
1493 void MetadataDatabase::CreateTrackerInternal(const FileTracker& parent_tracker, 1447 void MetadataDatabase::CreateTrackerInternal(const FileTracker& parent_tracker,
1494 const std::string& file_id, 1448 const std::string& file_id,
1495 const FileDetails* details, 1449 const FileDetails* details,
1496 UpdateOption option, 1450 UpdateOption option) {
1497 leveldb::WriteBatch* batch) {
1498 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1451 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1499 1452
1500 int64 tracker_id = IncrementTrackerID(batch); 1453 int64 tracker_id = IncrementTrackerID();
1501 scoped_ptr<FileTracker> tracker(new FileTracker); 1454 scoped_ptr<FileTracker> tracker(new FileTracker);
1502 tracker->set_tracker_id(tracker_id); 1455 tracker->set_tracker_id(tracker_id);
1503 tracker->set_parent_tracker_id(parent_tracker.tracker_id()); 1456 tracker->set_parent_tracker_id(parent_tracker.tracker_id());
1504 tracker->set_file_id(file_id); 1457 tracker->set_file_id(file_id);
1505 tracker->set_app_id(parent_tracker.app_id()); 1458 tracker->set_app_id(parent_tracker.app_id());
1506 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); 1459 tracker->set_tracker_kind(TRACKER_KIND_REGULAR);
1507 tracker->set_dirty(true); 1460 tracker->set_dirty(true);
1508 tracker->set_active(false); 1461 tracker->set_active(false);
1509 tracker->set_needs_folder_listing(false); 1462 tracker->set_needs_folder_listing(false);
1510 if (details) { 1463 if (details) {
1511 *tracker->mutable_synced_details() = *details; 1464 *tracker->mutable_synced_details() = *details;
1512 if (option == UPDATE_TRACKER_FOR_UNSYNCED_FILE) { 1465 if (option == UPDATE_TRACKER_FOR_UNSYNCED_FILE) {
1513 tracker->mutable_synced_details()->set_missing(true); 1466 tracker->mutable_synced_details()->set_missing(true);
1514 tracker->mutable_synced_details()->clear_md5(); 1467 tracker->mutable_synced_details()->clear_md5();
1515 } 1468 }
1516 } 1469 }
1517 index_->StoreFileTracker(tracker.Pass(), batch); 1470 index_->StoreFileTracker(tracker.Pass());
1518 } 1471 }
1519 1472
1520 void MetadataDatabase::MaybeAddTrackersForNewFile( 1473 void MetadataDatabase::MaybeAddTrackersForNewFile(
1521 const FileMetadata& metadata, 1474 const FileMetadata& metadata,
1522 UpdateOption option, 1475 UpdateOption option) {
1523 leveldb::WriteBatch* batch) {
1524 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1476 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1525 1477
1526 std::set<int64> parents_to_exclude; 1478 std::set<int64> parents_to_exclude;
1527 TrackerIDSet existing_trackers = 1479 TrackerIDSet existing_trackers =
1528 index_->GetFileTrackerIDsByFileID(metadata.file_id()); 1480 index_->GetFileTrackerIDsByFileID(metadata.file_id());
1529 for (TrackerIDSet::const_iterator itr = existing_trackers.begin(); 1481 for (TrackerIDSet::const_iterator itr = existing_trackers.begin();
1530 itr != existing_trackers.end(); ++itr) { 1482 itr != existing_trackers.end(); ++itr) {
1531 FileTracker tracker; 1483 FileTracker tracker;
1532 if (!index_->GetFileTracker(*itr, &tracker)) { 1484 if (!index_->GetFileTracker(*itr, &tracker)) {
1533 NOTREACHED(); 1485 NOTREACHED();
(...skipping 20 matching lines...) Expand all
1554 itr != parent_trackers.end(); ++itr) { 1506 itr != parent_trackers.end(); ++itr) {
1555 FileTracker parent_tracker; 1507 FileTracker parent_tracker;
1556 index_->GetFileTracker(*itr, &parent_tracker); 1508 index_->GetFileTracker(*itr, &parent_tracker);
1557 if (!parent_tracker.active()) 1509 if (!parent_tracker.active())
1558 continue; 1510 continue;
1559 1511
1560 if (ContainsKey(parents_to_exclude, parent_tracker.tracker_id())) 1512 if (ContainsKey(parents_to_exclude, parent_tracker.tracker_id()))
1561 continue; 1513 continue;
1562 1514
1563 CreateTrackerForParentAndFileMetadata( 1515 CreateTrackerForParentAndFileMetadata(
1564 parent_tracker, metadata, option, batch); 1516 parent_tracker, metadata, option);
1565 } 1517 }
1566 } 1518 }
1567 } 1519 }
1568 1520
1569 int64 MetadataDatabase::IncrementTrackerID(leveldb::WriteBatch* batch) { 1521 int64 MetadataDatabase::IncrementTrackerID() {
1570 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1522 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1571 1523
1572 int64 tracker_id = index_->GetNextTrackerID(); 1524 int64 tracker_id = index_->GetNextTrackerID();
1573 index_->SetNextTrackerID(tracker_id + 1, batch); 1525 index_->SetNextTrackerID(tracker_id + 1);
1574 DCHECK_GT(tracker_id, 0); 1526 DCHECK_GT(tracker_id, 0);
1575 return tracker_id; 1527 return tracker_id;
1576 } 1528 }
1577 1529
1578 bool MetadataDatabase::CanActivateTracker(const FileTracker& tracker) { 1530 bool MetadataDatabase::CanActivateTracker(const FileTracker& tracker) {
1579 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1531 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1580 DCHECK(!tracker.active()); 1532 DCHECK(!tracker.active());
1581 DCHECK_NE(index_->GetSyncRootTrackerID(), tracker.tracker_id()); 1533 DCHECK_NE(index_->GetSyncRootTrackerID(), tracker.tracker_id());
1582 1534
1583 if (HasActiveTrackerForFileID(tracker.file_id())) 1535 if (HasActiveTrackerForFileID(tracker.file_id()))
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 } 1607 }
1656 1608
1657 bool MetadataDatabase::HasActiveTrackerForPath(int64 parent_tracker_id, 1609 bool MetadataDatabase::HasActiveTrackerForPath(int64 parent_tracker_id,
1658 const std::string& title) const { 1610 const std::string& title) const {
1659 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1611 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1660 return index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title) 1612 return index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title)
1661 .has_active(); 1613 .has_active();
1662 } 1614 }
1663 1615
1664 void MetadataDatabase::RemoveUnneededTrackersForMissingFile( 1616 void MetadataDatabase::RemoveUnneededTrackersForMissingFile(
1665 const std::string& file_id, 1617 const std::string& file_id) {
1666 leveldb::WriteBatch* batch) {
1667 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1618 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1668 1619
1669 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id); 1620 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id);
1670 for (TrackerIDSet::const_iterator itr = trackers.begin(); 1621 for (TrackerIDSet::const_iterator itr = trackers.begin();
1671 itr != trackers.end(); ++itr) { 1622 itr != trackers.end(); ++itr) {
1672 FileTracker tracker; 1623 FileTracker tracker;
1673 if (!index_->GetFileTracker(*itr, &tracker)) { 1624 if (!index_->GetFileTracker(*itr, &tracker)) {
1674 NOTREACHED(); 1625 NOTREACHED();
1675 continue; 1626 continue;
1676 } 1627 }
1677 1628
1678 if (!tracker.has_synced_details() || tracker.synced_details().missing()) { 1629 if (!tracker.has_synced_details() || tracker.synced_details().missing()) {
1679 RemoveFileTracker(*itr, MARK_NOTHING_DIRTY, index_.get(), batch); 1630 RemoveFileTracker(*itr, MARK_NOTHING_DIRTY, index_.get());
1680 } 1631 }
1681 } 1632 }
1682 } 1633 }
1683 1634
1684 void MetadataDatabase::UpdateByFileMetadata( 1635 void MetadataDatabase::UpdateByFileMetadata(
1685 const tracked_objects::Location& from_where, 1636 const tracked_objects::Location& from_where,
1686 scoped_ptr<FileMetadata> metadata, 1637 scoped_ptr<FileMetadata> metadata,
1687 UpdateOption option, 1638 UpdateOption option) {
1688 leveldb::WriteBatch* batch) {
1689 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1639 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1690 DCHECK(metadata); 1640 DCHECK(metadata);
1691 DCHECK(metadata->has_details()); 1641 DCHECK(metadata->has_details());
1692 1642
1693 DVLOG(1) << from_where.function_name() << ": " 1643 DVLOG(1) << from_where.function_name() << ": "
1694 << metadata->file_id() << " (" 1644 << metadata->file_id() << " ("
1695 << metadata->details().title() << ")" 1645 << metadata->details().title() << ")"
1696 << (metadata->details().missing() ? " deleted" : ""); 1646 << (metadata->details().missing() ? " deleted" : "");
1697 1647
1698 std::string file_id = metadata->file_id(); 1648 std::string file_id = metadata->file_id();
1699 if (metadata->details().missing()) 1649 if (metadata->details().missing())
1700 RemoveUnneededTrackersForMissingFile(file_id, batch); 1650 RemoveUnneededTrackersForMissingFile(file_id);
1701 else 1651 else
1702 MaybeAddTrackersForNewFile(*metadata, option, batch); 1652 MaybeAddTrackersForNewFile(*metadata, option);
1703 1653
1704 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id); 1654 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id);
1705 if (!trackers.empty()) { 1655 if (!trackers.empty()) {
1706 index_->StoreFileMetadata(metadata.Pass(), batch); 1656 index_->StoreFileMetadata(metadata.Pass());
1707 1657
1708 if (option != UPDATE_TRACKER_FOR_SYNCED_FILE) 1658 if (option != UPDATE_TRACKER_FOR_SYNCED_FILE)
1709 MarkTrackerSetDirty(trackers, index_.get(), batch); 1659 MarkTrackerSetDirty(trackers, index_.get());
1710 } 1660 }
1711 } 1661 }
1712 1662
1713 void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch, 1663 void MetadataDatabase::WriteToDatabase(const SyncStatusCallback& callback) {
1714 const SyncStatusCallback& callback) {
1715 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1664 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1716 1665
1717 if (!batch) { 1666 leveldb::Status status = db_->Commit();
1718 callback.Run(SYNC_STATUS_OK);
1719 return;
1720 }
1721
1722 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch.get());
1723 callback.Run(LevelDBStatusToSyncStatusCode(status)); 1667 callback.Run(LevelDBStatusToSyncStatusCode(status));
1724 } 1668 }
1725 1669
1726 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles( 1670 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles(
1727 const std::string& app_id) { 1671 const std::string& app_id) {
1728 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1672 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1729 1673
1730 scoped_ptr<base::ListValue> files(new base::ListValue); 1674 scoped_ptr<base::ListValue> files(new base::ListValue);
1731 1675
1732 FileTracker app_root_tracker; 1676 FileTracker app_root_tracker;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 for (int i = 0; i < details.parent_folder_ids_size(); ++i) 1843 for (int i = 0; i < details.parent_folder_ids_size(); ++i)
1900 parents.push_back(details.parent_folder_ids(i)); 1844 parents.push_back(details.parent_folder_ids(i));
1901 dict->SetString("parents", JoinString(parents, ",")); 1845 dict->SetString("parents", JoinString(parents, ","));
1902 } 1846 }
1903 files->Append(dict); 1847 files->Append(dict);
1904 } 1848 }
1905 return files.Pass(); 1849 return files.Pass();
1906 } 1850 }
1907 1851
1908 void MetadataDatabase::AttachSyncRoot( 1852 void MetadataDatabase::AttachSyncRoot(
1909 const google_apis::FileResource& sync_root_folder, 1853 const google_apis::FileResource& sync_root_folder) {
1910 leveldb::WriteBatch* batch) {
1911 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1854 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1912 1855
1913 scoped_ptr<FileMetadata> sync_root_metadata = 1856 scoped_ptr<FileMetadata> sync_root_metadata =
1914 CreateFileMetadataFromFileResource( 1857 CreateFileMetadataFromFileResource(
1915 GetLargestKnownChangeID(), sync_root_folder); 1858 GetLargestKnownChangeID(), sync_root_folder);
1916 scoped_ptr<FileTracker> sync_root_tracker = 1859 scoped_ptr<FileTracker> sync_root_tracker =
1917 CreateSyncRootTracker(IncrementTrackerID(batch), *sync_root_metadata); 1860 CreateSyncRootTracker(IncrementTrackerID(), *sync_root_metadata);
1918 1861
1919 index_->SetSyncRootTrackerID(sync_root_tracker->tracker_id(), batch); 1862 index_->SetSyncRootTrackerID(sync_root_tracker->tracker_id());
1920 index_->StoreFileMetadata(sync_root_metadata.Pass(), batch); 1863 index_->StoreFileMetadata(sync_root_metadata.Pass());
1921 index_->StoreFileTracker(sync_root_tracker.Pass(), batch); 1864 index_->StoreFileTracker(sync_root_tracker.Pass());
1922 } 1865 }
1923 1866
1924 void MetadataDatabase::AttachInitialAppRoot( 1867 void MetadataDatabase::AttachInitialAppRoot(
1925 const google_apis::FileResource& app_root_folder, 1868 const google_apis::FileResource& app_root_folder) {
1926 leveldb::WriteBatch* batch) {
1927 scoped_ptr<FileMetadata> app_root_metadata = 1869 scoped_ptr<FileMetadata> app_root_metadata =
1928 CreateFileMetadataFromFileResource( 1870 CreateFileMetadataFromFileResource(
1929 GetLargestKnownChangeID(), app_root_folder); 1871 GetLargestKnownChangeID(), app_root_folder);
1930 scoped_ptr<FileTracker> app_root_tracker = 1872 scoped_ptr<FileTracker> app_root_tracker =
1931 CreateInitialAppRootTracker(IncrementTrackerID(batch), 1873 CreateInitialAppRootTracker(IncrementTrackerID(),
1932 GetSyncRootTrackerID(), 1874 GetSyncRootTrackerID(),
1933 *app_root_metadata); 1875 *app_root_metadata);
1934 1876
1935 index_->StoreFileMetadata(app_root_metadata.Pass(), batch); 1877 index_->StoreFileMetadata(app_root_metadata.Pass());
1936 index_->StoreFileTracker(app_root_tracker.Pass(), batch); 1878 index_->StoreFileTracker(app_root_tracker.Pass());
1937 } 1879 }
1938 1880
1939 void MetadataDatabase::DetachFromSequence() { 1881 void MetadataDatabase::DetachFromSequence() {
1940 worker_sequence_checker_.DetachFromSequence(); 1882 worker_sequence_checker_.DetachFromSequence();
1941 } 1883 }
1942 1884
1943 } // namespace drive_backend 1885 } // namespace drive_backend
1944 } // namespace sync_file_system 1886 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698