| OLD | NEW |
| 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/chromeos/drive/resource_metadata_storage.h" | 5 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/metrics/sparse_histogram.h" | 12 #include "base/metrics/sparse_histogram.h" |
| 13 #include "base/sequenced_task_runner.h" | 13 #include "base/sequenced_task_runner.h" |
| 14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
| 15 #include "chrome/browser/chromeos/drive/drive.pb.h" | 15 #include "chrome/browser/chromeos/drive/drive.pb.h" |
| 16 #include "third_party/leveldatabase/env_chromium.h" |
| 16 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 17 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| 17 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 18 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| 18 | 19 |
| 19 namespace drive { | 20 namespace drive { |
| 20 namespace internal { | 21 namespace internal { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 // Enum to describe DB initialization status. | 25 // Enum to describe DB initialization status. |
| 25 enum DBInitStatus { | 26 enum DBInitStatus { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 arraysize(kIdEntryKeyPrefix) - 1); | 120 arraysize(kIdEntryKeyPrefix) - 1); |
| 120 if (key.size() < 2 + expected_prefix.size()) | 121 if (key.size() < 2 + expected_prefix.size()) |
| 121 return false; | 122 return false; |
| 122 const leveldb::Slice key_substring(key.data() + 1, expected_prefix.size()); | 123 const leveldb::Slice key_substring(key.data() + 1, expected_prefix.size()); |
| 123 return key[0] == kDBKeyDelimeter && | 124 return key[0] == kDBKeyDelimeter && |
| 124 key_substring.compare(expected_prefix) == 0 && | 125 key_substring.compare(expected_prefix) == 0 && |
| 125 key[expected_prefix.size() + 1] == kDBKeyDelimeter; | 126 key[expected_prefix.size() + 1] == kDBKeyDelimeter; |
| 126 } | 127 } |
| 127 | 128 |
| 128 // Converts leveldb::Status to DBInitStatus. | 129 // Converts leveldb::Status to DBInitStatus. |
| 129 DBInitStatus LevelDBStatusToDBInitStatus(const leveldb::Status status) { | 130 DBInitStatus LevelDBStatusToDBInitStatus(const leveldb::Status& status) { |
| 130 if (status.ok()) | 131 if (status.ok()) |
| 131 return DB_INIT_SUCCESS; | 132 return DB_INIT_SUCCESS; |
| 132 if (status.IsNotFound()) | 133 if (status.IsNotFound()) |
| 133 return DB_INIT_NOT_FOUND; | 134 return DB_INIT_NOT_FOUND; |
| 134 if (status.IsCorruption()) | 135 if (status.IsCorruption()) |
| 135 return DB_INIT_CORRUPTION; | 136 return DB_INIT_CORRUPTION; |
| 136 if (status.IsIOError()) | 137 if (status.IsIOError()) |
| 137 return DB_INIT_IO_ERROR; | 138 return DB_INIT_IO_ERROR; |
| 138 return DB_INIT_FAILED; | 139 return DB_INIT_FAILED; |
| 139 } | 140 } |
| 140 | 141 |
| 142 // Converts leveldb::Status to FileError. |
| 143 FileError LevelDBStatusToFileError(const leveldb::Status& status) { |
| 144 if (status.ok()) |
| 145 return FILE_ERROR_OK; |
| 146 if (status.IsNotFound()) |
| 147 return FILE_ERROR_NOT_FOUND; |
| 148 if (leveldb_env::IndicatesDiskFull(status)) |
| 149 return FILE_ERROR_NO_LOCAL_SPACE; |
| 150 return FILE_ERROR_FAILED; |
| 151 } |
| 152 |
| 141 ResourceMetadataHeader GetDefaultHeaderEntry() { | 153 ResourceMetadataHeader GetDefaultHeaderEntry() { |
| 142 ResourceMetadataHeader header; | 154 ResourceMetadataHeader header; |
| 143 header.set_version(ResourceMetadataStorage::kDBVersion); | 155 header.set_version(ResourceMetadataStorage::kDBVersion); |
| 144 return header; | 156 return header; |
| 145 } | 157 } |
| 146 | 158 |
| 147 bool MoveIfPossible(const base::FilePath& from, const base::FilePath& to) { | 159 bool MoveIfPossible(const base::FilePath& from, const base::FilePath& to) { |
| 148 return !base::PathExists(from) || base::Move(from, to); | 160 return !base::PathExists(from) || base::Move(from, to); |
| 149 } | 161 } |
| 150 | 162 |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 status = leveldb::DB::Open(options, resource_map_path.AsUTF8Unsafe(), &db); | 444 status = leveldb::DB::Open(options, resource_map_path.AsUTF8Unsafe(), &db); |
| 433 open_existing_result = LevelDBStatusToDBInitStatus(status); | 445 open_existing_result = LevelDBStatusToDBInitStatus(status); |
| 434 } | 446 } |
| 435 | 447 |
| 436 if (open_existing_result == DB_INIT_SUCCESS) { | 448 if (open_existing_result == DB_INIT_SUCCESS) { |
| 437 resource_map_.reset(db); | 449 resource_map_.reset(db); |
| 438 | 450 |
| 439 // Check the validity of existing DB. | 451 // Check the validity of existing DB. |
| 440 int db_version = -1; | 452 int db_version = -1; |
| 441 ResourceMetadataHeader header; | 453 ResourceMetadataHeader header; |
| 442 if (GetHeader(&header)) | 454 if (GetHeader(&header) == FILE_ERROR_OK) |
| 443 db_version = header.version(); | 455 db_version = header.version(); |
| 444 | 456 |
| 445 bool should_discard_db = true; | 457 bool should_discard_db = true; |
| 446 if (db_version != kDBVersion) { | 458 if (db_version != kDBVersion) { |
| 447 open_existing_result = DB_INIT_INCOMPATIBLE; | 459 open_existing_result = DB_INIT_INCOMPATIBLE; |
| 448 DVLOG(1) << "Reject incompatible DB."; | 460 DVLOG(1) << "Reject incompatible DB."; |
| 449 } else if (!CheckValidity()) { | 461 } else if (!CheckValidity()) { |
| 450 open_existing_result = DB_INIT_BROKEN; | 462 open_existing_result = DB_INIT_BROKEN; |
| 451 LOG(ERROR) << "Reject invalid DB."; | 463 LOG(ERROR) << "Reject invalid DB."; |
| 452 } else { | 464 } else { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 474 | 486 |
| 475 // Create DB. | 487 // Create DB. |
| 476 options.max_open_files = 0; // Use minimum. | 488 options.max_open_files = 0; // Use minimum. |
| 477 options.create_if_missing = true; | 489 options.create_if_missing = true; |
| 478 options.error_if_exists = true; | 490 options.error_if_exists = true; |
| 479 | 491 |
| 480 status = leveldb::DB::Open(options, resource_map_path.AsUTF8Unsafe(), &db); | 492 status = leveldb::DB::Open(options, resource_map_path.AsUTF8Unsafe(), &db); |
| 481 if (status.ok()) { | 493 if (status.ok()) { |
| 482 resource_map_.reset(db); | 494 resource_map_.reset(db); |
| 483 | 495 |
| 484 if (PutHeader(GetDefaultHeaderEntry()) && // Set up header. | 496 // Set up header and trash the old DB. |
| 485 MoveIfPossible(preserved_resource_map_path, // Trash the old DB. | 497 if (PutHeader(GetDefaultHeaderEntry()) == FILE_ERROR_OK && |
| 498 MoveIfPossible(preserved_resource_map_path, |
| 486 trashed_resource_map_path)) { | 499 trashed_resource_map_path)) { |
| 487 init_result = open_existing_result == DB_INIT_NOT_FOUND ? | 500 init_result = open_existing_result == DB_INIT_NOT_FOUND ? |
| 488 DB_INIT_CREATED_NEW_DB : DB_INIT_REPLACED_EXISTING_DB_WITH_NEW_DB; | 501 DB_INIT_CREATED_NEW_DB : DB_INIT_REPLACED_EXISTING_DB_WITH_NEW_DB; |
| 489 } else { | 502 } else { |
| 490 init_result = DB_INIT_FAILED; | 503 init_result = DB_INIT_FAILED; |
| 491 resource_map_.reset(); | 504 resource_map_.reset(); |
| 492 } | 505 } |
| 493 } else { | 506 } else { |
| 494 LOG(ERROR) << "Failed to create resource map DB: " << status.ToString(); | 507 LOG(ERROR) << "Failed to create resource map DB: " << status.ToString(); |
| 495 init_result = LevelDBStatusToDBInitStatus(status); | 508 init_result = LevelDBStatusToDBInitStatus(status); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 if (resource_map->Get(leveldb::ReadOptions(), | 575 if (resource_map->Get(leveldb::ReadOptions(), |
| 563 leveldb::Slice(id), | 576 leveldb::Slice(id), |
| 564 &serialized_entry).ok() && | 577 &serialized_entry).ok() && |
| 565 entry.ParseFromString(serialized_entry)) | 578 entry.ParseFromString(serialized_entry)) |
| 566 info->title = entry.title(); | 579 info->title = entry.title(); |
| 567 } | 580 } |
| 568 } | 581 } |
| 569 } | 582 } |
| 570 } | 583 } |
| 571 | 584 |
| 572 bool ResourceMetadataStorage::SetLargestChangestamp( | 585 FileError ResourceMetadataStorage::SetLargestChangestamp( |
| 573 int64 largest_changestamp) { | 586 int64 largest_changestamp) { |
| 574 base::ThreadRestrictions::AssertIOAllowed(); | 587 base::ThreadRestrictions::AssertIOAllowed(); |
| 575 | 588 |
| 576 ResourceMetadataHeader header; | 589 ResourceMetadataHeader header; |
| 577 if (!GetHeader(&header)) { | 590 FileError error = GetHeader(&header); |
| 591 if (error != FILE_ERROR_OK) { |
| 578 DLOG(ERROR) << "Failed to get the header."; | 592 DLOG(ERROR) << "Failed to get the header."; |
| 579 return false; | 593 return error; |
| 580 } | 594 } |
| 581 header.set_largest_changestamp(largest_changestamp); | 595 header.set_largest_changestamp(largest_changestamp); |
| 582 return PutHeader(header); | 596 return PutHeader(header); |
| 583 } | 597 } |
| 584 | 598 |
| 585 int64 ResourceMetadataStorage::GetLargestChangestamp() { | 599 FileError ResourceMetadataStorage::GetLargestChangestamp( |
| 600 int64* largest_changestamp) { |
| 586 base::ThreadRestrictions::AssertIOAllowed(); | 601 base::ThreadRestrictions::AssertIOAllowed(); |
| 587 ResourceMetadataHeader header; | 602 ResourceMetadataHeader header; |
| 588 if (!GetHeader(&header)) { | 603 FileError error = GetHeader(&header); |
| 604 if (error != FILE_ERROR_OK) { |
| 589 DLOG(ERROR) << "Failed to get the header."; | 605 DLOG(ERROR) << "Failed to get the header."; |
| 590 return 0; | 606 return error; |
| 591 } | 607 } |
| 592 return header.largest_changestamp(); | 608 *largest_changestamp = header.largest_changestamp(); |
| 609 return FILE_ERROR_OK; |
| 593 } | 610 } |
| 594 | 611 |
| 595 bool ResourceMetadataStorage::PutEntry(const ResourceEntry& entry) { | 612 FileError ResourceMetadataStorage::PutEntry(const ResourceEntry& entry) { |
| 596 base::ThreadRestrictions::AssertIOAllowed(); | 613 base::ThreadRestrictions::AssertIOAllowed(); |
| 597 | 614 |
| 598 const std::string& id = entry.local_id(); | 615 const std::string& id = entry.local_id(); |
| 599 DCHECK(!id.empty()); | 616 DCHECK(!id.empty()); |
| 600 | 617 |
| 601 // Try to get existing entry. | 618 // Try to get existing entry. |
| 602 std::string serialized_entry; | 619 std::string serialized_entry; |
| 603 leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(), | 620 leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(), |
| 604 leveldb::Slice(id), | 621 leveldb::Slice(id), |
| 605 &serialized_entry); | 622 &serialized_entry); |
| 606 if (!status.ok() && !status.IsNotFound()) // Unexpected errors. | 623 if (!status.ok() && !status.IsNotFound()) // Unexpected errors. |
| 607 return false; | 624 return LevelDBStatusToFileError(status); |
| 608 | 625 |
| 609 ResourceEntry old_entry; | 626 ResourceEntry old_entry; |
| 610 if (status.ok() && !old_entry.ParseFromString(serialized_entry)) | 627 if (status.ok() && !old_entry.ParseFromString(serialized_entry)) |
| 611 return false; | 628 return FILE_ERROR_FAILED; |
| 612 | 629 |
| 613 // Construct write batch. | 630 // Construct write batch. |
| 614 leveldb::WriteBatch batch; | 631 leveldb::WriteBatch batch; |
| 615 | 632 |
| 616 // Remove from the old parent. | 633 // Remove from the old parent. |
| 617 if (!old_entry.parent_local_id().empty()) { | 634 if (!old_entry.parent_local_id().empty()) { |
| 618 batch.Delete(GetChildEntryKey(old_entry.parent_local_id(), | 635 batch.Delete(GetChildEntryKey(old_entry.parent_local_id(), |
| 619 old_entry.base_name())); | 636 old_entry.base_name())); |
| 620 } | 637 } |
| 621 // Add to the new parent. | 638 // Add to the new parent. |
| 622 if (!entry.parent_local_id().empty()) | 639 if (!entry.parent_local_id().empty()) |
| 623 batch.Put(GetChildEntryKey(entry.parent_local_id(), entry.base_name()), id); | 640 batch.Put(GetChildEntryKey(entry.parent_local_id(), entry.base_name()), id); |
| 624 | 641 |
| 625 // Refresh resource-ID-to-local-ID mapping entry. | 642 // Refresh resource-ID-to-local-ID mapping entry. |
| 626 if (old_entry.resource_id() != entry.resource_id()) { | 643 if (old_entry.resource_id() != entry.resource_id()) { |
| 627 // Resource ID should not change. | 644 // Resource ID should not change. |
| 628 DCHECK(old_entry.resource_id().empty() || entry.resource_id().empty()); | 645 DCHECK(old_entry.resource_id().empty() || entry.resource_id().empty()); |
| 629 | 646 |
| 630 if (!old_entry.resource_id().empty()) | 647 if (!old_entry.resource_id().empty()) |
| 631 batch.Delete(GetIdEntryKey(old_entry.resource_id())); | 648 batch.Delete(GetIdEntryKey(old_entry.resource_id())); |
| 632 if (!entry.resource_id().empty()) | 649 if (!entry.resource_id().empty()) |
| 633 batch.Put(GetIdEntryKey(entry.resource_id()), id); | 650 batch.Put(GetIdEntryKey(entry.resource_id()), id); |
| 634 } | 651 } |
| 635 | 652 |
| 636 // Put the entry itself. | 653 // Put the entry itself. |
| 637 if (!entry.SerializeToString(&serialized_entry)) { | 654 if (!entry.SerializeToString(&serialized_entry)) { |
| 638 DLOG(ERROR) << "Failed to serialize the entry: " << id; | 655 DLOG(ERROR) << "Failed to serialize the entry: " << id; |
| 639 return false; | 656 return FILE_ERROR_FAILED; |
| 640 } | 657 } |
| 641 batch.Put(id, serialized_entry); | 658 batch.Put(id, serialized_entry); |
| 642 | 659 |
| 643 status = resource_map_->Write(leveldb::WriteOptions(), &batch); | 660 status = resource_map_->Write(leveldb::WriteOptions(), &batch); |
| 644 return status.ok(); | 661 return LevelDBStatusToFileError(status); |
| 645 } | 662 } |
| 646 | 663 |
| 647 bool ResourceMetadataStorage::GetEntry(const std::string& id, | 664 FileError ResourceMetadataStorage::GetEntry(const std::string& id, |
| 648 ResourceEntry* out_entry) { | 665 ResourceEntry* out_entry) { |
| 649 base::ThreadRestrictions::AssertIOAllowed(); | 666 base::ThreadRestrictions::AssertIOAllowed(); |
| 650 DCHECK(!id.empty()); | 667 DCHECK(!id.empty()); |
| 651 | 668 |
| 652 std::string serialized_entry; | 669 std::string serialized_entry; |
| 653 const leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(), | 670 const leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(), |
| 654 leveldb::Slice(id), | 671 leveldb::Slice(id), |
| 655 &serialized_entry); | 672 &serialized_entry); |
| 656 return status.ok() && out_entry->ParseFromString(serialized_entry); | 673 if (!status.ok()) |
| 674 return LevelDBStatusToFileError(status); |
| 675 return out_entry->ParseFromString(serialized_entry) ? |
| 676 FILE_ERROR_OK : FILE_ERROR_FAILED; |
| 657 } | 677 } |
| 658 | 678 |
| 659 bool ResourceMetadataStorage::RemoveEntry(const std::string& id) { | 679 FileError ResourceMetadataStorage::RemoveEntry(const std::string& id) { |
| 660 base::ThreadRestrictions::AssertIOAllowed(); | 680 base::ThreadRestrictions::AssertIOAllowed(); |
| 661 DCHECK(!id.empty()); | 681 DCHECK(!id.empty()); |
| 662 | 682 |
| 663 ResourceEntry entry; | 683 ResourceEntry entry; |
| 664 if (!GetEntry(id, &entry)) | 684 FileError error = GetEntry(id, &entry); |
| 665 return false; | 685 if (error != FILE_ERROR_OK) |
| 686 return error; |
| 666 | 687 |
| 667 leveldb::WriteBatch batch; | 688 leveldb::WriteBatch batch; |
| 668 | 689 |
| 669 // Remove from the parent. | 690 // Remove from the parent. |
| 670 if (!entry.parent_local_id().empty()) | 691 if (!entry.parent_local_id().empty()) |
| 671 batch.Delete(GetChildEntryKey(entry.parent_local_id(), entry.base_name())); | 692 batch.Delete(GetChildEntryKey(entry.parent_local_id(), entry.base_name())); |
| 672 | 693 |
| 673 // Remove resource ID-local ID mapping entry. | 694 // Remove resource ID-local ID mapping entry. |
| 674 if (!entry.resource_id().empty()) | 695 if (!entry.resource_id().empty()) |
| 675 batch.Delete(GetIdEntryKey(entry.resource_id())); | 696 batch.Delete(GetIdEntryKey(entry.resource_id())); |
| 676 | 697 |
| 677 // Remove the entry itself. | 698 // Remove the entry itself. |
| 678 batch.Delete(id); | 699 batch.Delete(id); |
| 679 | 700 |
| 680 const leveldb::Status status = resource_map_->Write(leveldb::WriteOptions(), | 701 const leveldb::Status status = resource_map_->Write(leveldb::WriteOptions(), |
| 681 &batch); | 702 &batch); |
| 682 return status.ok(); | 703 return LevelDBStatusToFileError(status); |
| 683 } | 704 } |
| 684 | 705 |
| 685 scoped_ptr<ResourceMetadataStorage::Iterator> | 706 scoped_ptr<ResourceMetadataStorage::Iterator> |
| 686 ResourceMetadataStorage::GetIterator() { | 707 ResourceMetadataStorage::GetIterator() { |
| 687 base::ThreadRestrictions::AssertIOAllowed(); | 708 base::ThreadRestrictions::AssertIOAllowed(); |
| 688 | 709 |
| 689 scoped_ptr<leveldb::Iterator> it( | 710 scoped_ptr<leveldb::Iterator> it( |
| 690 resource_map_->NewIterator(leveldb::ReadOptions())); | 711 resource_map_->NewIterator(leveldb::ReadOptions())); |
| 691 return make_scoped_ptr(new Iterator(it.Pass())); | 712 return make_scoped_ptr(new Iterator(it.Pass())); |
| 692 } | 713 } |
| 693 | 714 |
| 694 std::string ResourceMetadataStorage::GetChild(const std::string& parent_id, | 715 FileError ResourceMetadataStorage::GetChild(const std::string& parent_id, |
| 695 const std::string& child_name) { | 716 const std::string& child_name, |
| 717 std::string* child_id) { |
| 696 base::ThreadRestrictions::AssertIOAllowed(); | 718 base::ThreadRestrictions::AssertIOAllowed(); |
| 697 DCHECK(!parent_id.empty()); | 719 DCHECK(!parent_id.empty()); |
| 698 DCHECK(!child_name.empty()); | 720 DCHECK(!child_name.empty()); |
| 699 | 721 |
| 700 std::string child_id; | 722 const leveldb::Status status = |
| 701 resource_map_->Get(leveldb::ReadOptions(), | 723 resource_map_->Get( |
| 702 leveldb::Slice(GetChildEntryKey(parent_id, child_name)), | 724 leveldb::ReadOptions(), |
| 703 &child_id); | 725 leveldb::Slice(GetChildEntryKey(parent_id, child_name)), |
| 704 return child_id; | 726 child_id); |
| 727 return LevelDBStatusToFileError(status); |
| 705 } | 728 } |
| 706 | 729 |
| 707 void ResourceMetadataStorage::GetChildren(const std::string& parent_id, | 730 FileError ResourceMetadataStorage::GetChildren( |
| 708 std::vector<std::string>* children) { | 731 const std::string& parent_id, |
| 732 std::vector<std::string>* children) { |
| 709 base::ThreadRestrictions::AssertIOAllowed(); | 733 base::ThreadRestrictions::AssertIOAllowed(); |
| 710 DCHECK(!parent_id.empty()); | 734 DCHECK(!parent_id.empty()); |
| 711 | 735 |
| 712 // Iterate over all entries with keys starting with |parent_id|. | 736 // Iterate over all entries with keys starting with |parent_id|. |
| 713 scoped_ptr<leveldb::Iterator> it( | 737 scoped_ptr<leveldb::Iterator> it( |
| 714 resource_map_->NewIterator(leveldb::ReadOptions())); | 738 resource_map_->NewIterator(leveldb::ReadOptions())); |
| 715 for (it->Seek(parent_id); | 739 for (it->Seek(parent_id); |
| 716 it->Valid() && it->key().starts_with(leveldb::Slice(parent_id)); | 740 it->Valid() && it->key().starts_with(leveldb::Slice(parent_id)); |
| 717 it->Next()) { | 741 it->Next()) { |
| 718 if (IsChildEntryKey(it->key())) | 742 if (IsChildEntryKey(it->key())) |
| 719 children->push_back(it->value().ToString()); | 743 children->push_back(it->value().ToString()); |
| 720 } | 744 } |
| 721 DCHECK(it->status().ok()); | 745 return LevelDBStatusToFileError(it->status()); |
| 722 } | 746 } |
| 723 | 747 |
| 724 bool ResourceMetadataStorage::PutCacheEntry(const std::string& id, | 748 FileError ResourceMetadataStorage::PutCacheEntry(const std::string& id, |
| 725 const FileCacheEntry& entry) { | 749 const FileCacheEntry& entry) { |
| 726 base::ThreadRestrictions::AssertIOAllowed(); | 750 base::ThreadRestrictions::AssertIOAllowed(); |
| 727 DCHECK(!id.empty()); | 751 DCHECK(!id.empty()); |
| 728 | 752 |
| 729 std::string serialized_entry; | 753 std::string serialized_entry; |
| 730 if (!entry.SerializeToString(&serialized_entry)) { | 754 if (!entry.SerializeToString(&serialized_entry)) { |
| 731 DLOG(ERROR) << "Failed to serialize the entry."; | 755 DLOG(ERROR) << "Failed to serialize the entry."; |
| 732 return false; | 756 return FILE_ERROR_FAILED; |
| 733 } | 757 } |
| 734 | 758 |
| 735 const leveldb::Status status = resource_map_->Put( | 759 const leveldb::Status status = resource_map_->Put( |
| 736 leveldb::WriteOptions(), | 760 leveldb::WriteOptions(), |
| 737 leveldb::Slice(GetCacheEntryKey(id)), | 761 leveldb::Slice(GetCacheEntryKey(id)), |
| 738 leveldb::Slice(serialized_entry)); | 762 leveldb::Slice(serialized_entry)); |
| 739 return status.ok(); | 763 return LevelDBStatusToFileError(status); |
| 740 } | 764 } |
| 741 | 765 |
| 742 bool ResourceMetadataStorage::GetCacheEntry(const std::string& id, | 766 FileError ResourceMetadataStorage::GetCacheEntry(const std::string& id, |
| 743 FileCacheEntry* out_entry) { | 767 FileCacheEntry* out_entry) { |
| 744 base::ThreadRestrictions::AssertIOAllowed(); | 768 base::ThreadRestrictions::AssertIOAllowed(); |
| 745 DCHECK(!id.empty()); | 769 DCHECK(!id.empty()); |
| 746 | 770 |
| 747 std::string serialized_entry; | 771 std::string serialized_entry; |
| 748 const leveldb::Status status = resource_map_->Get( | 772 const leveldb::Status status = resource_map_->Get( |
| 749 leveldb::ReadOptions(), | 773 leveldb::ReadOptions(), |
| 750 leveldb::Slice(GetCacheEntryKey(id)), | 774 leveldb::Slice(GetCacheEntryKey(id)), |
| 751 &serialized_entry); | 775 &serialized_entry); |
| 752 return status.ok() && out_entry->ParseFromString(serialized_entry); | 776 if (!status.ok()) |
| 777 return LevelDBStatusToFileError(status); |
| 778 return out_entry->ParseFromString(serialized_entry) ? |
| 779 FILE_ERROR_OK : FILE_ERROR_FAILED; |
| 753 } | 780 } |
| 754 | 781 |
| 755 bool ResourceMetadataStorage::RemoveCacheEntry(const std::string& id) { | 782 FileError ResourceMetadataStorage::RemoveCacheEntry(const std::string& id) { |
| 756 base::ThreadRestrictions::AssertIOAllowed(); | 783 base::ThreadRestrictions::AssertIOAllowed(); |
| 757 DCHECK(!id.empty()); | 784 DCHECK(!id.empty()); |
| 758 | 785 |
| 759 const leveldb::Status status = resource_map_->Delete( | 786 const leveldb::Status status = resource_map_->Delete( |
| 760 leveldb::WriteOptions(), | 787 leveldb::WriteOptions(), |
| 761 leveldb::Slice(GetCacheEntryKey(id))); | 788 leveldb::Slice(GetCacheEntryKey(id))); |
| 762 return status.ok(); | 789 return LevelDBStatusToFileError(status); |
| 763 } | 790 } |
| 764 | 791 |
| 765 scoped_ptr<ResourceMetadataStorage::CacheEntryIterator> | 792 scoped_ptr<ResourceMetadataStorage::CacheEntryIterator> |
| 766 ResourceMetadataStorage::GetCacheEntryIterator() { | 793 ResourceMetadataStorage::GetCacheEntryIterator() { |
| 767 base::ThreadRestrictions::AssertIOAllowed(); | 794 base::ThreadRestrictions::AssertIOAllowed(); |
| 768 | 795 |
| 769 scoped_ptr<leveldb::Iterator> it( | 796 scoped_ptr<leveldb::Iterator> it( |
| 770 resource_map_->NewIterator(leveldb::ReadOptions())); | 797 resource_map_->NewIterator(leveldb::ReadOptions())); |
| 771 return make_scoped_ptr(new CacheEntryIterator(it.Pass())); | 798 return make_scoped_ptr(new CacheEntryIterator(it.Pass())); |
| 772 } | 799 } |
| 773 | 800 |
| 774 ResourceMetadataStorage::RecoveredCacheInfo::RecoveredCacheInfo() | 801 ResourceMetadataStorage::RecoveredCacheInfo::RecoveredCacheInfo() |
| 775 : is_dirty(false) {} | 802 : is_dirty(false) {} |
| 776 | 803 |
| 777 ResourceMetadataStorage::RecoveredCacheInfo::~RecoveredCacheInfo() {} | 804 ResourceMetadataStorage::RecoveredCacheInfo::~RecoveredCacheInfo() {} |
| 778 | 805 |
| 779 bool ResourceMetadataStorage::GetIdByResourceId( | 806 FileError ResourceMetadataStorage::GetIdByResourceId( |
| 780 const std::string& resource_id, | 807 const std::string& resource_id, |
| 781 std::string* out_id) { | 808 std::string* out_id) { |
| 782 base::ThreadRestrictions::AssertIOAllowed(); | 809 base::ThreadRestrictions::AssertIOAllowed(); |
| 783 DCHECK(!resource_id.empty()); | 810 DCHECK(!resource_id.empty()); |
| 784 | 811 |
| 785 const leveldb::Status status = resource_map_->Get( | 812 const leveldb::Status status = resource_map_->Get( |
| 786 leveldb::ReadOptions(), | 813 leveldb::ReadOptions(), |
| 787 leveldb::Slice(GetIdEntryKey(resource_id)), | 814 leveldb::Slice(GetIdEntryKey(resource_id)), |
| 788 out_id); | 815 out_id); |
| 789 return status.ok(); | 816 return LevelDBStatusToFileError(status); |
| 790 } | 817 } |
| 791 | 818 |
| 792 ResourceMetadataStorage::~ResourceMetadataStorage() { | 819 ResourceMetadataStorage::~ResourceMetadataStorage() { |
| 793 base::ThreadRestrictions::AssertIOAllowed(); | 820 base::ThreadRestrictions::AssertIOAllowed(); |
| 794 } | 821 } |
| 795 | 822 |
| 796 void ResourceMetadataStorage::DestroyOnBlockingPool() { | 823 void ResourceMetadataStorage::DestroyOnBlockingPool() { |
| 797 delete this; | 824 delete this; |
| 798 } | 825 } |
| 799 | 826 |
| 800 // static | 827 // static |
| 801 std::string ResourceMetadataStorage::GetChildEntryKey( | 828 std::string ResourceMetadataStorage::GetChildEntryKey( |
| 802 const std::string& parent_id, | 829 const std::string& parent_id, |
| 803 const std::string& child_name) { | 830 const std::string& child_name) { |
| 804 DCHECK(!parent_id.empty()); | 831 DCHECK(!parent_id.empty()); |
| 805 DCHECK(!child_name.empty()); | 832 DCHECK(!child_name.empty()); |
| 806 | 833 |
| 807 std::string key = parent_id; | 834 std::string key = parent_id; |
| 808 key.push_back(kDBKeyDelimeter); | 835 key.push_back(kDBKeyDelimeter); |
| 809 key.append(child_name); | 836 key.append(child_name); |
| 810 key.push_back(kDBKeyDelimeter); | 837 key.push_back(kDBKeyDelimeter); |
| 811 return key; | 838 return key; |
| 812 } | 839 } |
| 813 | 840 |
| 814 bool ResourceMetadataStorage::PutHeader( | 841 FileError ResourceMetadataStorage::PutHeader( |
| 815 const ResourceMetadataHeader& header) { | 842 const ResourceMetadataHeader& header) { |
| 816 base::ThreadRestrictions::AssertIOAllowed(); | 843 base::ThreadRestrictions::AssertIOAllowed(); |
| 817 | 844 |
| 818 std::string serialized_header; | 845 std::string serialized_header; |
| 819 if (!header.SerializeToString(&serialized_header)) { | 846 if (!header.SerializeToString(&serialized_header)) { |
| 820 DLOG(ERROR) << "Failed to serialize the header"; | 847 DLOG(ERROR) << "Failed to serialize the header"; |
| 821 return false; | 848 return FILE_ERROR_FAILED; |
| 822 } | 849 } |
| 823 | 850 |
| 824 const leveldb::Status status = resource_map_->Put( | 851 const leveldb::Status status = resource_map_->Put( |
| 825 leveldb::WriteOptions(), | 852 leveldb::WriteOptions(), |
| 826 leveldb::Slice(GetHeaderDBKey()), | 853 leveldb::Slice(GetHeaderDBKey()), |
| 827 leveldb::Slice(serialized_header)); | 854 leveldb::Slice(serialized_header)); |
| 828 return status.ok(); | 855 return LevelDBStatusToFileError(status); |
| 829 } | 856 } |
| 830 | 857 |
| 831 bool ResourceMetadataStorage::GetHeader(ResourceMetadataHeader* header) { | 858 FileError ResourceMetadataStorage::GetHeader(ResourceMetadataHeader* header) { |
| 832 base::ThreadRestrictions::AssertIOAllowed(); | 859 base::ThreadRestrictions::AssertIOAllowed(); |
| 833 | 860 |
| 834 std::string serialized_header; | 861 std::string serialized_header; |
| 835 const leveldb::Status status = resource_map_->Get( | 862 const leveldb::Status status = resource_map_->Get( |
| 836 leveldb::ReadOptions(), | 863 leveldb::ReadOptions(), |
| 837 leveldb::Slice(GetHeaderDBKey()), | 864 leveldb::Slice(GetHeaderDBKey()), |
| 838 &serialized_header); | 865 &serialized_header); |
| 839 return status.ok() && header->ParseFromString(serialized_header); | 866 if (!status.ok()) |
| 867 return LevelDBStatusToFileError(status); |
| 868 return header->ParseFromString(serialized_header) ? |
| 869 FILE_ERROR_OK : FILE_ERROR_FAILED; |
| 840 } | 870 } |
| 841 | 871 |
| 842 bool ResourceMetadataStorage::CheckValidity() { | 872 bool ResourceMetadataStorage::CheckValidity() { |
| 843 base::ThreadRestrictions::AssertIOAllowed(); | 873 base::ThreadRestrictions::AssertIOAllowed(); |
| 844 | 874 |
| 845 // Perform read with checksums verification enalbed. | 875 // Perform read with checksums verification enalbed. |
| 846 leveldb::ReadOptions options; | 876 leveldb::ReadOptions options; |
| 847 options.verify_checksums = true; | 877 options.verify_checksums = true; |
| 848 | 878 |
| 849 scoped_ptr<leveldb::Iterator> it(resource_map_->NewIterator(options)); | 879 scoped_ptr<leveldb::Iterator> it(resource_map_->NewIterator(options)); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 if (!it->status().ok() || num_child_entries != num_entries_with_parent) { | 975 if (!it->status().ok() || num_child_entries != num_entries_with_parent) { |
| 946 DLOG(ERROR) << "Error during checking resource map. status = " | 976 DLOG(ERROR) << "Error during checking resource map. status = " |
| 947 << it->status().ToString(); | 977 << it->status().ToString(); |
| 948 return false; | 978 return false; |
| 949 } | 979 } |
| 950 return true; | 980 return true; |
| 951 } | 981 } |
| 952 | 982 |
| 953 } // namespace internal | 983 } // namespace internal |
| 954 } // namespace drive | 984 } // namespace drive |
| OLD | NEW |