OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/browser/leveldb_wrapper_impl.h" | 5 #include "content/browser/leveldb_wrapper_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "mojo/common/common_type_converters.h" | |
8 | 9 |
9 namespace content { | 10 namespace content { |
10 | 11 |
11 LevelDBWrapperImpl::LevelDBWrapperImpl( | 12 LevelDBWrapperImpl::LevelDBWrapperImpl( |
12 leveldb::LevelDBDatabase* database, | 13 leveldb::LevelDBDatabase* database, |
13 const std::string& prefix, | 14 const std::string& prefix, |
15 size_t max_size, | |
14 const base::Closure& no_bindings_callback) | 16 const base::Closure& no_bindings_callback) |
15 : prefix_(prefix), | 17 : prefix_(prefix), |
16 no_bindings_callback_(no_bindings_callback), | 18 no_bindings_callback_(no_bindings_callback), |
17 database_(database) { | 19 database_(database), |
20 bytes_used_(0), | |
21 max_size_(max_size) { | |
18 bindings_.set_connection_error_handler(base::Bind( | 22 bindings_.set_connection_error_handler(base::Bind( |
19 &LevelDBWrapperImpl::OnConnectionError, base::Unretained(this))); | 23 &LevelDBWrapperImpl::OnConnectionError, base::Unretained(this))); |
20 } | 24 } |
21 | 25 |
22 void LevelDBWrapperImpl::Bind(LevelDBWrapperRequest request) { | 26 void LevelDBWrapperImpl::Bind(LevelDBWrapperRequest request) { |
23 bindings_.AddBinding(this, std::move(request)); | 27 bindings_.AddBinding(this, std::move(request)); |
24 } | 28 } |
25 | 29 |
26 LevelDBWrapperImpl::~LevelDBWrapperImpl() {} | 30 LevelDBWrapperImpl::~LevelDBWrapperImpl() {} |
27 | 31 |
32 void LevelDBWrapperImpl::AddObserver(LevelDBObserverPtr observer) { | |
33 observers_.AddInterfacePtr(std::move(observer)); | |
34 } | |
35 | |
28 void LevelDBWrapperImpl::Put(mojo::Array<uint8_t> key, | 36 void LevelDBWrapperImpl::Put(mojo::Array<uint8_t> key, |
29 mojo::Array<uint8_t> value, | 37 mojo::Array<uint8_t> value, |
30 const mojo::String& source, | 38 const mojo::String& source, |
31 const PutCallback& callback) { | 39 const PutCallback& callback) { |
32 NOTIMPLEMENTED(); | 40 bool has_old_item = false; |
33 callback.Run(leveldb::DatabaseError::NOT_SUPPORTED); | 41 mojo::Array<uint8_t> old_value; |
42 size_t old_item_size = 0; | |
43 auto found = map_.find(key); | |
44 if (found != map_.end()) { | |
45 old_value = std::move(found->second); | |
46 old_item_size = key.size() + old_value.size(); | |
47 has_old_item = true; | |
48 } | |
49 size_t new_item_size = key.size() + value.size(); | |
50 size_t new_bytes_used = bytes_used_ - old_item_size + new_item_size; | |
51 | |
52 // Only check quota if the size is increasing, this allows | |
53 // shrinking changes to pre-existing maps that are over budget. | |
54 if (new_item_size > old_item_size && new_bytes_used > max_size_) { | |
55 callback.Run(false); | |
56 return; | |
57 } | |
58 | |
59 map_[key.Clone()] = value.Clone(); | |
60 bytes_used_ = new_bytes_used; | |
61 if (!has_old_item) { | |
62 // We added a new key/value pair. | |
63 observers_.ForAllPtrs( | |
64 [&key, &value, &source](LevelDBObserver* observer) { | |
65 observer->KeyAdded(key.Clone(), value.Clone(), source); | |
michaeln
2016/03/29 22:20:46
like we've talked about, the repeated cloning is n
| |
66 }); | |
67 } else { | |
68 // We changed the value for an existing key. | |
69 observers_.ForAllPtrs( | |
70 [&key, &value, &source, &old_value](LevelDBObserver* observer) { | |
71 observer->KeyChanged( | |
72 key.Clone(), value.Clone(), old_value.Clone(), source); | |
73 }); | |
74 } | |
75 callback.Run(true); | |
34 } | 76 } |
35 | 77 |
36 void LevelDBWrapperImpl::Delete(mojo::Array<uint8_t> key, | 78 void LevelDBWrapperImpl::Delete(mojo::Array<uint8_t> key, |
37 const mojo::String& source, | 79 const mojo::String& source, |
38 const DeleteCallback& callback) { | 80 const DeleteCallback& callback) { |
39 NOTIMPLEMENTED(); | 81 auto found = map_.find(key); |
40 callback.Run(leveldb::DatabaseError::NOT_SUPPORTED); | 82 if (found == map_.end()) { |
83 callback.Run(true); | |
84 return; | |
85 } | |
86 | |
87 mojo::Array<uint8_t> old_value = std::move(found->second); | |
88 map_.erase(found); | |
89 bytes_used_ -= key.size() + old_value.size(); | |
90 observers_.ForAllPtrs( | |
91 [&key, &source, &old_value](LevelDBObserver* observer) { | |
92 observer->KeyDeleted( | |
93 key.Clone(), old_value.Clone(), source); | |
94 }); | |
95 callback.Run(true); | |
41 } | 96 } |
42 | 97 |
43 void LevelDBWrapperImpl::DeleteAll(LevelDBObserverPtr observer, | 98 void LevelDBWrapperImpl::DeleteAll(const mojo::String& source, |
44 const mojo::String& source, | |
45 const DeleteAllCallback& callback) { | 99 const DeleteAllCallback& callback) { |
46 // TODO(jam): store observer and call it when changes occur. | 100 map_.clear(); |
47 NOTIMPLEMENTED(); | 101 bytes_used_ = 0; |
48 callback.Run(leveldb::DatabaseError::NOT_SUPPORTED); | 102 observers_.ForAllPtrs( |
103 [&source](LevelDBObserver* observer) { | |
104 observer->AllDeleted(source); | |
105 }); | |
106 callback.Run(true); | |
49 } | 107 } |
50 | 108 |
51 void LevelDBWrapperImpl::Get(mojo::Array<uint8_t> key, | 109 void LevelDBWrapperImpl::GetAll(uint64_t request_id, |
michaeln
2016/03/29 22:20:46
we don't have a use for this method in the localst
jam
2016/03/30 17:15:16
it doesn't harm to keep it there, so let's not rem
michaeln
2016/03/30 21:57:01
Done.
The comment about general purpose'ness is a
| |
52 const GetCallback& callback) { | 110 const GetAllCallback& callback) { |
53 NOTIMPLEMENTED(); | |
54 callback.Run(leveldb::DatabaseError::NOT_SUPPORTED, mojo::Array<uint8_t>()); | |
55 } | |
56 | 111 |
57 void LevelDBWrapperImpl::GetAll(LevelDBObserverPtr observer, | 112 mojo::Array<KeyValuePtr> all(map_.size()); |
58 const GetAllCallback& callback) { | 113 for (const auto& it : map_) { |
59 // TODO(jam): store observer and call it when changes occur. | 114 KeyValuePtr kv = KeyValue::New(); |
60 NOTIMPLEMENTED(); | 115 kv->key = it.first.Clone(); |
61 callback.Run(leveldb::DatabaseError::NOT_SUPPORTED, | 116 kv->value = it.second.Clone(); |
62 mojo::Array<KeyValuePtr>()); | 117 all.push_back(std::move(kv)); |
118 } | |
119 callback.Run(leveldb::DatabaseError::OK, std::move(all)); | |
120 observers_.ForAllPtrs( | |
121 [request_id](LevelDBObserver* observer) { | |
122 observer->GetAllComplete(request_id); | |
123 }); | |
63 } | 124 } |
64 | 125 |
65 void LevelDBWrapperImpl::OnConnectionError() { | 126 void LevelDBWrapperImpl::OnConnectionError() { |
66 if (!bindings_.empty()) | 127 if (!bindings_.empty()) |
67 return; | 128 return; |
68 | 129 |
69 no_bindings_callback_.Run(); | 130 no_bindings_callback_.Run(); |
70 } | 131 } |
71 | 132 |
72 } // namespace content | 133 } // namespace content |
OLD | NEW |