Chromium Code Reviews| Index: chrome/browser/chromeos/gdata/gdata_files.cc |
| =================================================================== |
| --- chrome/browser/chromeos/gdata/gdata_files.cc (revision 148059) |
| +++ chrome/browser/chromeos/gdata/gdata_files.cc (working copy) |
| @@ -9,12 +9,16 @@ |
| #include "base/platform_file.h" |
| #include "base/string_util.h" |
| #include "base/stringprintf.h" |
| +#include "base/sequenced_task_runner.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" |
| +#include "content/public/browser/browser_thread.h" |
| #include "net/base/escape.h" |
| +using content::BrowserThread; |
| + |
| namespace gdata { |
| namespace { |
| @@ -437,7 +441,8 @@ |
| // GDataDirectoryService class implementation. |
| GDataDirectoryService::GDataDirectoryService() |
| - : serialized_size_(0), |
| + : blocking_task_runner_(NULL), |
| + serialized_size_(0), |
| largest_changestamp_(0), |
| origin_(UNINITIALIZED) { |
| root_.reset(new GDataDirectory(NULL, this)); |
| @@ -536,6 +541,129 @@ |
| base::Bind(&RefreshFileInternal, base::Passed(&fresh_file))); |
| } |
| +void GDataDirectoryService::InitFromDB( |
| + const FilePath& db_path, |
| + base::SequencedTaskRunner* blocking_task_runner) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(!db_path.empty()); |
| + DCHECK(blocking_task_runner); |
| + |
| + db_path_ = db_path; |
| + blocking_task_runner_ = blocking_task_runner; |
| + |
| + SerializedMap* serialized_resources(new SerializedMap); |
| + blocking_task_runner_->PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind(&GDataDirectoryService::ReadFromDBOnBlockingThread, |
| + base::Unretained(this), |
| + db_path, |
| + serialized_resources), |
| + base::Bind(&GDataDirectoryService::InitResourceMapOnUIThread, |
| + base::Unretained(this), |
|
hashimoto
2012/07/24 08:41:51
Is this Unretained safe?
satorux1
2012/07/24 16:30:34
should use WeakPtr here.
|
| + base::Owned(serialized_resources))); |
|
satorux1
2012/07/24 16:30:34
Seems to me that initialization from the DB is sig
|
| +} |
| + |
| +void GDataDirectoryService::ReadFromDBOnBlockingThread( |
| + const FilePath& db_path, |
| + SerializedMap* serialized_resources) { |
| + DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); |
| + InitDBOnBlockingThread(db_path); |
| + |
| + if (serialized_resources) { |
| + scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( |
| + leveldb::ReadOptions())); |
| + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { |
| + serialized_resources->insert(std::make_pair(iter->key().ToString(), |
| + iter->value().ToString())); |
| + } |
| + } |
| +} |
| + |
| +void GDataDirectoryService::InitDBOnBlockingThread(const FilePath& db_path) { |
| + DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); |
| + DCHECK(!db_path.empty()); |
| + |
| + db_path_ = db_path; |
| + leveldb::DB* level_db = NULL; |
| + leveldb::Options options; |
| + options.create_if_missing = true; |
| + leveldb::Status db_status = leveldb::DB::Open(options, db_path.value(), |
| + &level_db); |
| + DCHECK(level_db); |
| + DCHECK(db_status.ok()); |
| + level_db_.reset(level_db); |
| +} |
| + |
| +void GDataDirectoryService::InitResourceMapOnUIThread( |
| + SerializedMap* serialized_resources) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(resource_map_.empty()); |
| + |
| + ResourceMap resource_map; |
| + for (SerializedMap::const_iterator iter = serialized_resources->begin(); |
| + iter != serialized_resources->end(); ++iter) { |
| + scoped_ptr<GDataEntry> entry = GDataEntry::FromProtoString(iter->second); |
| + resource_map.insert(std::make_pair(iter->first, entry.release())); |
| + } |
| + |
| + // Fix up parent-child relations. |
| + for (ResourceMap::iterator iter = resource_map.begin(); |
| + iter != resource_map.end(); ++iter) { |
| + GDataEntry* entry = iter->second; |
| + ResourceMap::iterator parent_it = |
| + resource_map.find(entry->parent_resource_id()); |
| + if (parent_it != resource_map.end()) { |
| + GDataDirectory* parent = parent_it->second->AsGDataDirectory(); |
| + if (parent) { |
| + parent->AddEntry(entry); |
| + } else { |
| + NOTREACHED() << "Parent is not a directory " << parent->resource_id(); |
| + } |
| + } else { |
| + NOTREACHED() << "Missing parent id " << entry->parent_resource_id(); |
| + } |
| + } |
| +} |
| + |
| +void GDataDirectoryService::SaveResourceMapToDB() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + SerializedMap serialized_resources; |
| + for (ResourceMap::const_iterator iter = resource_map_.begin(); |
| + iter != resource_map_.end(); ++iter) { |
| + GDataEntryProto proto; |
| + iter->second->ToProtoFull(&proto); |
| + std::string serialized_string; |
| + const bool ok = proto.SerializeToString(&serialized_string); |
| + DCHECK(ok); |
| + if (ok) { |
| + serialized_resources.insert( |
| + std::make_pair(iter->first, serialized_string)); |
| + } |
| + } |
| + blocking_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&GDataDirectoryService::SaveSerializedToDBOnBlockingThread, |
| + base::Unretained(this), |
| + serialized_resources)); |
| +} |
| + |
| +void GDataDirectoryService::SaveSerializedToDBOnBlockingThread( |
| + const SerializedMap& serialized_resources) { |
| + DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); |
| + |
| + // Truncate the DB. |
| + level_db_.reset(); |
| + leveldb::DestroyDB(db_path_.value(), leveldb::Options()); |
| + InitDBOnBlockingThread(db_path_); |
| + |
| + for (SerializedMap::const_iterator iter = serialized_resources.begin(); |
| + iter != serialized_resources.end(); ++iter) { |
| + level_db_->Put(leveldb::WriteOptions(), |
| + leveldb::Slice(iter->first), |
| + leveldb::Slice(iter->second)); |
| + } |
| +} |
| + |
| // Convert to/from proto. |
| // static |