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

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: 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"
nhiroki 2014/08/01 09:43:38 nit: You already included this in *.h
peria 2014/08/04 03:13:43 Acknowledged.
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 void WriteOnFileTaskRunner( 195 void WriteOnFileTaskRunner(
195 leveldb::DB* db, 196 LevelDBWrapper* db,
196 scoped_ptr<leveldb::WriteBatch> batch,
197 scoped_refptr<base::SequencedTaskRunner> worker_task_runner, 197 scoped_refptr<base::SequencedTaskRunner> worker_task_runner,
198 const SyncStatusCallback& callback) { 198 const SyncStatusCallback& callback) {
199 DCHECK(db); 199 DCHECK(db);
200 DCHECK(batch); 200 leveldb::Status status = db->Commit();
201 leveldb::Status status = db->Write(leveldb::WriteOptions(), batch.get());
202 worker_task_runner->PostTask( 201 worker_task_runner->PostTask(
203 FROM_HERE, 202 FROM_HERE,
204 base::Bind(callback, LevelDBStatusToSyncStatusCode(status))); 203 base::Bind(callback, LevelDBStatusToSyncStatusCode(status)));
205 } 204 }
206 205
207 // Returns true if |db| has no content. 206 // Returns true if |db| has no content.
208 bool IsDatabaseEmpty(leveldb::DB* db) { 207 bool IsDatabaseEmpty(LevelDBWrapper* db) {
209 DCHECK(db); 208 DCHECK(db);
210 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 209 scoped_ptr<LevelDBWrapper::Iterator> itr(db->NewIterator());
211 itr->SeekToFirst(); 210 itr->SeekToFirst();
212 return !itr->Valid(); 211 return !itr->Valid();
213 } 212 }
214 213
215 SyncStatusCode OpenDatabase(const base::FilePath& path, 214 SyncStatusCode OpenDatabase(const base::FilePath& path,
216 leveldb::Env* env_override, 215 leveldb::Env* env_override,
217 scoped_ptr<leveldb::DB>* db_out, 216 scoped_ptr<LevelDBWrapper>* db_out,
218 bool* created) { 217 bool* created) {
219 base::ThreadRestrictions::AssertIOAllowed(); 218 base::ThreadRestrictions::AssertIOAllowed();
220 DCHECK(db_out); 219 DCHECK(db_out);
221 DCHECK(created); 220 DCHECK(created);
222 DCHECK(path.IsAbsolute()); 221 DCHECK(path.IsAbsolute());
223 222
224 leveldb::Options options; 223 leveldb::Options options;
225 options.max_open_files = 0; // Use minimum. 224 options.max_open_files = 0; // Use minimum.
226 options.create_if_missing = true; 225 options.create_if_missing = true;
227 if (env_override) 226 if (env_override)
228 options.env = env_override; 227 options.env = env_override;
229 leveldb::DB* db = NULL; 228 leveldb::DB* db = NULL;
230 leveldb::Status db_status = 229 leveldb::Status db_status =
231 leveldb::DB::Open(options, path.AsUTF8Unsafe(), &db); 230 leveldb::DB::Open(options, path.AsUTF8Unsafe(), &db);
232 SyncStatusCode status = LevelDBStatusToSyncStatusCode(db_status); 231 SyncStatusCode status = LevelDBStatusToSyncStatusCode(db_status);
233 if (status != SYNC_STATUS_OK) { 232 if (status != SYNC_STATUS_OK) {
234 delete db; 233 delete db;
235 return status; 234 return status;
236 } 235 }
237 236
238 *created = IsDatabaseEmpty(db); 237 db_out->reset(new LevelDBWrapper(make_scoped_ptr(db)));
239 db_out->reset(db); 238 *created = IsDatabaseEmpty(db_out->get());
240 return status; 239 return status;
241 } 240 }
242 241
243 SyncStatusCode MigrateDatabaseIfNeeded(leveldb::DB* db) { 242 SyncStatusCode MigrateDatabaseIfNeeded(LevelDBWrapper* db) {
244 // See metadata_database_index.cc for the database schema. 243 // See metadata_database_index.cc for the database schema.
245 base::ThreadRestrictions::AssertIOAllowed(); 244 base::ThreadRestrictions::AssertIOAllowed();
246 DCHECK(db); 245 DCHECK(db);
247 std::string value; 246 std::string value;
248 leveldb::Status status = 247 leveldb::Status status = db->Get(kDatabaseVersionKey, &value);
249 db->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value);
250 int64 version = 0; 248 int64 version = 0;
251 if (status.ok()) { 249 if (status.ok()) {
252 if (!base::StringToInt64(value, &version)) 250 if (!base::StringToInt64(value, &version))
253 return SYNC_DATABASE_ERROR_FAILED; 251 return SYNC_DATABASE_ERROR_FAILED;
254 } else { 252 } else {
255 if (!status.IsNotFound()) 253 if (!status.IsNotFound())
256 return SYNC_DATABASE_ERROR_FAILED; 254 return SYNC_DATABASE_ERROR_FAILED;
257 } 255 }
258 256
259 switch (version) { 257 switch (version) {
260 case 0: 258 case 0:
261 drive_backend::MigrateDatabaseFromV0ToV1(db); 259 drive_backend::MigrateDatabaseFromV0ToV1(db->GetLevelDB());
262 // fall-through 260 // fall-through
263 case 1: 261 case 1:
264 drive_backend::MigrateDatabaseFromV1ToV2(db); 262 drive_backend::MigrateDatabaseFromV1ToV2(db->GetLevelDB());
265 // fall-through 263 // fall-through
266 case 2: 264 case 2:
267 // TODO(tzik): Migrate database from version 2 to 3. 265 // TODO(tzik): Migrate database from version 2 to 3.
268 // * Add sync-root folder as active, dirty and needs_folder_listing 266 // * Add sync-root folder as active, dirty and needs_folder_listing
269 // folder. 267 // folder.
270 // * Add app-root folders for each origins. Each app-root folder for 268 // * Add app-root folders for each origins. Each app-root folder for
271 // an enabled origin should be a active, dirty and 269 // an enabled origin should be a active, dirty and
272 // needs_folder_listing folder. And Each app-root folder for a 270 // needs_folder_listing folder. And Each app-root folder for a
273 // disabled origin should be an inactive, dirty and 271 // disabled origin should be an inactive, dirty and
274 // non-needs_folder_listing folder. 272 // non-needs_folder_listing folder.
275 // * Add a file metadata for each file in previous version. 273 // * Add a file metadata for each file in previous version.
276 NOTIMPLEMENTED(); 274 NOTIMPLEMENTED();
277 return SYNC_DATABASE_ERROR_FAILED; 275 return SYNC_DATABASE_ERROR_FAILED;
278 // fall-through 276 // fall-through
279 case 3: 277 case 3:
280 DCHECK_EQ(3, kCurrentDatabaseVersion); 278 DCHECK_EQ(3, kCurrentDatabaseVersion);
281 return SYNC_STATUS_OK; 279 return SYNC_STATUS_OK;
282 default: 280 default:
283 return SYNC_DATABASE_ERROR_FAILED; 281 return SYNC_DATABASE_ERROR_FAILED;
284 } 282 }
285 } 283 }
286 284
287 bool HasInvalidTitle(const std::string& title) { 285 bool HasInvalidTitle(const std::string& title) {
288 return title.empty() || 286 return title.empty() ||
289 title.find('/') != std::string::npos || 287 title.find('/') != std::string::npos ||
290 title.find('\\') != std::string::npos; 288 title.find('\\') != std::string::npos;
291 } 289 }
292 290
293 void MarkTrackerSetDirty(const TrackerIDSet& trackers, 291 void MarkTrackerSetDirty(const TrackerIDSet& trackers,
294 MetadataDatabaseIndexInterface* index, 292 MetadataDatabaseIndexInterface* index) {
295 leveldb::WriteBatch* batch) {
296 for (TrackerIDSet::const_iterator itr = trackers.begin(); 293 for (TrackerIDSet::const_iterator itr = trackers.begin();
297 itr != trackers.end(); ++itr) { 294 itr != trackers.end(); ++itr) {
298 scoped_ptr<FileTracker> tracker(new FileTracker); 295 scoped_ptr<FileTracker> tracker(new FileTracker);
299 index->GetFileTracker(*itr, tracker.get()); 296 index->GetFileTracker(*itr, tracker.get());
300 if (tracker->dirty()) 297 if (tracker->dirty())
301 continue; 298 continue;
302 tracker->set_dirty(true); 299 tracker->set_dirty(true);
303 index->StoreFileTracker(tracker.Pass(), batch); 300 index->StoreFileTracker(tracker.Pass());
304 } 301 }
305 } 302 }
306 303
307 void MarkTrackersDirtyByPath(int64 parent_tracker_id, 304 void MarkTrackersDirtyByPath(int64 parent_tracker_id,
308 const std::string& title, 305 const std::string& title,
309 MetadataDatabaseIndexInterface* index, 306 MetadataDatabaseIndexInterface* index) {
310 leveldb::WriteBatch* batch) {
311 if (parent_tracker_id == kInvalidTrackerID || title.empty()) 307 if (parent_tracker_id == kInvalidTrackerID || title.empty())
312 return; 308 return;
313 MarkTrackerSetDirty( 309 MarkTrackerSetDirty(
314 index->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title), 310 index->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title),
315 index, batch); 311 index);
316 } 312 }
317 313
318 void MarkTrackersDirtyByFileID(const std::string& file_id, 314 void MarkTrackersDirtyByFileID(const std::string& file_id,
319 MetadataDatabaseIndexInterface* index, 315 MetadataDatabaseIndexInterface* index) {
320 leveldb::WriteBatch* batch) { 316 MarkTrackerSetDirty(index->GetFileTrackerIDsByFileID(file_id), index);
321 MarkTrackerSetDirty(index->GetFileTrackerIDsByFileID(file_id),
322 index, batch);
323 } 317 }
324 318
325 void MarkTrackersDirtyRecursively(int64 root_tracker_id, 319 void MarkTrackersDirtyRecursively(int64 root_tracker_id,
326 MetadataDatabaseIndexInterface* index, 320 MetadataDatabaseIndexInterface* index) {
327 leveldb::WriteBatch* batch) {
328 std::vector<int64> stack; 321 std::vector<int64> stack;
329 stack.push_back(root_tracker_id); 322 stack.push_back(root_tracker_id);
330 while (!stack.empty()) { 323 while (!stack.empty()) {
331 int64 tracker_id = stack.back(); 324 int64 tracker_id = stack.back();
332 stack.pop_back(); 325 stack.pop_back();
333 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), &stack); 326 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), &stack);
334 327
335 scoped_ptr<FileTracker> tracker(new FileTracker); 328 scoped_ptr<FileTracker> tracker(new FileTracker);
336 index->GetFileTracker(tracker_id, tracker.get()); 329 index->GetFileTracker(tracker_id, tracker.get());
337 tracker->set_dirty(true); 330 tracker->set_dirty(true);
338 331
339 index->StoreFileTracker(tracker.Pass(), batch); 332 index->StoreFileTracker(tracker.Pass());
340 } 333 }
341 } 334 }
342 335
343 void RemoveAllDescendantTrackers(int64 root_tracker_id, 336 void RemoveAllDescendantTrackers(int64 root_tracker_id,
344 MetadataDatabaseIndexInterface* index, 337 MetadataDatabaseIndexInterface* index) {
345 leveldb::WriteBatch* batch) {
346 std::vector<int64> pending_trackers; 338 std::vector<int64> pending_trackers;
347 AppendContents(index->GetFileTrackerIDsByParent(root_tracker_id), 339 AppendContents(index->GetFileTrackerIDsByParent(root_tracker_id),
348 &pending_trackers); 340 &pending_trackers);
349 341
350 std::vector<int64> to_be_removed; 342 std::vector<int64> to_be_removed;
351 343
352 // List trackers to remove. 344 // List trackers to remove.
353 while (!pending_trackers.empty()) { 345 while (!pending_trackers.empty()) {
354 int64 tracker_id = pending_trackers.back(); 346 int64 tracker_id = pending_trackers.back();
355 pending_trackers.pop_back(); 347 pending_trackers.pop_back();
356 AppendContents(index->GetFileTrackerIDsByParent(tracker_id), 348 AppendContents(index->GetFileTrackerIDsByParent(tracker_id),
357 &pending_trackers); 349 &pending_trackers);
358 to_be_removed.push_back(tracker_id); 350 to_be_removed.push_back(tracker_id);
359 } 351 }
360 352
361 // Remove trackers in the reversed order. 353 // Remove trackers in the reversed order.
362 base::hash_set<std::string> affected_file_ids; 354 base::hash_set<std::string> affected_file_ids;
363 for (std::vector<int64>::reverse_iterator itr = to_be_removed.rbegin(); 355 for (std::vector<int64>::reverse_iterator itr = to_be_removed.rbegin();
364 itr != to_be_removed.rend(); ++itr) { 356 itr != to_be_removed.rend(); ++itr) {
365 FileTracker tracker; 357 FileTracker tracker;
366 index->GetFileTracker(*itr, &tracker); 358 index->GetFileTracker(*itr, &tracker);
367 affected_file_ids.insert(tracker.file_id()); 359 affected_file_ids.insert(tracker.file_id());
368 index->RemoveFileTracker(*itr, batch); 360 index->RemoveFileTracker(*itr);
369 } 361 }
370 362
371 for (base::hash_set<std::string>::iterator itr = affected_file_ids.begin(); 363 for (base::hash_set<std::string>::iterator itr = affected_file_ids.begin();
372 itr != affected_file_ids.end(); ++itr) { 364 itr != affected_file_ids.end(); ++itr) {
373 TrackerIDSet trackers = index->GetFileTrackerIDsByFileID(*itr); 365 TrackerIDSet trackers = index->GetFileTrackerIDsByFileID(*itr);
374 if (trackers.empty()) { 366 if (trackers.empty()) {
375 // Remove metadata that no longer has any tracker. 367 // Remove metadata that no longer has any tracker.
376 index->RemoveFileMetadata(*itr, batch); 368 index->RemoveFileMetadata(*itr);
377 } else { 369 } else {
378 MarkTrackerSetDirty(trackers, index, batch); 370 MarkTrackerSetDirty(trackers, index);
379 } 371 }
380 } 372 }
381 } 373 }
382 374
383 bool FilterFileTrackersByParent( 375 bool FilterFileTrackersByParent(
384 const MetadataDatabaseIndexInterface* index, 376 const MetadataDatabaseIndexInterface* index,
385 const TrackerIDSet& trackers, 377 const TrackerIDSet& trackers,
386 int64 parent_tracker_id, 378 int64 parent_tracker_id,
387 FileTracker* tracker_out) { 379 FileTracker* tracker_out) {
388 FileTracker tracker; 380 FileTracker tracker;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 454
463 enum DirtyingOption { 455 enum DirtyingOption {
464 MARK_NOTHING_DIRTY = 0, 456 MARK_NOTHING_DIRTY = 0,
465 MARK_ITSELF_DIRTY = 1 << 0, 457 MARK_ITSELF_DIRTY = 1 << 0,
466 MARK_SAME_FILE_ID_TRACKERS_DIRTY = 1 << 1, 458 MARK_SAME_FILE_ID_TRACKERS_DIRTY = 1 << 1,
467 MARK_SAME_PATH_TRACKERS_DIRTY = 1 << 2, 459 MARK_SAME_PATH_TRACKERS_DIRTY = 1 << 2,
468 }; 460 };
469 461
470 void ActivateFileTracker(int64 tracker_id, 462 void ActivateFileTracker(int64 tracker_id,
471 int dirtying_options, 463 int dirtying_options,
472 MetadataDatabaseIndexInterface* index, 464 MetadataDatabaseIndexInterface* index) {
473 leveldb::WriteBatch* batch) {
474 DCHECK(dirtying_options == MARK_NOTHING_DIRTY || 465 DCHECK(dirtying_options == MARK_NOTHING_DIRTY ||
475 dirtying_options == MARK_ITSELF_DIRTY); 466 dirtying_options == MARK_ITSELF_DIRTY);
476 467
477 scoped_ptr<FileTracker> tracker(new FileTracker); 468 scoped_ptr<FileTracker> tracker(new FileTracker);
478 index->GetFileTracker(tracker_id, tracker.get()); 469 index->GetFileTracker(tracker_id, tracker.get());
479 tracker->set_active(true); 470 tracker->set_active(true);
480 if (dirtying_options & MARK_ITSELF_DIRTY) { 471 if (dirtying_options & MARK_ITSELF_DIRTY) {
481 tracker->set_dirty(true); 472 tracker->set_dirty(true);
482 tracker->set_needs_folder_listing( 473 tracker->set_needs_folder_listing(
483 tracker->has_synced_details() && 474 tracker->has_synced_details() &&
484 tracker->synced_details().file_kind() == FILE_KIND_FOLDER); 475 tracker->synced_details().file_kind() == FILE_KIND_FOLDER);
485 } else { 476 } else {
486 tracker->set_dirty(false); 477 tracker->set_dirty(false);
487 tracker->set_needs_folder_listing(false); 478 tracker->set_needs_folder_listing(false);
488 } 479 }
489 480
490 index->StoreFileTracker(tracker.Pass(), batch); 481 index->StoreFileTracker(tracker.Pass());
491 } 482 }
492 483
493 void DeactivateFileTracker(int64 tracker_id, 484 void DeactivateFileTracker(int64 tracker_id,
494 int dirtying_options, 485 int dirtying_options,
495 MetadataDatabaseIndexInterface* index, 486 MetadataDatabaseIndexInterface* index) {
496 leveldb::WriteBatch* batch) { 487 RemoveAllDescendantTrackers(tracker_id, index);
497 RemoveAllDescendantTrackers(tracker_id, index, batch);
498 488
499 scoped_ptr<FileTracker> tracker(new FileTracker); 489 scoped_ptr<FileTracker> tracker(new FileTracker);
500 index->GetFileTracker(tracker_id, tracker.get()); 490 index->GetFileTracker(tracker_id, tracker.get());
501 491
502 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY) 492 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY)
503 MarkTrackersDirtyByFileID(tracker->file_id(), index, batch); 493 MarkTrackersDirtyByFileID(tracker->file_id(), index);
504 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) { 494 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) {
505 MarkTrackersDirtyByPath(tracker->parent_tracker_id(), 495 MarkTrackersDirtyByPath(tracker->parent_tracker_id(),
506 GetTrackerTitle(*tracker), 496 GetTrackerTitle(*tracker), index);
507 index, batch);
508 } 497 }
509 498
510 tracker->set_dirty(dirtying_options & MARK_ITSELF_DIRTY); 499 tracker->set_dirty(dirtying_options & MARK_ITSELF_DIRTY);
511 tracker->set_active(false); 500 tracker->set_active(false);
512 index->StoreFileTracker(tracker.Pass(), batch); 501 index->StoreFileTracker(tracker.Pass());
513 } 502 }
514 503
515 void RemoveFileTracker(int64 tracker_id, 504 void RemoveFileTracker(int64 tracker_id,
516 int dirtying_options, 505 int dirtying_options,
517 MetadataDatabaseIndexInterface* index, 506 MetadataDatabaseIndexInterface* index) {
518 leveldb::WriteBatch* batch) {
519 DCHECK(!(dirtying_options & MARK_ITSELF_DIRTY)); 507 DCHECK(!(dirtying_options & MARK_ITSELF_DIRTY));
520 508
521 FileTracker tracker; 509 FileTracker tracker;
522 if (!index->GetFileTracker(tracker_id, &tracker)) 510 if (!index->GetFileTracker(tracker_id, &tracker))
523 return; 511 return;
524 512
525 std::string file_id = tracker.file_id(); 513 std::string file_id = tracker.file_id();
526 int64 parent_tracker_id = tracker.parent_tracker_id(); 514 int64 parent_tracker_id = tracker.parent_tracker_id();
527 std::string title = GetTrackerTitle(tracker); 515 std::string title = GetTrackerTitle(tracker);
528 516
529 RemoveAllDescendantTrackers(tracker_id, index, batch); 517 RemoveAllDescendantTrackers(tracker_id, index);
530 index->RemoveFileTracker(tracker_id, batch); 518 index->RemoveFileTracker(tracker_id);
531 519
532 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY) 520 if (dirtying_options & MARK_SAME_FILE_ID_TRACKERS_DIRTY)
533 MarkTrackersDirtyByFileID(file_id, index, batch); 521 MarkTrackersDirtyByFileID(file_id, index);
534 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY) 522 if (dirtying_options & MARK_SAME_PATH_TRACKERS_DIRTY)
535 MarkTrackersDirtyByPath(parent_tracker_id, title, index, batch); 523 MarkTrackersDirtyByPath(parent_tracker_id, title, index);
536 524
537 if (index->GetFileTrackerIDsByFileID(file_id).empty()) { 525 if (index->GetFileTrackerIDsByFileID(file_id).empty()) {
538 index->RemoveFileMetadata(file_id, batch); 526 index->RemoveFileMetadata(file_id);
539 } 527 }
540 } 528 }
541 529
542 } // namespace 530 } // namespace
543 531
544 struct MetadataDatabase::CreateParam { 532 struct MetadataDatabase::CreateParam {
545 scoped_refptr<base::SequencedTaskRunner> worker_task_runner; 533 scoped_refptr<base::SequencedTaskRunner> worker_task_runner;
546 scoped_refptr<base::SequencedTaskRunner> file_task_runner; 534 scoped_refptr<base::SequencedTaskRunner> file_task_runner;
547 base::FilePath database_path; 535 base::FilePath database_path;
548 leveldb::Env* env_override; 536 leveldb::Env* env_override;
(...skipping 20 matching lines...) Expand all
569 base::Passed(make_scoped_ptr(new CreateParam( 557 base::Passed(make_scoped_ptr(new CreateParam(
570 worker_task_runner, 558 worker_task_runner,
571 file_task_runner, 559 file_task_runner,
572 database_path, 560 database_path,
573 env_override))), 561 env_override))),
574 callback)); 562 callback));
575 } 563 }
576 564
577 // static 565 // static
578 SyncStatusCode MetadataDatabase::CreateForTesting( 566 SyncStatusCode MetadataDatabase::CreateForTesting(
579 scoped_ptr<leveldb::DB> db, 567 scoped_ptr<LevelDBWrapper> db,
580 scoped_ptr<MetadataDatabase>* metadata_database_out) { 568 scoped_ptr<MetadataDatabase>* metadata_database_out) {
581 scoped_ptr<MetadataDatabase> metadata_database( 569 scoped_ptr<MetadataDatabase> metadata_database(
582 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(), 570 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(),
583 base::ThreadTaskRunnerHandle::Get(), 571 base::ThreadTaskRunnerHandle::Get(),
584 base::FilePath(), NULL)); 572 base::FilePath(), NULL));
585 metadata_database->db_ = db.Pass(); 573 metadata_database->db_ = db.Pass();
586 SyncStatusCode status = 574 SyncStatusCode status =
587 metadata_database->InitializeOnFileTaskRunner(); 575 metadata_database->InitializeOnFileTaskRunner();
588 if (status == SYNC_STATUS_OK) 576 if (status == SYNC_STATUS_OK)
589 *metadata_database_out = metadata_database.Pass(); 577 *metadata_database_out = metadata_database.Pass();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 return index_->GetSyncRootTrackerID() != kInvalidTrackerID; 625 return index_->GetSyncRootTrackerID() != kInvalidTrackerID;
638 } 626 }
639 627
640 void MetadataDatabase::PopulateInitialData( 628 void MetadataDatabase::PopulateInitialData(
641 int64 largest_change_id, 629 int64 largest_change_id,
642 const google_apis::FileResource& sync_root_folder, 630 const google_apis::FileResource& sync_root_folder,
643 const ScopedVector<google_apis::FileResource>& app_root_folders, 631 const ScopedVector<google_apis::FileResource>& app_root_folders,
644 const SyncStatusCallback& callback) { 632 const SyncStatusCallback& callback) {
645 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 633 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
646 634
647 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 635 index_->SetLargestChangeID(largest_change_id);
648 index_->SetLargestChangeID(largest_change_id, batch.get());
649 UpdateLargestKnownChangeID(largest_change_id); 636 UpdateLargestKnownChangeID(largest_change_id);
650 637
651 AttachSyncRoot(sync_root_folder, batch.get()); 638 AttachSyncRoot(sync_root_folder);
652 for (size_t i = 0; i < app_root_folders.size(); ++i) 639 for (size_t i = 0; i < app_root_folders.size(); ++i)
653 AttachInitialAppRoot(*app_root_folders[i], batch.get()); 640 AttachInitialAppRoot(*app_root_folders[i]);
654 641
655 WriteToDatabase(batch.Pass(), callback); 642 WriteToDatabase(callback);
656 } 643 }
657 644
658 bool MetadataDatabase::IsAppEnabled(const std::string& app_id) const { 645 bool MetadataDatabase::IsAppEnabled(const std::string& app_id) const {
659 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 646 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
660 647
661 int64 tracker_id = index_->GetAppRootTracker(app_id); 648 int64 tracker_id = index_->GetAppRootTracker(app_id);
662 if (tracker_id == kInvalidTrackerID) 649 if (tracker_id == kInvalidTrackerID)
663 return false; 650 return false;
664 651
665 FileTracker tracker; 652 FileTracker tracker;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 698
712 scoped_ptr<FileTracker> tracker(new FileTracker); 699 scoped_ptr<FileTracker> tracker(new FileTracker);
713 if (!FilterFileTrackersByParent(index_.get(), trackers, 700 if (!FilterFileTrackersByParent(index_.get(), trackers,
714 sync_root_tracker_id, tracker.get())) { 701 sync_root_tracker_id, tracker.get())) {
715 worker_task_runner_->PostTask( 702 worker_task_runner_->PostTask(
716 FROM_HERE, 703 FROM_HERE,
717 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND)); 704 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
718 return; 705 return;
719 } 706 }
720 707
721 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
722 tracker->set_app_id(app_id); 708 tracker->set_app_id(app_id);
723 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT); 709 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
724 tracker->set_active(true); 710 tracker->set_active(true);
725 tracker->set_needs_folder_listing(true); 711 tracker->set_needs_folder_listing(true);
726 tracker->set_dirty(true); 712 tracker->set_dirty(true);
727 713
728 index_->StoreFileTracker(tracker.Pass(), batch.get()); 714 index_->StoreFileTracker(tracker.Pass());
729 WriteToDatabase(batch.Pass(), callback); 715 WriteToDatabase(callback);
730 } 716 }
731 717
732 void MetadataDatabase::DisableApp(const std::string& app_id, 718 void MetadataDatabase::DisableApp(const std::string& app_id,
733 const SyncStatusCallback& callback) { 719 const SyncStatusCallback& callback) {
734 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 720 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
735 721
736 int64 tracker_id = index_->GetAppRootTracker(app_id); 722 int64 tracker_id = index_->GetAppRootTracker(app_id);
737 scoped_ptr<FileTracker> tracker(new FileTracker); 723 scoped_ptr<FileTracker> tracker(new FileTracker);
738 if (!index_->GetFileTracker(tracker_id, tracker.get())) { 724 if (!index_->GetFileTracker(tracker_id, tracker.get())) {
739 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND); 725 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND);
740 return; 726 return;
741 } 727 }
742 728
743 if (tracker->tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT) { 729 if (tracker->tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT) {
744 callback.Run(SYNC_STATUS_OK); 730 callback.Run(SYNC_STATUS_OK);
745 return; 731 return;
746 } 732 }
747 733
748 DCHECK_EQ(TRACKER_KIND_APP_ROOT, tracker->tracker_kind()); 734 DCHECK_EQ(TRACKER_KIND_APP_ROOT, tracker->tracker_kind());
749 DCHECK(tracker->active()); 735 DCHECK(tracker->active());
750 736
751 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
752
753 // Keep the app-root tracker active (but change the tracker_kind) so that 737 // Keep the app-root tracker active (but change the tracker_kind) so that
754 // other conflicting trackers won't become active. 738 // other conflicting trackers won't become active.
755 tracker->set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT); 739 tracker->set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT);
756 740
757 index_->StoreFileTracker(tracker.Pass(), batch.get()); 741 index_->StoreFileTracker(tracker.Pass());
758 WriteToDatabase(batch.Pass(), callback); 742 WriteToDatabase(callback);
759 } 743 }
760 744
761 void MetadataDatabase::EnableApp(const std::string& app_id, 745 void MetadataDatabase::EnableApp(const std::string& app_id,
762 const SyncStatusCallback& callback) { 746 const SyncStatusCallback& callback) {
763 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 747 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
764 748
765 int64 tracker_id = index_->GetAppRootTracker(app_id); 749 int64 tracker_id = index_->GetAppRootTracker(app_id);
766 scoped_ptr<FileTracker> tracker(new FileTracker); 750 scoped_ptr<FileTracker> tracker(new FileTracker);
767 if (!index_->GetFileTracker(tracker_id, tracker.get())) { 751 if (!index_->GetFileTracker(tracker_id, tracker.get())) {
768 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND); 752 callback.Run(SYNC_DATABASE_ERROR_NOT_FOUND);
769 return; 753 return;
770 } 754 }
771 755
772 if (tracker->tracker_kind() == TRACKER_KIND_APP_ROOT) { 756 if (tracker->tracker_kind() == TRACKER_KIND_APP_ROOT) {
773 callback.Run(SYNC_STATUS_OK); 757 callback.Run(SYNC_STATUS_OK);
774 return; 758 return;
775 } 759 }
776 760
777 DCHECK_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker->tracker_kind()); 761 DCHECK_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker->tracker_kind());
778 DCHECK(tracker->active()); 762 DCHECK(tracker->active());
779 763
780 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 764 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT);
765 index_->StoreFileTracker(tracker.Pass());
781 766
782 tracker->set_tracker_kind(TRACKER_KIND_APP_ROOT); 767 MarkTrackersDirtyRecursively(tracker_id, index_.get());
783 index_->StoreFileTracker(tracker.Pass(), batch.get()); 768 WriteToDatabase(callback);
784
785 MarkTrackersDirtyRecursively(tracker_id, index_.get(), batch.get());
786 WriteToDatabase(batch.Pass(), callback);
787 } 769 }
788 770
789 void MetadataDatabase::UnregisterApp(const std::string& app_id, 771 void MetadataDatabase::UnregisterApp(const std::string& app_id,
790 const SyncStatusCallback& callback) { 772 const SyncStatusCallback& callback) {
791 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 773 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
792 774
793 int64 tracker_id = index_->GetAppRootTracker(app_id); 775 int64 tracker_id = index_->GetAppRootTracker(app_id);
794 scoped_ptr<FileTracker> tracker(new FileTracker); 776 scoped_ptr<FileTracker> tracker(new FileTracker);
795 if (!index_->GetFileTracker(tracker_id, tracker.get()) || 777 if (!index_->GetFileTracker(tracker_id, tracker.get()) ||
796 tracker->tracker_kind() == TRACKER_KIND_REGULAR) { 778 tracker->tracker_kind() == TRACKER_KIND_REGULAR) {
797 worker_task_runner_->PostTask( 779 worker_task_runner_->PostTask(
798 FROM_HERE, 780 FROM_HERE,
799 base::Bind(callback, SYNC_STATUS_OK)); 781 base::Bind(callback, SYNC_STATUS_OK));
800 return; 782 return;
801 } 783 }
802 784
803 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 785 RemoveAllDescendantTrackers(tracker_id, index_.get());
804 RemoveAllDescendantTrackers(tracker_id, index_.get(), batch.get());
805 786
806 tracker->clear_app_id(); 787 tracker->clear_app_id();
807 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); 788 tracker->set_tracker_kind(TRACKER_KIND_REGULAR);
808 tracker->set_active(false); 789 tracker->set_active(false);
809 tracker->set_dirty(true); 790 tracker->set_dirty(true);
810 791
811 index_->StoreFileTracker(tracker.Pass(), batch.get()); 792 index_->StoreFileTracker(tracker.Pass());
812 WriteToDatabase(batch.Pass(), callback); 793 WriteToDatabase(callback);
813 } 794 }
814 795
815 bool MetadataDatabase::FindAppRootTracker(const std::string& app_id, 796 bool MetadataDatabase::FindAppRootTracker(const std::string& app_id,
816 FileTracker* tracker_out) const { 797 FileTracker* tracker_out) const {
817 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 798 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
818 799
819 int64 app_root_tracker_id = index_->GetAppRootTracker(app_id); 800 int64 app_root_tracker_id = index_->GetAppRootTracker(app_id);
820 if (!app_root_tracker_id) 801 if (!app_root_tracker_id)
821 return false; 802 return false;
822 803
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 return true; 940 return true;
960 } 941 }
961 942
962 void MetadataDatabase::UpdateByChangeList( 943 void MetadataDatabase::UpdateByChangeList(
963 int64 largest_change_id, 944 int64 largest_change_id,
964 ScopedVector<google_apis::ChangeResource> changes, 945 ScopedVector<google_apis::ChangeResource> changes,
965 const SyncStatusCallback& callback) { 946 const SyncStatusCallback& callback) {
966 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 947 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
967 DCHECK_LE(index_->GetLargestChangeID(), largest_change_id); 948 DCHECK_LE(index_->GetLargestChangeID(), largest_change_id);
968 949
969 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
970
971 for (size_t i = 0; i < changes.size(); ++i) { 950 for (size_t i = 0; i < changes.size(); ++i) {
972 const google_apis::ChangeResource& change = *changes[i]; 951 const google_apis::ChangeResource& change = *changes[i];
973 if (HasNewerFileMetadata(change.file_id(), change.change_id())) 952 if (HasNewerFileMetadata(change.file_id(), change.change_id()))
974 continue; 953 continue;
975 954
976 scoped_ptr<FileMetadata> metadata( 955 scoped_ptr<FileMetadata> metadata(
977 CreateFileMetadataFromChangeResource(change)); 956 CreateFileMetadataFromChangeResource(change));
978 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 957 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
979 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 958 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
980 batch.get());
981 } 959 }
982 960
983 UpdateLargestKnownChangeID(largest_change_id); 961 UpdateLargestKnownChangeID(largest_change_id);
984 index_->SetLargestChangeID(largest_change_id, batch.get()); 962 index_->SetLargestChangeID(largest_change_id);
985 WriteToDatabase(batch.Pass(), callback); 963 WriteToDatabase(callback);
986 } 964 }
987 965
988 void MetadataDatabase::UpdateByFileResource( 966 void MetadataDatabase::UpdateByFileResource(
989 const google_apis::FileResource& resource, 967 const google_apis::FileResource& resource,
990 const SyncStatusCallback& callback) { 968 const SyncStatusCallback& callback) {
991 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 969 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
992 970
993 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
994
995 scoped_ptr<FileMetadata> metadata( 971 scoped_ptr<FileMetadata> metadata(
996 CreateFileMetadataFromFileResource( 972 CreateFileMetadataFromFileResource(
997 GetLargestKnownChangeID(), resource)); 973 GetLargestKnownChangeID(), resource));
998 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 974 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
999 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 975 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1000 batch.get()); 976 WriteToDatabase(callback);
1001 WriteToDatabase(batch.Pass(), callback);
1002 } 977 }
1003 978
1004 void MetadataDatabase::UpdateByFileResourceList( 979 void MetadataDatabase::UpdateByFileResourceList(
1005 ScopedVector<google_apis::FileResource> resources, 980 ScopedVector<google_apis::FileResource> resources,
1006 const SyncStatusCallback& callback) { 981 const SyncStatusCallback& callback) {
1007 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 982 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1008 983
1009 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1010
1011 for (size_t i = 0; i < resources.size(); ++i) { 984 for (size_t i = 0; i < resources.size(); ++i) {
1012 scoped_ptr<FileMetadata> metadata( 985 scoped_ptr<FileMetadata> metadata(
1013 CreateFileMetadataFromFileResource( 986 CreateFileMetadataFromFileResource(
1014 GetLargestKnownChangeID(), *resources[i])); 987 GetLargestKnownChangeID(), *resources[i]));
1015 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 988 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
1016 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 989 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1017 batch.get());
1018 } 990 }
1019 WriteToDatabase(batch.Pass(), callback); 991 WriteToDatabase(callback);
1020 } 992 }
1021 993
1022 void MetadataDatabase::UpdateByDeletedRemoteFile( 994 void MetadataDatabase::UpdateByDeletedRemoteFile(
1023 const std::string& file_id, 995 const std::string& file_id,
1024 const SyncStatusCallback& callback) { 996 const SyncStatusCallback& callback) {
1025 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 997 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1026 998
1027 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1028 scoped_ptr<FileMetadata> metadata( 999 scoped_ptr<FileMetadata> metadata(
1029 CreateDeletedFileMetadata(GetLargestKnownChangeID(), file_id)); 1000 CreateDeletedFileMetadata(GetLargestKnownChangeID(), file_id));
1030 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 1001 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
1031 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 1002 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1032 batch.get()); 1003 WriteToDatabase(callback);
1033 WriteToDatabase(batch.Pass(), callback);
1034 } 1004 }
1035 1005
1036 void MetadataDatabase::UpdateByDeletedRemoteFileList( 1006 void MetadataDatabase::UpdateByDeletedRemoteFileList(
1037 const FileIDList& file_ids, 1007 const FileIDList& file_ids,
1038 const SyncStatusCallback& callback) { 1008 const SyncStatusCallback& callback) {
1039 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1009 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1040 1010
1041 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1042 for (FileIDList::const_iterator itr = file_ids.begin(); 1011 for (FileIDList::const_iterator itr = file_ids.begin();
1043 itr != file_ids.end(); ++itr) { 1012 itr != file_ids.end(); ++itr) {
1044 scoped_ptr<FileMetadata> metadata( 1013 scoped_ptr<FileMetadata> metadata(
1045 CreateDeletedFileMetadata(GetLargestKnownChangeID(), *itr)); 1014 CreateDeletedFileMetadata(GetLargestKnownChangeID(), *itr));
1046 UpdateByFileMetadata(FROM_HERE, metadata.Pass(), 1015 UpdateByFileMetadata(FROM_HERE, metadata.Pass(),
1047 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 1016 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1048 batch.get());
1049 } 1017 }
1050 WriteToDatabase(batch.Pass(), callback); 1018 WriteToDatabase(callback);
1051 } 1019 }
1052 1020
1053 void MetadataDatabase::ReplaceActiveTrackerWithNewResource( 1021 void MetadataDatabase::ReplaceActiveTrackerWithNewResource(
1054 int64 parent_tracker_id, 1022 int64 parent_tracker_id,
1055 const google_apis::FileResource& resource, 1023 const google_apis::FileResource& resource,
1056 const SyncStatusCallback& callback) { 1024 const SyncStatusCallback& callback) {
1057 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1025 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1058 1026
1059 DCHECK(!index_->GetFileMetadata(resource.file_id(), NULL)); 1027 DCHECK(!index_->GetFileMetadata(resource.file_id(), NULL));
1060 DCHECK(index_->GetFileTracker(parent_tracker_id, NULL)); 1028 DCHECK(index_->GetFileTracker(parent_tracker_id, NULL));
1061 1029
1062 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1063 UpdateByFileMetadata( 1030 UpdateByFileMetadata(
1064 FROM_HERE, 1031 FROM_HERE,
1065 CreateFileMetadataFromFileResource(GetLargestKnownChangeID(), resource), 1032 CreateFileMetadataFromFileResource(GetLargestKnownChangeID(), resource),
1066 UPDATE_TRACKER_FOR_SYNCED_FILE, 1033 UPDATE_TRACKER_FOR_SYNCED_FILE);
1067 batch.get());
1068 1034
1069 DCHECK(index_->GetFileMetadata(resource.file_id(), NULL)); 1035 DCHECK(index_->GetFileMetadata(resource.file_id(), NULL));
1070 DCHECK(!index_->GetFileTrackerIDsByFileID(resource.file_id()).has_active()); 1036 DCHECK(!index_->GetFileTrackerIDsByFileID(resource.file_id()).has_active());
1071 1037
1072 TrackerIDSet same_path_trackers = 1038 TrackerIDSet same_path_trackers =
1073 index_->GetFileTrackerIDsByParentAndTitle( 1039 index_->GetFileTrackerIDsByParentAndTitle(
1074 parent_tracker_id, resource.title()); 1040 parent_tracker_id, resource.title());
1075 FileTracker to_be_activated; 1041 FileTracker to_be_activated;
1076 if (!FilterFileTrackersByFileID(index_.get(), same_path_trackers, 1042 if (!FilterFileTrackersByFileID(index_.get(), same_path_trackers,
1077 resource.file_id(), &to_be_activated)) { 1043 resource.file_id(), &to_be_activated)) {
1078 NOTREACHED(); 1044 NOTREACHED();
1079 worker_task_runner_->PostTask( 1045 worker_task_runner_->PostTask(
1080 FROM_HERE, 1046 FROM_HERE,
1081 base::Bind(callback, SYNC_STATUS_FAILED)); 1047 base::Bind(callback, SYNC_STATUS_FAILED));
1082 return; 1048 return;
1083 } 1049 }
1084 1050
1085 int64 tracker_id = to_be_activated.tracker_id(); 1051 int64 tracker_id = to_be_activated.tracker_id();
1086 if (same_path_trackers.has_active()) { 1052 if (same_path_trackers.has_active()) {
1087 DeactivateFileTracker(same_path_trackers.active_tracker(), 1053 DeactivateFileTracker(same_path_trackers.active_tracker(),
1088 MARK_ITSELF_DIRTY | 1054 MARK_ITSELF_DIRTY |
1089 MARK_SAME_FILE_ID_TRACKERS_DIRTY, 1055 MARK_SAME_FILE_ID_TRACKERS_DIRTY,
1090 index_.get(), batch.get()); 1056 index_.get());
1091 } 1057 }
1092 1058
1093 ActivateFileTracker(tracker_id, MARK_NOTHING_DIRTY, 1059 ActivateFileTracker(tracker_id, MARK_NOTHING_DIRTY,
1094 index_.get(), batch.get()); 1060 index_.get());
nhiroki 2014/08/01 09:43:38 nit: can you squash this into the previous line?
peria 2014/08/04 03:13:43 Done.
1095 WriteToDatabase(batch.Pass(), callback); 1061 WriteToDatabase(callback);
1096 } 1062 }
1097 1063
1098 void MetadataDatabase::PopulateFolderByChildList( 1064 void MetadataDatabase::PopulateFolderByChildList(
1099 const std::string& folder_id, 1065 const std::string& folder_id,
1100 const FileIDList& child_file_ids, 1066 const FileIDList& child_file_ids,
1101 const SyncStatusCallback& callback) { 1067 const SyncStatusCallback& callback) {
1102 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1068 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1103 1069
1104 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(folder_id); 1070 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(folder_id);
1105 if (!trackers.has_active()) { 1071 if (!trackers.has_active()) {
(...skipping 22 matching lines...) Expand all
1128 index_->GetFileTrackerIDsByParent(folder_tracker->tracker_id()); 1094 index_->GetFileTrackerIDsByParent(folder_tracker->tracker_id());
1129 for (size_t i = 0; i < known_children.size(); ++i) { 1095 for (size_t i = 0; i < known_children.size(); ++i) {
1130 FileTracker tracker; 1096 FileTracker tracker;
1131 if (!index_->GetFileTracker(known_children[i], &tracker)) { 1097 if (!index_->GetFileTracker(known_children[i], &tracker)) {
1132 NOTREACHED(); 1098 NOTREACHED();
1133 continue; 1099 continue;
1134 } 1100 }
1135 children.erase(tracker.file_id()); 1101 children.erase(tracker.file_id());
1136 } 1102 }
1137 1103
1138 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1139 for (base::hash_set<std::string>::const_iterator itr = children.begin(); 1104 for (base::hash_set<std::string>::const_iterator itr = children.begin();
1140 itr != children.end(); ++itr) 1105 itr != children.end(); ++itr)
1141 CreateTrackerForParentAndFileID(*folder_tracker, *itr, batch.get()); 1106 CreateTrackerForParentAndFileID(*folder_tracker, *itr);
1142 folder_tracker->set_needs_folder_listing(false); 1107 folder_tracker->set_needs_folder_listing(false);
1143 if (folder_tracker->dirty() && !ShouldKeepDirty(*folder_tracker)) 1108 if (folder_tracker->dirty() && !ShouldKeepDirty(*folder_tracker))
1144 folder_tracker->set_dirty(false); 1109 folder_tracker->set_dirty(false);
1145 index_->StoreFileTracker(folder_tracker.Pass(), batch.get()); 1110 index_->StoreFileTracker(folder_tracker.Pass());
1146 1111
1147 WriteToDatabase(batch.Pass(), callback); 1112 WriteToDatabase(callback);
1148 } 1113 }
1149 1114
1150 void MetadataDatabase::UpdateTracker(int64 tracker_id, 1115 void MetadataDatabase::UpdateTracker(int64 tracker_id,
1151 const FileDetails& updated_details, 1116 const FileDetails& updated_details,
1152 const SyncStatusCallback& callback) { 1117 const SyncStatusCallback& callback) {
1153 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1118 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1154 1119
1155 FileTracker tracker; 1120 FileTracker tracker;
1156 if (!index_->GetFileTracker(tracker_id, &tracker)) { 1121 if (!index_->GetFileTracker(tracker_id, &tracker)) {
1157 worker_task_runner_->PostTask( 1122 worker_task_runner_->PostTask(
1158 FROM_HERE, 1123 FROM_HERE,
1159 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND)); 1124 base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
1160 return; 1125 return;
1161 } 1126 }
1162 1127
1163 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1164
1165 // Check if the tracker is to be deleted. 1128 // Check if the tracker is to be deleted.
1166 if (updated_details.missing()) { 1129 if (updated_details.missing()) {
1167 FileMetadata metadata; 1130 FileMetadata metadata;
1168 if (!index_->GetFileMetadata(tracker.file_id(), &metadata) || 1131 if (!index_->GetFileMetadata(tracker.file_id(), &metadata) ||
1169 metadata.details().missing()) { 1132 metadata.details().missing()) {
1170 // Both the tracker and metadata have the missing flag, now it's safe to 1133 // Both the tracker and metadata have the missing flag, now it's safe to
1171 // delete the |tracker|. 1134 // delete the |tracker|.
1172 RemoveFileTracker(tracker_id, 1135 RemoveFileTracker(tracker_id,
1173 MARK_SAME_FILE_ID_TRACKERS_DIRTY | 1136 MARK_SAME_FILE_ID_TRACKERS_DIRTY |
1174 MARK_SAME_PATH_TRACKERS_DIRTY, 1137 MARK_SAME_PATH_TRACKERS_DIRTY,
1175 index_.get(), batch.get()); 1138 index_.get());
1176 WriteToDatabase(batch.Pass(), callback); 1139 WriteToDatabase(callback);
1177 return; 1140 return;
1178 } 1141 }
1179 } 1142 }
1180 1143
1181 // Sync-root deletion should be handled separately by SyncEngine. 1144 // Sync-root deletion should be handled separately by SyncEngine.
1182 DCHECK(tracker_id != GetSyncRootTrackerID() || 1145 DCHECK(tracker_id != GetSyncRootTrackerID() ||
1183 (tracker.has_synced_details() && 1146 (tracker.has_synced_details() &&
1184 tracker.synced_details().title() == updated_details.title() && 1147 tracker.synced_details().title() == updated_details.title() &&
1185 !updated_details.missing())); 1148 !updated_details.missing()));
1186 1149
1187 if (tracker_id != GetSyncRootTrackerID()) { 1150 if (tracker_id != GetSyncRootTrackerID()) {
1188 // Check if the tracker's parent is still in |parent_tracker_ids|. 1151 // Check if the tracker's parent is still in |parent_tracker_ids|.
1189 // If not, there should exist another tracker for the new parent, so delete 1152 // If not, there should exist another tracker for the new parent, so delete
1190 // old tracker. 1153 // old tracker.
1191 FileTracker parent_tracker; 1154 FileTracker parent_tracker;
1192 index_->GetFileTracker(tracker.parent_tracker_id(), &parent_tracker); 1155 index_->GetFileTracker(tracker.parent_tracker_id(), &parent_tracker);
1193 1156
1194 if (!HasFileAsParent(updated_details, parent_tracker.file_id())) { 1157 if (!HasFileAsParent(updated_details, parent_tracker.file_id())) {
1195 RemoveFileTracker(tracker.tracker_id(), 1158 RemoveFileTracker(tracker.tracker_id(),
1196 MARK_SAME_PATH_TRACKERS_DIRTY, 1159 MARK_SAME_PATH_TRACKERS_DIRTY,
1197 index_.get(), batch.get()); 1160 index_.get());
1198 WriteToDatabase(batch.Pass(), callback); 1161 WriteToDatabase(callback);
1199 return; 1162 return;
1200 } 1163 }
1201 1164
1202 if (tracker.has_synced_details()) { 1165 if (tracker.has_synced_details()) {
1203 // Check if the tracker was retitled. If it was, there should exist 1166 // Check if the tracker was retitled. If it was, there should exist
1204 // another tracker for the new title, so delete the tracker being updated. 1167 // another tracker for the new title, so delete the tracker being updated.
1205 if (tracker.synced_details().title() != updated_details.title()) { 1168 if (tracker.synced_details().title() != updated_details.title()) {
1206 RemoveFileTracker(tracker.tracker_id(), 1169 RemoveFileTracker(tracker.tracker_id(),
1207 MARK_SAME_FILE_ID_TRACKERS_DIRTY, 1170 MARK_SAME_FILE_ID_TRACKERS_DIRTY,
1208 index_.get(), batch.get()); 1171 index_.get());
1209 WriteToDatabase(batch.Pass(), callback); 1172 WriteToDatabase(callback);
1210 return; 1173 return;
1211 } 1174 }
1212 } else { 1175 } else {
1213 // Check if any other tracker exists has the same parent, title and 1176 // Check if any other tracker exists has the same parent, title and
1214 // file_id to the updated tracker. If it exists, delete the tracker being 1177 // file_id to the updated tracker. If it exists, delete the tracker being
1215 // updated. 1178 // updated.
1216 if (FilterFileTrackersByFileID( 1179 if (FilterFileTrackersByFileID(
1217 index_.get(), 1180 index_.get(),
1218 index_->GetFileTrackerIDsByParentAndTitle( 1181 index_->GetFileTrackerIDsByParentAndTitle(
1219 parent_tracker.tracker_id(), 1182 parent_tracker.tracker_id(),
1220 updated_details.title()), 1183 updated_details.title()),
1221 tracker.file_id(), 1184 tracker.file_id(),
1222 NULL)) { 1185 NULL)) {
1223 RemoveFileTracker(tracker.tracker_id(), 1186 RemoveFileTracker(tracker.tracker_id(),
1224 MARK_NOTHING_DIRTY, 1187 MARK_NOTHING_DIRTY,
1225 index_.get(), batch.get()); 1188 index_.get());
1226 WriteToDatabase(batch.Pass(), callback); 1189 WriteToDatabase(callback);
1227 return; 1190 return;
1228 } 1191 }
1229 } 1192 }
1230 } 1193 }
1231 1194
1232 scoped_ptr<FileTracker> updated_tracker = CloneFileTracker(&tracker); 1195 scoped_ptr<FileTracker> updated_tracker = CloneFileTracker(&tracker);
1233 *updated_tracker->mutable_synced_details() = updated_details; 1196 *updated_tracker->mutable_synced_details() = updated_details;
1234 1197
1235 // Activate the tracker if: 1198 // Activate the tracker if:
1236 // - There is no active tracker that tracks |tracker->file_id()|. 1199 // - There is no active tracker that tracks |tracker->file_id()|.
1237 // - There is no active tracker that has the same |parent| and |title|. 1200 // - There is no active tracker that has the same |parent| and |title|.
1238 if (!tracker.active() && CanActivateTracker(tracker)) { 1201 if (!tracker.active() && CanActivateTracker(tracker)) {
1239 updated_tracker->set_active(true); 1202 updated_tracker->set_active(true);
1240 updated_tracker->set_dirty(true); 1203 updated_tracker->set_dirty(true);
1241 updated_tracker->set_needs_folder_listing( 1204 updated_tracker->set_needs_folder_listing(
1242 tracker.synced_details().file_kind() == FILE_KIND_FOLDER); 1205 tracker.synced_details().file_kind() == FILE_KIND_FOLDER);
1243 } else if (tracker.dirty() && !ShouldKeepDirty(tracker)) { 1206 } else if (tracker.dirty() && !ShouldKeepDirty(tracker)) {
1244 updated_tracker->set_dirty(false); 1207 updated_tracker->set_dirty(false);
1245 } 1208 }
1246 index_->StoreFileTracker(updated_tracker.Pass(), batch.get()); 1209 index_->StoreFileTracker(updated_tracker.Pass());
1247 1210
1248 WriteToDatabase(batch.Pass(), callback); 1211 WriteToDatabase(callback);
1249 } 1212 }
1250 1213
1251 MetadataDatabase::ActivationStatus MetadataDatabase::TryActivateTracker( 1214 MetadataDatabase::ActivationStatus MetadataDatabase::TryActivateTracker(
1252 int64 parent_tracker_id, 1215 int64 parent_tracker_id,
1253 const std::string& file_id, 1216 const std::string& file_id,
1254 const SyncStatusCallback& callback) { 1217 const SyncStatusCallback& callback) {
1255 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1218 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1256 1219
1257 FileMetadata metadata; 1220 FileMetadata metadata;
1258 if (!index_->GetFileMetadata(file_id, &metadata)) { 1221 if (!index_->GetFileMetadata(file_id, &metadata)) {
(...skipping 12 matching lines...) Expand all
1271 FilterFileTrackersByParentAndTitle( 1234 FilterFileTrackersByParentAndTitle(
1272 index_.get(), same_file_id_trackers, parent_tracker_id, 1235 index_.get(), same_file_id_trackers, parent_tracker_id,
1273 title, tracker_to_be_activated.get()); 1236 title, tracker_to_be_activated.get());
1274 1237
1275 // Check if there is another active tracker that tracks |file_id|. 1238 // Check if there is another active tracker that tracks |file_id|.
1276 // This can happen when the tracked file has multiple parents. 1239 // This can happen when the tracked file has multiple parents.
1277 // In this case, report the failure to the caller. 1240 // In this case, report the failure to the caller.
1278 if (!tracker_to_be_activated->active() && same_file_id_trackers.has_active()) 1241 if (!tracker_to_be_activated->active() && same_file_id_trackers.has_active())
1279 return ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER; 1242 return ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER;
1280 1243
1281 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
1282
1283 if (!tracker_to_be_activated->active()) { 1244 if (!tracker_to_be_activated->active()) {
1284 // Check if there exists another active tracker that has the same path to 1245 // Check if there exists another active tracker that has the same path to
1285 // the tracker. If there is, deactivate it, assuming the caller already 1246 // the tracker. If there is, deactivate it, assuming the caller already
1286 // overrides local file with newly added file, 1247 // overrides local file with newly added file,
1287 TrackerIDSet same_title_trackers = 1248 TrackerIDSet same_title_trackers =
1288 index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title); 1249 index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title);
1289 if (same_title_trackers.has_active()) { 1250 if (same_title_trackers.has_active()) {
1290 RemoveAllDescendantTrackers(same_title_trackers.active_tracker(), 1251 RemoveAllDescendantTrackers(same_title_trackers.active_tracker(),
1291 index_.get(), batch.get()); 1252 index_.get());
1292 1253
1293 scoped_ptr<FileTracker> tracker_to_be_deactivated(new FileTracker); 1254 scoped_ptr<FileTracker> tracker_to_be_deactivated(new FileTracker);
1294 if (index_->GetFileTracker(same_title_trackers.active_tracker(), 1255 if (index_->GetFileTracker(same_title_trackers.active_tracker(),
1295 tracker_to_be_deactivated.get())) { 1256 tracker_to_be_deactivated.get())) {
1296 const std::string file_id = tracker_to_be_deactivated->file_id(); 1257 const std::string file_id = tracker_to_be_deactivated->file_id();
1297 tracker_to_be_deactivated->set_active(false); 1258 tracker_to_be_deactivated->set_active(false);
1298 index_->StoreFileTracker(tracker_to_be_deactivated.Pass(), batch.get()); 1259 index_->StoreFileTracker(tracker_to_be_deactivated.Pass());
1299 1260
1300 MarkTrackersDirtyByFileID(file_id, index_.get(), batch.get()); 1261 MarkTrackersDirtyByFileID(file_id, index_.get());
1301 } else { 1262 } else {
1302 NOTREACHED(); 1263 NOTREACHED();
1303 } 1264 }
1304 } 1265 }
1305 } 1266 }
1306 1267
1307 tracker_to_be_activated->set_dirty(false); 1268 tracker_to_be_activated->set_dirty(false);
1308 tracker_to_be_activated->set_active(true); 1269 tracker_to_be_activated->set_active(true);
1309 *tracker_to_be_activated->mutable_synced_details() = metadata.details(); 1270 *tracker_to_be_activated->mutable_synced_details() = metadata.details();
1310 if (tracker_to_be_activated->synced_details().file_kind() == 1271 if (tracker_to_be_activated->synced_details().file_kind() ==
1311 FILE_KIND_FOLDER) { 1272 FILE_KIND_FOLDER) {
1312 tracker_to_be_activated->set_needs_folder_listing(true); 1273 tracker_to_be_activated->set_needs_folder_listing(true);
1313 } 1274 }
1314 tracker_to_be_activated->set_dirty(false); 1275 tracker_to_be_activated->set_dirty(false);
1315 1276
1316 index_->StoreFileTracker(tracker_to_be_activated.Pass(), batch.get()); 1277 index_->StoreFileTracker(tracker_to_be_activated.Pass());
1317 1278
1318 WriteToDatabase(batch.Pass(), callback); 1279 WriteToDatabase(callback);
1319 return ACTIVATION_PENDING; 1280 return ACTIVATION_PENDING;
1320 } 1281 }
1321 1282
1322 void MetadataDatabase::LowerTrackerPriority(int64 tracker_id) { 1283 void MetadataDatabase::LowerTrackerPriority(int64 tracker_id) {
1323 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1284 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1324 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 1285 index_->DemoteDirtyTracker(tracker_id);
1325 index_->DemoteDirtyTracker(tracker_id, batch.get()); 1286 WriteToDatabase(base::Bind(&EmptyStatusCallback));
1326 WriteToDatabase(batch.Pass(), base::Bind(&EmptyStatusCallback));
1327 } 1287 }
1328 1288
1329 void MetadataDatabase::PromoteLowerPriorityTrackersToNormal() { 1289 void MetadataDatabase::PromoteLowerPriorityTrackersToNormal() {
1330 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1290 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1331 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 1291 index_->PromoteDemotedDirtyTrackers();
1332 index_->PromoteDemotedDirtyTrackers(batch.get()); 1292 WriteToDatabase(base::Bind(&EmptyStatusCallback));
1333 WriteToDatabase(batch.Pass(), base::Bind(&EmptyStatusCallback));
1334 } 1293 }
1335 1294
1336 bool MetadataDatabase::GetNormalPriorityDirtyTracker( 1295 bool MetadataDatabase::GetNormalPriorityDirtyTracker(
1337 FileTracker* tracker_out) const { 1296 FileTracker* tracker_out) const {
1338 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1297 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1339 1298
1340 int64 dirty_tracker_id = index_->PickDirtyTracker(); 1299 int64 dirty_tracker_id = index_->PickDirtyTracker();
1341 if (!dirty_tracker_id) 1300 if (!dirty_tracker_id)
1342 return false; 1301 return false;
1343 1302
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 if (status != SYNC_STATUS_OK) 1428 if (status != SYNC_STATUS_OK)
1470 return status; 1429 return status;
1471 } 1430 }
1472 1431
1473 if (!created) { 1432 if (!created) {
1474 status = MigrateDatabaseIfNeeded(db_.get()); 1433 status = MigrateDatabaseIfNeeded(db_.get());
1475 if (status != SYNC_STATUS_OK) 1434 if (status != SYNC_STATUS_OK)
1476 return status; 1435 return status;
1477 } 1436 }
1478 1437
1479 leveldb::WriteBatch batch; 1438 index_ = MetadataDatabaseIndex::Create(db_.get());
1480 index_ = MetadataDatabaseIndex::Create(db_.get(), &batch);
1481 1439
1482 status = LevelDBStatusToSyncStatusCode( 1440 status = LevelDBStatusToSyncStatusCode(db_->Commit());
1483 db_->Write(leveldb::WriteOptions(), &batch));
1484 if (status != SYNC_STATUS_OK) 1441 if (status != SYNC_STATUS_OK)
1485 return status; 1442 return status;
1486 1443
1487 UpdateLargestKnownChangeID(index_->GetLargestChangeID()); 1444 UpdateLargestKnownChangeID(index_->GetLargestChangeID());
1488 1445
1489 return status; 1446 return status;
1490 } 1447 }
1491 1448
1492 void MetadataDatabase::CreateTrackerForParentAndFileID( 1449 void MetadataDatabase::CreateTrackerForParentAndFileID(
1493 const FileTracker& parent_tracker, 1450 const FileTracker& parent_tracker,
1494 const std::string& file_id, 1451 const std::string& file_id) {
1495 leveldb::WriteBatch* batch) {
1496 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1452 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1497 CreateTrackerInternal(parent_tracker, file_id, NULL, 1453 CreateTrackerInternal(parent_tracker, file_id, NULL,
1498 UPDATE_TRACKER_FOR_UNSYNCED_FILE, 1454 UPDATE_TRACKER_FOR_UNSYNCED_FILE);
1499 batch);
1500 } 1455 }
1501 1456
1502 void MetadataDatabase::CreateTrackerForParentAndFileMetadata( 1457 void MetadataDatabase::CreateTrackerForParentAndFileMetadata(
1503 const FileTracker& parent_tracker, 1458 const FileTracker& parent_tracker,
1504 const FileMetadata& file_metadata, 1459 const FileMetadata& file_metadata,
1505 UpdateOption option, 1460 UpdateOption option) {
1506 leveldb::WriteBatch* batch) {
1507 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1461 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1508 DCHECK(file_metadata.has_details()); 1462 DCHECK(file_metadata.has_details());
1509 CreateTrackerInternal(parent_tracker, 1463 CreateTrackerInternal(parent_tracker,
1510 file_metadata.file_id(), 1464 file_metadata.file_id(),
1511 &file_metadata.details(), 1465 &file_metadata.details(),
1512 option, 1466 option);
1513 batch);
1514 } 1467 }
1515 1468
1516 void MetadataDatabase::CreateTrackerInternal(const FileTracker& parent_tracker, 1469 void MetadataDatabase::CreateTrackerInternal(const FileTracker& parent_tracker,
1517 const std::string& file_id, 1470 const std::string& file_id,
1518 const FileDetails* details, 1471 const FileDetails* details,
1519 UpdateOption option, 1472 UpdateOption option) {
1520 leveldb::WriteBatch* batch) {
1521 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1473 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1522 1474
1523 int64 tracker_id = IncrementTrackerID(batch); 1475 int64 tracker_id = IncrementTrackerID();
1524 scoped_ptr<FileTracker> tracker(new FileTracker); 1476 scoped_ptr<FileTracker> tracker(new FileTracker);
1525 tracker->set_tracker_id(tracker_id); 1477 tracker->set_tracker_id(tracker_id);
1526 tracker->set_parent_tracker_id(parent_tracker.tracker_id()); 1478 tracker->set_parent_tracker_id(parent_tracker.tracker_id());
1527 tracker->set_file_id(file_id); 1479 tracker->set_file_id(file_id);
1528 tracker->set_app_id(parent_tracker.app_id()); 1480 tracker->set_app_id(parent_tracker.app_id());
1529 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); 1481 tracker->set_tracker_kind(TRACKER_KIND_REGULAR);
1530 tracker->set_dirty(true); 1482 tracker->set_dirty(true);
1531 tracker->set_active(false); 1483 tracker->set_active(false);
1532 tracker->set_needs_folder_listing(false); 1484 tracker->set_needs_folder_listing(false);
1533 if (details) { 1485 if (details) {
1534 *tracker->mutable_synced_details() = *details; 1486 *tracker->mutable_synced_details() = *details;
1535 if (option == UPDATE_TRACKER_FOR_UNSYNCED_FILE) { 1487 if (option == UPDATE_TRACKER_FOR_UNSYNCED_FILE) {
1536 tracker->mutable_synced_details()->set_missing(true); 1488 tracker->mutable_synced_details()->set_missing(true);
1537 tracker->mutable_synced_details()->clear_md5(); 1489 tracker->mutable_synced_details()->clear_md5();
1538 } 1490 }
1539 } 1491 }
1540 index_->StoreFileTracker(tracker.Pass(), batch); 1492 index_->StoreFileTracker(tracker.Pass());
1541 } 1493 }
1542 1494
1543 void MetadataDatabase::MaybeAddTrackersForNewFile( 1495 void MetadataDatabase::MaybeAddTrackersForNewFile(
1544 const FileMetadata& metadata, 1496 const FileMetadata& metadata,
1545 UpdateOption option, 1497 UpdateOption option) {
1546 leveldb::WriteBatch* batch) {
1547 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1498 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1548 1499
1549 std::set<int64> parents_to_exclude; 1500 std::set<int64> parents_to_exclude;
1550 TrackerIDSet existing_trackers = 1501 TrackerIDSet existing_trackers =
1551 index_->GetFileTrackerIDsByFileID(metadata.file_id()); 1502 index_->GetFileTrackerIDsByFileID(metadata.file_id());
1552 for (TrackerIDSet::const_iterator itr = existing_trackers.begin(); 1503 for (TrackerIDSet::const_iterator itr = existing_trackers.begin();
1553 itr != existing_trackers.end(); ++itr) { 1504 itr != existing_trackers.end(); ++itr) {
1554 FileTracker tracker; 1505 FileTracker tracker;
1555 if (!index_->GetFileTracker(*itr, &tracker)) { 1506 if (!index_->GetFileTracker(*itr, &tracker)) {
1556 NOTREACHED(); 1507 NOTREACHED();
(...skipping 20 matching lines...) Expand all
1577 itr != parent_trackers.end(); ++itr) { 1528 itr != parent_trackers.end(); ++itr) {
1578 FileTracker parent_tracker; 1529 FileTracker parent_tracker;
1579 index_->GetFileTracker(*itr, &parent_tracker); 1530 index_->GetFileTracker(*itr, &parent_tracker);
1580 if (!parent_tracker.active()) 1531 if (!parent_tracker.active())
1581 continue; 1532 continue;
1582 1533
1583 if (ContainsKey(parents_to_exclude, parent_tracker.tracker_id())) 1534 if (ContainsKey(parents_to_exclude, parent_tracker.tracker_id()))
1584 continue; 1535 continue;
1585 1536
1586 CreateTrackerForParentAndFileMetadata( 1537 CreateTrackerForParentAndFileMetadata(
1587 parent_tracker, metadata, option, batch); 1538 parent_tracker, metadata, option);
1588 } 1539 }
1589 } 1540 }
1590 } 1541 }
1591 1542
1592 int64 MetadataDatabase::IncrementTrackerID(leveldb::WriteBatch* batch) { 1543 int64 MetadataDatabase::IncrementTrackerID() {
1593 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1544 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1594 1545
1595 int64 tracker_id = index_->GetNextTrackerID(); 1546 int64 tracker_id = index_->GetNextTrackerID();
1596 index_->SetNextTrackerID(tracker_id + 1, batch); 1547 index_->SetNextTrackerID(tracker_id + 1);
1597 DCHECK_GT(tracker_id, 0); 1548 DCHECK_GT(tracker_id, 0);
1598 return tracker_id; 1549 return tracker_id;
1599 } 1550 }
1600 1551
1601 bool MetadataDatabase::CanActivateTracker(const FileTracker& tracker) { 1552 bool MetadataDatabase::CanActivateTracker(const FileTracker& tracker) {
1602 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1553 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1603 DCHECK(!tracker.active()); 1554 DCHECK(!tracker.active());
1604 DCHECK_NE(index_->GetSyncRootTrackerID(), tracker.tracker_id()); 1555 DCHECK_NE(index_->GetSyncRootTrackerID(), tracker.tracker_id());
1605 1556
1606 if (HasActiveTrackerForFileID(tracker.file_id())) 1557 if (HasActiveTrackerForFileID(tracker.file_id()))
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 } 1629 }
1679 1630
1680 bool MetadataDatabase::HasActiveTrackerForPath(int64 parent_tracker_id, 1631 bool MetadataDatabase::HasActiveTrackerForPath(int64 parent_tracker_id,
1681 const std::string& title) const { 1632 const std::string& title) const {
1682 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1633 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1683 return index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title) 1634 return index_->GetFileTrackerIDsByParentAndTitle(parent_tracker_id, title)
1684 .has_active(); 1635 .has_active();
1685 } 1636 }
1686 1637
1687 void MetadataDatabase::RemoveUnneededTrackersForMissingFile( 1638 void MetadataDatabase::RemoveUnneededTrackersForMissingFile(
1688 const std::string& file_id, 1639 const std::string& file_id) {
1689 leveldb::WriteBatch* batch) {
1690 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1640 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1691 1641
1692 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id); 1642 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id);
1693 for (TrackerIDSet::const_iterator itr = trackers.begin(); 1643 for (TrackerIDSet::const_iterator itr = trackers.begin();
1694 itr != trackers.end(); ++itr) { 1644 itr != trackers.end(); ++itr) {
1695 FileTracker tracker; 1645 FileTracker tracker;
1696 if (!index_->GetFileTracker(*itr, &tracker)) { 1646 if (!index_->GetFileTracker(*itr, &tracker)) {
1697 NOTREACHED(); 1647 NOTREACHED();
1698 continue; 1648 continue;
1699 } 1649 }
1700 1650
1701 if (!tracker.has_synced_details() || tracker.synced_details().missing()) { 1651 if (!tracker.has_synced_details() || tracker.synced_details().missing()) {
1702 RemoveFileTracker(*itr, MARK_NOTHING_DIRTY, index_.get(), batch); 1652 RemoveFileTracker(*itr, MARK_NOTHING_DIRTY, index_.get());
1703 } 1653 }
1704 } 1654 }
1705 } 1655 }
1706 1656
1707 void MetadataDatabase::UpdateByFileMetadata( 1657 void MetadataDatabase::UpdateByFileMetadata(
1708 const tracked_objects::Location& from_where, 1658 const tracked_objects::Location& from_where,
1709 scoped_ptr<FileMetadata> metadata, 1659 scoped_ptr<FileMetadata> metadata,
1710 UpdateOption option, 1660 UpdateOption option) {
1711 leveldb::WriteBatch* batch) {
1712 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1661 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1713 DCHECK(metadata); 1662 DCHECK(metadata);
1714 DCHECK(metadata->has_details()); 1663 DCHECK(metadata->has_details());
1715 1664
1716 DVLOG(1) << from_where.function_name() << ": " 1665 DVLOG(1) << from_where.function_name() << ": "
1717 << metadata->file_id() << " (" 1666 << metadata->file_id() << " ("
1718 << metadata->details().title() << ")" 1667 << metadata->details().title() << ")"
1719 << (metadata->details().missing() ? " deleted" : ""); 1668 << (metadata->details().missing() ? " deleted" : "");
1720 1669
1721 std::string file_id = metadata->file_id(); 1670 std::string file_id = metadata->file_id();
1722 if (metadata->details().missing()) 1671 if (metadata->details().missing())
1723 RemoveUnneededTrackersForMissingFile(file_id, batch); 1672 RemoveUnneededTrackersForMissingFile(file_id);
1724 else 1673 else
1725 MaybeAddTrackersForNewFile(*metadata, option, batch); 1674 MaybeAddTrackersForNewFile(*metadata, option);
1726 1675
1727 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id); 1676 TrackerIDSet trackers = index_->GetFileTrackerIDsByFileID(file_id);
1728 if (!trackers.empty()) { 1677 if (!trackers.empty()) {
1729 index_->StoreFileMetadata(metadata.Pass(), batch); 1678 index_->StoreFileMetadata(metadata.Pass());
1730 1679
1731 if (option != UPDATE_TRACKER_FOR_SYNCED_FILE) 1680 if (option != UPDATE_TRACKER_FOR_SYNCED_FILE)
1732 MarkTrackerSetDirty(trackers, index_.get(), batch); 1681 MarkTrackerSetDirty(trackers, index_.get());
1733 } 1682 }
1734 } 1683 }
1735 1684
1736 void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch, 1685 void MetadataDatabase::WriteToDatabase(const SyncStatusCallback& callback) {
1737 const SyncStatusCallback& callback) {
1738 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1686 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1739 1687
1740 if (!batch) {
1741 worker_task_runner_->PostTask(
1742 FROM_HERE,
1743 base::Bind(callback, SYNC_STATUS_OK));
1744 return;
1745 }
1746
1747 // TODO(peria): Write to DB on disk synchronously. 1688 // TODO(peria): Write to DB on disk synchronously.
1748 file_task_runner_->PostTask( 1689 file_task_runner_->PostTask(
1749 FROM_HERE, 1690 FROM_HERE,
1750 base::Bind(&WriteOnFileTaskRunner, 1691 base::Bind(&WriteOnFileTaskRunner,
1751 base::Unretained(db_.get()), 1692 base::Unretained(db_.get()),
1752 base::Passed(&batch),
1753 worker_task_runner_, 1693 worker_task_runner_,
1754 callback)); 1694 callback));
1755 } 1695 }
1756 1696
1757 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles( 1697 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles(
1758 const std::string& app_id) { 1698 const std::string& app_id) {
1759 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1699 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1760 1700
1761 scoped_ptr<base::ListValue> files(new base::ListValue); 1701 scoped_ptr<base::ListValue> files(new base::ListValue);
1762 1702
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1930 for (int i = 0; i < details.parent_folder_ids_size(); ++i) 1870 for (int i = 0; i < details.parent_folder_ids_size(); ++i)
1931 parents.push_back(details.parent_folder_ids(i)); 1871 parents.push_back(details.parent_folder_ids(i));
1932 dict->SetString("parents", JoinString(parents, ",")); 1872 dict->SetString("parents", JoinString(parents, ","));
1933 } 1873 }
1934 files->Append(dict); 1874 files->Append(dict);
1935 } 1875 }
1936 return files.Pass(); 1876 return files.Pass();
1937 } 1877 }
1938 1878
1939 void MetadataDatabase::AttachSyncRoot( 1879 void MetadataDatabase::AttachSyncRoot(
1940 const google_apis::FileResource& sync_root_folder, 1880 const google_apis::FileResource& sync_root_folder) {
1941 leveldb::WriteBatch* batch) {
1942 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); 1881 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread());
1943 1882
1944 scoped_ptr<FileMetadata> sync_root_metadata = 1883 scoped_ptr<FileMetadata> sync_root_metadata =
1945 CreateFileMetadataFromFileResource( 1884 CreateFileMetadataFromFileResource(
1946 GetLargestKnownChangeID(), sync_root_folder); 1885 GetLargestKnownChangeID(), sync_root_folder);
1947 scoped_ptr<FileTracker> sync_root_tracker = 1886 scoped_ptr<FileTracker> sync_root_tracker =
1948 CreateSyncRootTracker(IncrementTrackerID(batch), *sync_root_metadata); 1887 CreateSyncRootTracker(IncrementTrackerID(), *sync_root_metadata);
1949 1888
1950 index_->SetSyncRootTrackerID(sync_root_tracker->tracker_id(), batch); 1889 index_->SetSyncRootTrackerID(sync_root_tracker->tracker_id());
1951 index_->StoreFileMetadata(sync_root_metadata.Pass(), batch); 1890 index_->StoreFileMetadata(sync_root_metadata.Pass());
1952 index_->StoreFileTracker(sync_root_tracker.Pass(), batch); 1891 index_->StoreFileTracker(sync_root_tracker.Pass());
1953 } 1892 }
1954 1893
1955 void MetadataDatabase::AttachInitialAppRoot( 1894 void MetadataDatabase::AttachInitialAppRoot(
1956 const google_apis::FileResource& app_root_folder, 1895 const google_apis::FileResource& app_root_folder) {
1957 leveldb::WriteBatch* batch) {
1958 scoped_ptr<FileMetadata> app_root_metadata = 1896 scoped_ptr<FileMetadata> app_root_metadata =
1959 CreateFileMetadataFromFileResource( 1897 CreateFileMetadataFromFileResource(
1960 GetLargestKnownChangeID(), app_root_folder); 1898 GetLargestKnownChangeID(), app_root_folder);
1961 scoped_ptr<FileTracker> app_root_tracker = 1899 scoped_ptr<FileTracker> app_root_tracker =
1962 CreateInitialAppRootTracker(IncrementTrackerID(batch), 1900 CreateInitialAppRootTracker(IncrementTrackerID(),
1963 GetSyncRootTrackerID(), 1901 GetSyncRootTrackerID(),
1964 *app_root_metadata); 1902 *app_root_metadata);
1965 1903
1966 index_->StoreFileMetadata(app_root_metadata.Pass(), batch); 1904 index_->StoreFileMetadata(app_root_metadata.Pass());
1967 index_->StoreFileTracker(app_root_tracker.Pass(), batch); 1905 index_->StoreFileTracker(app_root_tracker.Pass());
1968 } 1906 }
1969 1907
1970 void MetadataDatabase::DetachFromSequence() { 1908 void MetadataDatabase::DetachFromSequence() {
1971 worker_sequence_checker_.DetachFromSequence(); 1909 worker_sequence_checker_.DetachFromSequence();
1972 } 1910 }
1973 1911
1974 } // namespace drive_backend 1912 } // namespace drive_backend
1975 } // namespace sync_file_system 1913 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698