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

Side by Side Diff: chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc

Issue 14108009: chromeos: Use WriteBatch to update DriveResourceMetadata DB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename method Created 7 years, 8 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/chromeos/drive/drive_resource_metadata_storage.h" 5 #include "chrome/browser/chromeos/drive/drive_resource_metadata_storage.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
11 #include "chrome/browser/chromeos/drive/drive.pb.h" 11 #include "chrome/browser/chromeos/drive/drive.pb.h"
12 #include "third_party/leveldatabase/src/include/leveldb/db.h" 12 #include "third_party/leveldatabase/src/include/leveldb/db.h"
13 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
13 14
14 namespace drive { 15 namespace drive {
15 16
16 namespace { 17 namespace {
17 18
18 const base::FilePath::CharType kResourceMapDBName[] = 19 const base::FilePath::CharType kResourceMapDBName[] =
19 FILE_PATH_LITERAL("resource_metadata_resource_map.db"); 20 FILE_PATH_LITERAL("resource_metadata_resource_map.db");
20 const base::FilePath::CharType kChildMapDBName[] = 21 const base::FilePath::CharType kChildMapDBName[] =
21 FILE_PATH_LITERAL("resource_metadata_child_map.db"); 22 FILE_PATH_LITERAL("resource_metadata_child_map.db");
22 23
23 // Meant to be a character which never happen to be in real resource IDs. 24 // Meant to be a character which never happen to be in real resource IDs.
24 const char kDBKeyDelimeter = '\0'; 25 const char kDBKeyDelimeter = '\0';
25 26
26 // Returns a string to be used as the key for the header. 27 // Returns a string to be used as the key for the header.
27 std::string GetHeaderDBKey() { 28 std::string GetHeaderDBKey() {
28 std::string key; 29 std::string key;
29 key.push_back(kDBKeyDelimeter); 30 key.push_back(kDBKeyDelimeter);
30 key.append("HEADER"); 31 key.append("HEADER");
31 return key; 32 return key;
32 } 33 }
33 34
34 // Returns a string to be used as a key for child entry.
35 std::string GetChildEntryKey(const std::string& parent_resource_id,
36 const std::string& child_name) {
37 std::string key = parent_resource_id;
38 key.push_back(kDBKeyDelimeter);
39 key.append(child_name);
40 key.push_back(kDBKeyDelimeter);
41 return key;
42 }
43
44 // Returns true if |key| is a key for a child entry. 35 // Returns true if |key| is a key for a child entry.
45 bool IsChildEntryKey(const leveldb::Slice& key) { 36 bool IsChildEntryKey(const leveldb::Slice& key) {
46 return !key.empty() && key[key.size() - 1] == kDBKeyDelimeter; 37 return !key.empty() && key[key.size() - 1] == kDBKeyDelimeter;
47 } 38 }
48 39
49 } // namespace 40 } // namespace
50 41
51 DriveResourceMetadataStorage::DriveResourceMetadataStorage( 42 DriveResourceMetadataStorage::DriveResourceMetadataStorage(
52 const base::FilePath& directory_path) 43 const base::FilePath& directory_path)
53 : directory_path_(directory_path) { 44 : directory_path_(directory_path) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 PutHeader(*header); 116 PutHeader(*header);
126 } 117 }
127 118
128 int64 DriveResourceMetadataStorage::GetLargestChangestamp() { 119 int64 DriveResourceMetadataStorage::GetLargestChangestamp() {
129 base::ThreadRestrictions::AssertIOAllowed(); 120 base::ThreadRestrictions::AssertIOAllowed();
130 scoped_ptr<DriveResourceMetadataHeader> header = GetHeader(); 121 scoped_ptr<DriveResourceMetadataHeader> header = GetHeader();
131 DCHECK(header); 122 DCHECK(header);
132 return header->largest_changestamp(); 123 return header->largest_changestamp();
133 } 124 }
134 125
135 void DriveResourceMetadataStorage::PutEntry(const DriveEntryProto& entry) { 126 bool DriveResourceMetadataStorage::PutEntry(const DriveEntryProto& entry) {
136 base::ThreadRestrictions::AssertIOAllowed(); 127 base::ThreadRestrictions::AssertIOAllowed();
137 DCHECK(!entry.resource_id().empty()); 128 DCHECK(!entry.resource_id().empty());
138 129
139 std::string serialized_entry; 130 std::string serialized_entry;
140 if (!entry.SerializeToString(&serialized_entry)) { 131 if (!entry.SerializeToString(&serialized_entry)) {
141 DLOG(ERROR) << "Failed to serialize the entry: " << entry.resource_id(); 132 DLOG(ERROR) << "Failed to serialize the entry: " << entry.resource_id();
142 return; 133 return false;
143 } 134 }
144 135
145 const leveldb::Status status = resource_map_->Put( 136 leveldb::WriteBatch batch;
146 leveldb::WriteOptions(), 137
147 leveldb::Slice(entry.resource_id()), 138 // Remove from the old parent.
148 leveldb::Slice(serialized_entry)); 139 scoped_ptr<DriveEntryProto> old_entry = GetEntry(entry.resource_id());
149 DCHECK(status.ok()); 140 if (old_entry && !old_entry->parent_resource_id().empty()) {
141 batch.Delete(GetChildEntryKey(old_entry->parent_resource_id(),
142 old_entry->base_name()));
143 }
144
145 // Add to the new parent.
146 if (!entry.parent_resource_id().empty()) {
147 batch.Put(GetChildEntryKey(entry.parent_resource_id(), entry.base_name()),
148 entry.resource_id());
149 }
150
151 // Put the entry itself.
152 batch.Put(entry.resource_id(), serialized_entry);
153
154 const leveldb::Status status = resource_map_->Write(leveldb::WriteOptions(),
155 &batch);
156 return status.ok();
150 } 157 }
151 158
152 scoped_ptr<DriveEntryProto> DriveResourceMetadataStorage::GetEntry( 159 scoped_ptr<DriveEntryProto> DriveResourceMetadataStorage::GetEntry(
153 const std::string& resource_id) { 160 const std::string& resource_id) {
154 base::ThreadRestrictions::AssertIOAllowed(); 161 base::ThreadRestrictions::AssertIOAllowed();
155 DCHECK(!resource_id.empty()); 162 DCHECK(!resource_id.empty());
156 163
157 std::string serialized_entry; 164 std::string serialized_entry;
158 const leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(), 165 const leveldb::Status status = resource_map_->Get(leveldb::ReadOptions(),
159 leveldb::Slice(resource_id), 166 leveldb::Slice(resource_id),
160 &serialized_entry); 167 &serialized_entry);
161 if (!status.ok()) 168 if (!status.ok())
162 return scoped_ptr<DriveEntryProto>(); 169 return scoped_ptr<DriveEntryProto>();
163 170
164 scoped_ptr<DriveEntryProto> entry(new DriveEntryProto); 171 scoped_ptr<DriveEntryProto> entry(new DriveEntryProto);
165 if (!entry->ParseFromString(serialized_entry)) 172 if (!entry->ParseFromString(serialized_entry))
166 return scoped_ptr<DriveEntryProto>(); 173 return scoped_ptr<DriveEntryProto>();
167 return entry.Pass(); 174 return entry.Pass();
168 } 175 }
169 176
170 void DriveResourceMetadataStorage::RemoveEntry(const std::string& resource_id) { 177 bool DriveResourceMetadataStorage::RemoveEntry(const std::string& resource_id) {
171 base::ThreadRestrictions::AssertIOAllowed(); 178 base::ThreadRestrictions::AssertIOAllowed();
172 DCHECK(!resource_id.empty()); 179 DCHECK(!resource_id.empty());
173 180
174 const leveldb::Status status = resource_map_->Delete( 181 scoped_ptr<DriveEntryProto> entry = GetEntry(resource_id);
175 leveldb::WriteOptions(), 182 if (!entry)
176 leveldb::Slice(resource_id)); 183 return false;
177 DCHECK(status.ok()); 184
185 leveldb::WriteBatch batch;
186
187 // Remove from the parent.
188 if (!entry->parent_resource_id().empty()) {
189 batch.Delete(GetChildEntryKey(entry->parent_resource_id(),
190 entry->base_name()));
191 }
192 // Remove the entry itself.
193 batch.Delete(resource_id);
194
195 const leveldb::Status status = resource_map_->Write(leveldb::WriteOptions(),
196 &batch);
197 return status.ok();
178 } 198 }
179 199
180 void DriveResourceMetadataStorage::Iterate(const IterateCallback& callback) { 200 void DriveResourceMetadataStorage::Iterate(const IterateCallback& callback) {
181 base::ThreadRestrictions::AssertIOAllowed(); 201 base::ThreadRestrictions::AssertIOAllowed();
182 DCHECK(!callback.is_null()); 202 DCHECK(!callback.is_null());
183 203
184 scoped_ptr<leveldb::Iterator> it( 204 scoped_ptr<leveldb::Iterator> it(
185 resource_map_->NewIterator(leveldb::ReadOptions())); 205 resource_map_->NewIterator(leveldb::ReadOptions()));
186 206
187 // Skip the header entry. 207 // Skip the header entry.
188 // Note: The header entry comes before all other entries because its key 208 // Note: The header entry comes before all other entries because its key
189 // starts with kDBKeyDelimeter. (i.e. '\0') 209 // starts with kDBKeyDelimeter. (i.e. '\0')
190 it->Seek(leveldb::Slice(GetHeaderDBKey())); 210 it->Seek(leveldb::Slice(GetHeaderDBKey()));
191 it->Next(); 211 it->Next();
192 212
193 DriveEntryProto entry; 213 DriveEntryProto entry;
194 for (; it->Valid(); it->Next()) { 214 for (; it->Valid(); it->Next()) {
195 if (!IsChildEntryKey(it->key()) && 215 if (!IsChildEntryKey(it->key()) &&
196 entry.ParseFromArray(it->value().data(), it->value().size())) 216 entry.ParseFromArray(it->value().data(), it->value().size()))
197 callback.Run(entry); 217 callback.Run(entry);
198 } 218 }
199 } 219 }
200 220
201 void DriveResourceMetadataStorage::PutChild(
202 const std::string& parent_resource_id,
203 const std::string& child_name,
204 const std::string& child_resource_id) {
205 base::ThreadRestrictions::AssertIOAllowed();
206
207 const leveldb::Status status = resource_map_->Put(
208 leveldb::WriteOptions(),
209 leveldb::Slice(GetChildEntryKey(parent_resource_id, child_name)),
210 leveldb::Slice(child_resource_id));
211 DCHECK(status.ok());
212 }
213
214 std::string DriveResourceMetadataStorage::GetChild( 221 std::string DriveResourceMetadataStorage::GetChild(
215 const std::string& parent_resource_id, 222 const std::string& parent_resource_id,
216 const std::string& child_name) { 223 const std::string& child_name) {
217 base::ThreadRestrictions::AssertIOAllowed(); 224 base::ThreadRestrictions::AssertIOAllowed();
218 225
219 std::string child_resource_id; 226 std::string child_resource_id;
220 resource_map_->Get( 227 resource_map_->Get(
221 leveldb::ReadOptions(), 228 leveldb::ReadOptions(),
222 leveldb::Slice(GetChildEntryKey(parent_resource_id, child_name)), 229 leveldb::Slice(GetChildEntryKey(parent_resource_id, child_name)),
223 &child_resource_id); 230 &child_resource_id);
(...skipping 10 matching lines...) Expand all
234 resource_map_->NewIterator(leveldb::ReadOptions())); 241 resource_map_->NewIterator(leveldb::ReadOptions()));
235 for (it->Seek(parent_resource_id); 242 for (it->Seek(parent_resource_id);
236 it->Valid() && it->key().starts_with(leveldb::Slice(parent_resource_id)); 243 it->Valid() && it->key().starts_with(leveldb::Slice(parent_resource_id));
237 it->Next()) { 244 it->Next()) {
238 if (IsChildEntryKey(it->key())) 245 if (IsChildEntryKey(it->key()))
239 children->push_back(it->value().ToString()); 246 children->push_back(it->value().ToString());
240 } 247 }
241 DCHECK(it->status().ok()); 248 DCHECK(it->status().ok());
242 } 249 }
243 250
244 void DriveResourceMetadataStorage::RemoveChild( 251 // static
252 std::string DriveResourceMetadataStorage::GetChildEntryKey(
245 const std::string& parent_resource_id, 253 const std::string& parent_resource_id,
246 const std::string& child_name) { 254 const std::string& child_name) {
247 base::ThreadRestrictions::AssertIOAllowed(); 255 std::string key = parent_resource_id;
248 256 key.push_back(kDBKeyDelimeter);
249 const leveldb::Status status = resource_map_->Delete( 257 key.append(child_name);
250 leveldb::WriteOptions(), 258 key.push_back(kDBKeyDelimeter);
251 leveldb::Slice(GetChildEntryKey(parent_resource_id, child_name))); 259 return key;
252 DCHECK(status.ok());
253 } 260 }
254 261
255 void DriveResourceMetadataStorage::PutHeader( 262 void DriveResourceMetadataStorage::PutHeader(
256 const DriveResourceMetadataHeader& header) { 263 const DriveResourceMetadataHeader& header) {
257 base::ThreadRestrictions::AssertIOAllowed(); 264 base::ThreadRestrictions::AssertIOAllowed();
258 265
259 std::string serialized_header; 266 std::string serialized_header;
260 if (!header.SerializeToString(&serialized_header)) { 267 if (!header.SerializeToString(&serialized_header)) {
261 DLOG(ERROR) << "Failed to serialize the header"; 268 DLOG(ERROR) << "Failed to serialize the header";
262 return; 269 return;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 361 }
355 if (!it->status().ok() || num_child_entries != num_entries_with_parent) { 362 if (!it->status().ok() || num_child_entries != num_entries_with_parent) {
356 DLOG(ERROR) << "Error during checking resource map. status = " 363 DLOG(ERROR) << "Error during checking resource map. status = "
357 << it->status().ToString(); 364 << it->status().ToString();
358 return false; 365 return false;
359 } 366 }
360 return true; 367 return true;
361 } 368 }
362 369
363 } // namespace drive 370 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698