pw_kvs: KeyDescriptor cleanup

- The key and value reading functions only need an address, not the
  KeyDescriptor.
- Have the KeyDescriptor initialize its own hash.
- Remove redundant FlashPartition::Address alias.

Change-Id: I80309f95f6cb0a39dbf12dfa874966d7ff1024fd
diff --git a/pw_kvs/key_value_store.cc b/pw_kvs/key_value_store.cc
index 94d4b32..f9f7811 100644
--- a/pw_kvs/key_value_store.cc
+++ b/pw_kvs/key_value_store.cc
@@ -28,25 +28,6 @@
 using std::byte;
 using std::string_view;
 
-namespace {
-
-using Address = FlashPartition::Address;
-
-// constexpr uint32_t SixFiveFiveNineNine(std::string_view string) {
-constexpr uint32_t HashKey(std::string_view string) {
-  uint32_t hash = 0;
-  uint32_t coefficient = 65599u;
-
-  for (char ch : string) {
-    hash += coefficient * unsigned(ch);
-    coefficient *= 65599u;
-  }
-
-  return hash;
-}
-
-}  // namespace
-
 Status KeyValueStore::Init() {
   // Reset the number of occupied key descriptors; we will fill them later.
   key_descriptor_list_size_ = 0;
@@ -124,10 +105,8 @@
   for (size_t key_id = 0; key_id < key_descriptor_list_size_; ++key_id) {
     uint32_t sector_id =
         key_descriptor_list_[key_id].address / sector_size_bytes;
-    KeyDescriptor key_descriptor;
-    key_descriptor.address = key_descriptor_list_[key_id].address;
     EntryHeader header;
-    TRY(ReadEntryHeader(key_descriptor, &header));
+    TRY(ReadEntryHeader(key_descriptor_list_[key_id].address, &header));
     sector_map_[sector_id].valid_bytes += header.size();
   }
   initialized_ = true;
@@ -138,11 +117,8 @@
                                 Address* next_entry_address) {
   const size_t alignment_bytes = partition_.alignment_bytes();
 
-  KeyDescriptor key_descriptor;
-  key_descriptor.address = entry_address;
-
   EntryHeader header;
-  TRY(ReadEntryHeader(key_descriptor, &header));
+  TRY(ReadEntryHeader(entry_address, &header));
   // TODO: Should likely add a "LogHeader" method or similar.
   DBG("Header: ");
   DBG("   Address      = 0x%zx", size_t(entry_address));
@@ -157,7 +133,6 @@
   if (HeaderLooksLikeUnwrittenData(header)) {
     return Status::NOT_FOUND;
   }
-  key_descriptor.key_version = header.key_version();
 
   // TODO: Handle multiple magics for formats that have changed.
   if (header.magic() != entry_header_format_.magic) {
@@ -171,12 +146,13 @@
 
   // Read the key from flash & validate the entry (which reads the value).
   KeyBuffer key_buffer;
-  TRY(ReadEntryKey(key_descriptor, header.key_length(), key_buffer.data()));
+  TRY(ReadEntryKey(entry_address, header.key_length(), key_buffer.data()));
   const string_view key(key_buffer.data(), header.key_length());
 
   TRY(header.VerifyChecksumInFlash(
-      &partition_, key_descriptor.address, entry_header_format_.checksum));
-  key_descriptor.key_hash = HashKey(key);
+      &partition_, entry_address, entry_header_format_.checksum));
+
+  KeyDescriptor key_descriptor(key, header.key_version(), entry_address);
 
   DBG("Key hash: %zx (%zu)",
       size_t(key_descriptor.key_hash),
@@ -257,7 +233,7 @@
   TRY(FindKeyDescriptor(key, &key_descriptor));
 
   EntryHeader header;
-  TRY(ReadEntryHeader(*key_descriptor, &header));
+  TRY(ReadEntryHeader(key_descriptor->address, &header));
 
   StatusWithSize result = ReadEntryValue(*key_descriptor, header, value_buffer);
   if (result.ok() && options_.verify_on_read) {
@@ -301,9 +277,9 @@
   std::memset(entry_.key_buffer_.data(), 0, entry_.key_buffer_.size());
 
   EntryHeader header;
-  if (entry_.kvs_.ReadEntryHeader(descriptor, &header).ok()) {
+  if (entry_.kvs_.ReadEntryHeader(descriptor.address, &header).ok()) {
     entry_.kvs_.ReadEntryKey(
-        descriptor, header.key_length(), entry_.key_buffer_.data());
+        descriptor.address, header.key_length(), entry_.key_buffer_.data());
   }
 
   return entry_;
@@ -316,11 +292,23 @@
   TRY(FindKeyDescriptor(key, &key_descriptor));
 
   EntryHeader header;
-  TRY(ReadEntryHeader(*key_descriptor, &header));
+  TRY(ReadEntryHeader(key_descriptor->address, &header));
 
   return StatusWithSize(header.value_length());
 }
 
+uint32_t KeyValueStore::HashKey(string_view string) {
+  uint32_t hash = 0;
+  uint32_t coefficient = 65599u;
+
+  for (char ch : string) {
+    hash += coefficient * unsigned(ch);
+    coefficient *= 65599u;
+  }
+
+  return hash;
+}
+
 Status KeyValueStore::FixedSizeGet(std::string_view key,
                                    byte* value,
                                    size_t size_bytes) const {
@@ -354,7 +342,7 @@
   for (auto& descriptor : key_descriptors()) {
     if (descriptor.key_hash == hash) {
       DBG("Found match! For hash: %zx", size_t(hash));
-      TRY(ReadEntryKey(descriptor, key.size(), key_buffer));
+      TRY(ReadEntryKey(descriptor.address, key.size(), key_buffer));
 
       if (key == string_view(key_buffer, key.size())) {
         DBG("Keys matched too");
@@ -366,12 +354,12 @@
   return Status::NOT_FOUND;
 }
 
-Status KeyValueStore::ReadEntryHeader(const KeyDescriptor& descriptor,
+Status KeyValueStore::ReadEntryHeader(Address address,
                                       EntryHeader* header) const {
-  return partition_.Read(descriptor.address, sizeof(*header), header).status();
+  return partition_.Read(address, sizeof(*header), header).status();
 }
 
-Status KeyValueStore::ReadEntryKey(const KeyDescriptor& descriptor,
+Status KeyValueStore::ReadEntryKey(Address address,
                                    size_t key_length,
                                    char* key) const {
   // TODO: This check probably shouldn't be here; this is like
@@ -384,8 +372,7 @@
     return Status::DATA_LOSS;
   }
   // The key is immediately after the entry header.
-  return partition_
-      .Read(descriptor.address + sizeof(EntryHeader), key_length, key)
+  return partition_.Read(address + sizeof(EntryHeader), key_length, key)
       .status();
 }
 
@@ -450,8 +437,9 @@
   // store the key and value in the TempEntry stored in the static allocated
   // working_buffer_.
   EntryHeader header;
-  TRY(ReadEntryHeader(key_descriptor, &header));
-  TRY(ReadEntryKey(key_descriptor, header.key_length(), entry->key.data()));
+  TRY(ReadEntryHeader(key_descriptor.address, &header));
+  TRY(ReadEntryKey(
+      key_descriptor.address, header.key_length(), entry->key.data()));
   string_view key = string_view(entry->key.data(), header.key_length());
   StatusWithSize result = ReadEntryValue(
       key_descriptor, header, as_writable_bytes(span(entry->value)));
diff --git a/pw_kvs/public/pw_kvs/key_value_store.h b/pw_kvs/public/pw_kvs/key_value_store.h
index f38592d..8661251 100644
--- a/pw_kvs/public/pw_kvs/key_value_store.h
+++ b/pw_kvs/public/pw_kvs/key_value_store.h
@@ -207,6 +207,11 @@
   using Address = FlashPartition::Address;
 
   struct KeyDescriptor {
+    KeyDescriptor() = default;
+
+    KeyDescriptor(std::string_view key, uint32_t version, Address address)
+        : key_hash(HashKey(key)), key_version(version), address(address) {}
+
     uint32_t key_hash;
     uint32_t key_version;
     Address address;  // In partition address.
@@ -221,6 +226,8 @@
     }
   };
 
+  static uint32_t HashKey(std::string_view string);
+
   Status FixedSizeGet(std::string_view key,
                       std::byte* value,
                       size_t size_bytes) const;
@@ -240,11 +247,8 @@
         key, const_cast<const KeyDescriptor**>(result));
   }
 
-  Status ReadEntryHeader(const KeyDescriptor& descriptor,
-                         EntryHeader* header) const;
-  Status ReadEntryKey(const KeyDescriptor& descriptor,
-                      size_t key_length,
-                      char* key) const;
+  Status ReadEntryHeader(Address address, EntryHeader* header) const;
+  Status ReadEntryKey(Address address, size_t key_length, char* key) const;
 
   StatusWithSize ReadEntryValue(const KeyDescriptor& key_descriptor,
                                 const EntryHeader& header,