pw_kvs: Add space reporting methods

This change adds KVS methods to retrieve the total available, used, and
reclaimable storage space.

Change-Id: I5461304d6c25780a3cdc3eb20f480006ae7afa92
diff --git a/pw_kvs/key_value_store.cc b/pw_kvs/key_value_store.cc
index f7fda90..306ad82 100644
--- a/pw_kvs/key_value_store.cc
+++ b/pw_kvs/key_value_store.cc
@@ -199,6 +199,31 @@
   return Status::OK;
 }
 
+KeyValueStore::StorageStats KeyValueStore::GetStorageStats() const {
+  StorageStats stats{0, 0, 0};
+  const size_t sector_size = partition_.sector_size_bytes();
+  bool found_empty_sector = false;
+
+  for (const SectorDescriptor& sector : sectors_) {
+    stats.in_use_bytes += sector.valid_bytes();
+    stats.reclaimable_bytes += sector.RecoverableBytes(sector_size);
+
+    if (!found_empty_sector && sector.Empty(sector_size)) {
+      // The KVS tries to always keep an empty sector for GC, so don't count
+      // the first empty sector seen as writable space. However, a free sector
+      // cannot always be assumed to exist; if a GC operation fails, all sectors
+      // may be partially written, in which case the space reported might be
+      // inaccurate.
+      found_empty_sector = true;
+      continue;
+    }
+
+    stats.writable_bytes += sector.writable_bytes();
+  }
+
+  return stats;
+}
+
 Status KeyValueStore::LoadEntry(Address entry_address,
                                 Address* next_entry_address) {
   Entry entry;
diff --git a/pw_kvs/public/pw_kvs/key_value_store.h b/pw_kvs/public/pw_kvs/key_value_store.h
index aa9d431..1cf60d7 100644
--- a/pw_kvs/public/pw_kvs/key_value_store.h
+++ b/pw_kvs/public/pw_kvs/key_value_store.h
@@ -212,6 +212,14 @@
   // the underlying flash is erased.
   uint32_t transaction_count() const { return last_transaction_id_; }
 
+  struct StorageStats {
+    size_t writable_bytes;
+    size_t in_use_bytes;
+    size_t reclaimable_bytes;
+  };
+
+  StorageStats GetStorageStats() const;
+
  protected:
   using Address = FlashPartition::Address;
   using Entry = internal::Entry;