| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "sync/internal_api/public/attachments/on_disk_attachment_store.h" | 5 #include "sync/internal_api/public/attachments/on_disk_attachment_store.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/sequenced_task_runner.h" | 11 #include "base/sequenced_task_runner.h" |
| 12 #include "sync/internal_api/attachments/proto/attachment_store.pb.h" | 12 #include "sync/internal_api/attachments/proto/attachment_store.pb.h" |
| 13 #include "sync/internal_api/public/attachments/attachment_util.h" |
| 13 #include "sync/protocol/attachments.pb.h" | 14 #include "sync/protocol/attachments.pb.h" |
| 14 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 15 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| 15 #include "third_party/leveldatabase/src/include/leveldb/options.h" | 16 #include "third_party/leveldatabase/src/include/leveldb/options.h" |
| 16 #include "third_party/leveldatabase/src/include/leveldb/slice.h" | 17 #include "third_party/leveldatabase/src/include/leveldb/slice.h" |
| 17 #include "third_party/leveldatabase/src/include/leveldb/status.h" | 18 #include "third_party/leveldatabase/src/include/leveldb/status.h" |
| 18 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 19 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| 19 | 20 |
| 20 namespace syncer { | 21 namespace syncer { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 205 |
| 205 db_ = db.Pass(); | 206 db_ = db.Pass(); |
| 206 return SUCCESS; | 207 return SUCCESS; |
| 207 } | 208 } |
| 208 | 209 |
| 209 scoped_ptr<Attachment> OnDiskAttachmentStore::ReadSingleAttachment( | 210 scoped_ptr<Attachment> OnDiskAttachmentStore::ReadSingleAttachment( |
| 210 const AttachmentId& attachment_id) { | 211 const AttachmentId& attachment_id) { |
| 211 scoped_ptr<Attachment> attachment; | 212 scoped_ptr<Attachment> attachment; |
| 212 | 213 |
| 213 const std::string key = MakeDataKeyFromAttachmentId(attachment_id); | 214 const std::string key = MakeDataKeyFromAttachmentId(attachment_id); |
| 215 const std::string metadata_key = |
| 216 MakeMetadataKeyFromAttachmentId(attachment_id); |
| 217 leveldb::Status status; |
| 218 std::string metadata_str; |
| 219 status = db_->Get(MakeMetadataReadOptions(), metadata_key, &metadata_str); |
| 220 if (!status.ok()) { |
| 221 DVLOG(1) << "DB::Get for metadata failed: status=" << status.ToString(); |
| 222 return attachment.Pass(); |
| 223 } |
| 224 attachment_store_pb::RecordMetadata record_metadata; |
| 225 if (!record_metadata.ParseFromString(metadata_str)) { |
| 226 DVLOG(1) << "RecordMetadata::ParseFromString failed"; |
| 227 return attachment.Pass(); |
| 228 } |
| 214 std::string data_str; | 229 std::string data_str; |
| 215 leveldb::Status status = db_->Get(MakeDataReadOptions(), key, &data_str); | 230 status = db_->Get(MakeDataReadOptions(), key, &data_str); |
| 216 if (status.ok()) { | 231 if (!status.ok()) { |
| 217 scoped_refptr<base::RefCountedMemory> data = | 232 DVLOG(1) << "DB::Get for data failed: status=" << status.ToString(); |
| 218 base::RefCountedString::TakeString(&data_str); | 233 return attachment.Pass(); |
| 219 attachment.reset( | |
| 220 new Attachment(Attachment::CreateWithId(attachment_id, data))); | |
| 221 } else { | |
| 222 DVLOG(1) << "DB::Get failed: status=" << status.ToString(); | |
| 223 } | 234 } |
| 235 scoped_refptr<base::RefCountedMemory> data = |
| 236 base::RefCountedString::TakeString(&data_str); |
| 237 uint32_t crc = ComputeCrc32c(data); |
| 238 if (record_metadata.has_crc32c() && record_metadata.crc32c() != crc) { |
| 239 DVLOG(1) << "Attachment crc does not match"; |
| 240 return attachment.Pass(); |
| 241 } |
| 242 attachment.reset( |
| 243 new Attachment(Attachment::RestoreExisting(attachment_id, data, crc))); |
| 224 return attachment.Pass(); | 244 return attachment.Pass(); |
| 225 } | 245 } |
| 226 | 246 |
| 227 bool OnDiskAttachmentStore::WriteSingleAttachment( | 247 bool OnDiskAttachmentStore::WriteSingleAttachment( |
| 228 const Attachment& attachment) { | 248 const Attachment& attachment) { |
| 229 const std::string metadata_key = | 249 const std::string metadata_key = |
| 230 MakeMetadataKeyFromAttachmentId(attachment.GetId()); | 250 MakeMetadataKeyFromAttachmentId(attachment.GetId()); |
| 231 const std::string data_key = MakeDataKeyFromAttachmentId(attachment.GetId()); | 251 const std::string data_key = MakeDataKeyFromAttachmentId(attachment.GetId()); |
| 232 | 252 |
| 233 std::string metadata_str; | 253 std::string metadata_str; |
| 234 leveldb::Status status = | 254 leveldb::Status status = |
| 235 db_->Get(MakeMetadataReadOptions(), metadata_key, &metadata_str); | 255 db_->Get(MakeMetadataReadOptions(), metadata_key, &metadata_str); |
| 236 if (status.ok()) { | 256 if (status.ok()) { |
| 237 // Entry exists, don't overwrite. | 257 // Entry exists, don't overwrite. |
| 238 return true; | 258 return true; |
| 239 } else if (!status.IsNotFound()) { | 259 } else if (!status.IsNotFound()) { |
| 240 // Entry exists but failed to read. | 260 // Entry exists but failed to read. |
| 241 DVLOG(1) << "DB::Get failed: status=" << status.ToString(); | 261 DVLOG(1) << "DB::Get failed: status=" << status.ToString(); |
| 242 return false; | 262 return false; |
| 243 } | 263 } |
| 244 DCHECK(status.IsNotFound()); | 264 DCHECK(status.IsNotFound()); |
| 245 | 265 |
| 246 leveldb::WriteBatch write_batch; | 266 leveldb::WriteBatch write_batch; |
| 247 // Write metadata. | 267 // Write metadata. |
| 248 attachment_store_pb::RecordMetadata metadata; | 268 attachment_store_pb::RecordMetadata metadata; |
| 249 metadata.set_attachment_size(attachment.GetData()->size()); | 269 metadata.set_attachment_size(attachment.GetData()->size()); |
| 270 metadata.set_crc32c(attachment.GetCrc32c()); |
| 250 metadata_str = metadata.SerializeAsString(); | 271 metadata_str = metadata.SerializeAsString(); |
| 251 write_batch.Put(metadata_key, metadata_str); | 272 write_batch.Put(metadata_key, metadata_str); |
| 252 // Write data. | 273 // Write data. |
| 253 scoped_refptr<base::RefCountedMemory> data = attachment.GetData(); | 274 scoped_refptr<base::RefCountedMemory> data = attachment.GetData(); |
| 254 leveldb::Slice data_slice(data->front_as<char>(), data->size()); | 275 leveldb::Slice data_slice(data->front_as<char>(), data->size()); |
| 255 write_batch.Put(data_key, data_slice); | 276 write_batch.Put(data_key, data_slice); |
| 256 | 277 |
| 257 status = db_->Write(MakeWriteOptions(), &write_batch); | 278 status = db_->Write(MakeWriteOptions(), &write_batch); |
| 258 if (!status.ok()) { | 279 if (!status.ok()) { |
| 259 // Failed to write. | 280 // Failed to write. |
| 260 DVLOG(1) << "DB::Write failed: status=" << status.ToString(); | 281 DVLOG(1) << "DB::Write failed: status=" << status.ToString(); |
| 261 return false; | 282 return false; |
| 262 } | 283 } |
| 263 return true; | 284 return true; |
| 264 } | 285 } |
| 265 | 286 |
| 266 std::string OnDiskAttachmentStore::MakeDataKeyFromAttachmentId( | 287 std::string OnDiskAttachmentStore::MakeDataKeyFromAttachmentId( |
| 267 const AttachmentId& attachment_id) { | 288 const AttachmentId& attachment_id) { |
| 268 std::string key = kDataPrefix + attachment_id.GetProto().unique_id(); | 289 std::string key = kDataPrefix + attachment_id.GetProto().unique_id(); |
| 269 return key; | 290 return key; |
| 270 } | 291 } |
| 271 | 292 |
| 272 std::string OnDiskAttachmentStore::MakeMetadataKeyFromAttachmentId( | 293 std::string OnDiskAttachmentStore::MakeMetadataKeyFromAttachmentId( |
| 273 const AttachmentId& attachment_id) { | 294 const AttachmentId& attachment_id) { |
| 274 std::string key = kMetadataPrefix + attachment_id.GetProto().unique_id(); | 295 std::string key = kMetadataPrefix + attachment_id.GetProto().unique_id(); |
| 275 return key; | 296 return key; |
| 276 } | 297 } |
| 277 | 298 |
| 278 } // namespace syncer | 299 } // namespace syncer |
| OLD | NEW |