pw_kvs: Put/Get updates
- Combine the two versions of Put into one template function. Values
that convert to span are converted to byte spans. A span is created
for other objects, if they are trivially copyable.
- Update Item::Get and Item::ValueSize to access the value from the
descriptor instead of the key, avoiding the unnecessary descriptor
search.
Change-Id: I11e7ee62d19c1d67a63174208bd82a5cbf66636b
diff --git a/pw_kvs/key_value_store.cc b/pw_kvs/key_value_store.cc
index faf7944..9aed5fe 100644
--- a/pw_kvs/key_value_store.cc
+++ b/pw_kvs/key_value_store.cc
@@ -345,24 +345,10 @@
const KeyDescriptor* key_descriptor;
TRY_WITH_SIZE(FindExistingKeyDescriptor(key, &key_descriptor));
- Entry entry;
- TRY_WITH_SIZE(Entry::Read(partition_, key_descriptor->address(), &entry));
-
- StatusWithSize result = entry.ReadValue(value_buffer, offset_bytes);
- if (result.ok() && options_.verify_on_read && offset_bytes == 0u) {
- Status verify_result = entry.VerifyChecksum(
- entry_header_format_.checksum, key, value_buffer.first(result.size()));
- if (!verify_result.ok()) {
- std::memset(value_buffer.data(), 0, result.size());
- return StatusWithSize(verify_result, 0);
- }
-
- return StatusWithSize(verify_result, result.size());
- }
- return result;
+ return Get(key, *key_descriptor, value_buffer, offset_bytes);
}
-Status KeyValueStore::Put(string_view key, span<const byte> value) {
+Status KeyValueStore::PutBytes(string_view key, span<const byte> value) {
DBG("Writing key/value; key length=%zu, value length=%zu",
key.size(),
value.size());
@@ -453,26 +439,65 @@
const KeyDescriptor* key_descriptor;
TRY_WITH_SIZE(FindExistingKeyDescriptor(key, &key_descriptor));
- Entry entry;
- TRY_WITH_SIZE(Entry::Read(partition_, key_descriptor->address(), &entry));
+ return ValueSize(*key_descriptor);
+}
- return StatusWithSize(entry.value_size());
+StatusWithSize KeyValueStore::Get(string_view key,
+ const KeyDescriptor& descriptor,
+ span<std::byte> value_buffer,
+ size_t offset_bytes) const {
+ Entry entry;
+ TRY_WITH_SIZE(Entry::Read(partition_, descriptor.address(), &entry));
+
+ StatusWithSize result = entry.ReadValue(value_buffer, offset_bytes);
+ if (result.ok() && options_.verify_on_read && offset_bytes == 0u) {
+ Status verify_result = entry.VerifyChecksum(
+ entry_header_format_.checksum, key, value_buffer.first(result.size()));
+ if (!verify_result.ok()) {
+ std::memset(value_buffer.data(), 0, result.size());
+ return StatusWithSize(verify_result, 0);
+ }
+
+ return StatusWithSize(verify_result, result.size());
+ }
+ return result;
}
Status KeyValueStore::FixedSizeGet(std::string_view key,
- byte* value,
+ void* value,
+ size_t size_bytes) const {
+ TRY(CheckOperation(key));
+
+ const KeyDescriptor* descriptor;
+ TRY(FindExistingKeyDescriptor(key, &descriptor));
+
+ return FixedSizeGet(key, *descriptor, value, size_bytes);
+}
+
+Status KeyValueStore::FixedSizeGet(std::string_view key,
+ const KeyDescriptor& descriptor,
+ void* value,
size_t size_bytes) const {
// Ensure that the size of the stored value matches the size of the type.
// Otherwise, report error. This check avoids potential memory corruption.
- StatusWithSize result = ValueSize(key);
- if (!result.ok()) {
- return result.status();
- }
- if (result.size() != size_bytes) {
- DBG("Requested %zu B read, but value is %zu B", size_bytes, result.size());
+ TRY_ASSIGN(const size_t actual_size, ValueSize(descriptor));
+
+ if (actual_size != size_bytes) {
+ DBG("Requested %zu B read, but value is %zu B", size_bytes, actual_size);
return Status::INVALID_ARGUMENT;
}
- return Get(key, span(value, size_bytes)).status();
+
+ StatusWithSize result =
+ Get(key, descriptor, span(static_cast<byte*>(value), size_bytes), 0);
+
+ return result.status();
+}
+
+StatusWithSize KeyValueStore::ValueSize(const KeyDescriptor& descriptor) const {
+ Entry entry;
+ TRY_WITH_SIZE(Entry::Read(partition_, descriptor.address(), &entry));
+
+ return StatusWithSize(entry.value_size());
}
Status KeyValueStore::CheckOperation(string_view key) const {