xref: /aosp_15_r20/external/pigweed/pw_kvs/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker======
4*61c4878aSAndroid Build Coastguard Workerpw_kvs
5*61c4878aSAndroid Build Coastguard Worker======
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_kvs
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard Worker.. tab-set::
10*61c4878aSAndroid Build Coastguard Worker
11*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: app.cpp
12*61c4878aSAndroid Build Coastguard Worker
13*61c4878aSAndroid Build Coastguard Worker      .. code-block:: cpp
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker         #include <cstddef>
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker         #include "pw_kvs/flash_test_partition.h"
18*61c4878aSAndroid Build Coastguard Worker         #include "pw_kvs/key_value_store.h"
19*61c4878aSAndroid Build Coastguard Worker         // Not a required dep; just here for demo comms
20*61c4878aSAndroid Build Coastguard Worker         #include "pw_sys_io/sys_io.h"
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker         // Create our key-value store (KVS). Sector and entry vals for this
23*61c4878aSAndroid Build Coastguard Worker         // demo are based on @pigweed//pw_kvs:fake_flash_64_aligned_partition
24*61c4878aSAndroid Build Coastguard Worker         constexpr size_t kMaxSectors = 6;
25*61c4878aSAndroid Build Coastguard Worker         constexpr size_t kMaxEntries = 64;
26*61c4878aSAndroid Build Coastguard Worker         static constexpr pw::kvs::EntryFormat kvs_format = {
27*61c4878aSAndroid Build Coastguard Worker           .magic = 0xd253a8a9,  // Prod apps should use a random number here
28*61c4878aSAndroid Build Coastguard Worker           .checksum = nullptr
29*61c4878aSAndroid Build Coastguard Worker         };
30*61c4878aSAndroid Build Coastguard Worker         pw::kvs::KeyValueStoreBuffer<kMaxEntries, kMaxSectors> kvs(
31*61c4878aSAndroid Build Coastguard Worker           &pw::kvs::FlashTestPartition(),
32*61c4878aSAndroid Build Coastguard Worker           kvs_format
33*61c4878aSAndroid Build Coastguard Worker         );
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker         kvs.Init();  // Initialize our KVS
36*61c4878aSAndroid Build Coastguard Worker         std::byte in;
37*61c4878aSAndroid Build Coastguard Worker         pw::sys_io::ReadByte(&in).IgnoreError();  // Get a char from the user
38*61c4878aSAndroid Build Coastguard Worker         kvs.Put("in", in);  // Save the char to our key-value store (KVS)
39*61c4878aSAndroid Build Coastguard Worker         std::byte out;
40*61c4878aSAndroid Build Coastguard Worker         kvs.Get("in", &out);  // Test that the KVS stored the data correctly
41*61c4878aSAndroid Build Coastguard Worker         pw::sys_io::WriteByte(out).IgnoreError();  // Echo the char back out
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: BUILD.bazel
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard Worker      .. code-block:: py
46*61c4878aSAndroid Build Coastguard Worker
47*61c4878aSAndroid Build Coastguard Worker         cc_binary(
48*61c4878aSAndroid Build Coastguard Worker             name = "app",
49*61c4878aSAndroid Build Coastguard Worker             srcs = ["app.cc"],
50*61c4878aSAndroid Build Coastguard Worker             # ...
51*61c4878aSAndroid Build Coastguard Worker             deps = [
52*61c4878aSAndroid Build Coastguard Worker                 # ...
53*61c4878aSAndroid Build Coastguard Worker                 "@pigweed//pw_kvs",
54*61c4878aSAndroid Build Coastguard Worker                 "@pigweed//pw_kvs:fake_flash_64_aligned_partition",
55*61c4878aSAndroid Build Coastguard Worker                 # ...
56*61c4878aSAndroid Build Coastguard Worker             ]
57*61c4878aSAndroid Build Coastguard Worker             # ...
58*61c4878aSAndroid Build Coastguard Worker         )
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard Worker``pw_kvs`` is a flash-backed, persistent key-value storage (KVS) system with
61*61c4878aSAndroid Build Coastguard Workerintegrated :ref:`wear leveling <module-pw_kvs-design-wear>`. It's a relatively
62*61c4878aSAndroid Build Coastguard Workerlightweight alternative to a file system.
63*61c4878aSAndroid Build Coastguard Worker
64*61c4878aSAndroid Build Coastguard Worker.. grid:: 2
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard Worker   .. grid-item-card:: :octicon:`rocket` Get started
67*61c4878aSAndroid Build Coastguard Worker      :link: module-pw_kvs-start
68*61c4878aSAndroid Build Coastguard Worker      :link-type: ref
69*61c4878aSAndroid Build Coastguard Worker      :class-item: sales-pitch-cta-primary
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker      Integrate pw_kvs into your project
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard Worker   .. grid-item-card:: :octicon:`code-square` Reference
74*61c4878aSAndroid Build Coastguard Worker      :link: module-pw_kvs-reference
75*61c4878aSAndroid Build Coastguard Worker      :link-type: ref
76*61c4878aSAndroid Build Coastguard Worker      :class-item: sales-pitch-cta-secondary
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker      pw_kvs API reference
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker.. grid:: 2
81*61c4878aSAndroid Build Coastguard Worker
82*61c4878aSAndroid Build Coastguard Worker   .. grid-item-card:: :octicon:`stack` Design
83*61c4878aSAndroid Build Coastguard Worker      :link: module-pw_kvs-design
84*61c4878aSAndroid Build Coastguard Worker      :link-type: ref
85*61c4878aSAndroid Build Coastguard Worker      :class-item: sales-pitch-cta-secondary
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker      How pw_kvs manages state, does garbage collection, etc.
88*61c4878aSAndroid Build Coastguard Worker
89*61c4878aSAndroid Build Coastguard Worker   .. grid-item-card:: :octicon:`graph` Code size analysis
90*61c4878aSAndroid Build Coastguard Worker      :link: module-pw_kvs-size
91*61c4878aSAndroid Build Coastguard Worker      :link-type: ref
92*61c4878aSAndroid Build Coastguard Worker      :class-item: sales-pitch-cta-secondary
93*61c4878aSAndroid Build Coastguard Worker
94*61c4878aSAndroid Build Coastguard Worker      The code size impact of using pw_kvs in your project
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-start:
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Worker-----------
99*61c4878aSAndroid Build Coastguard WorkerGet started
100*61c4878aSAndroid Build Coastguard Worker-----------
101*61c4878aSAndroid Build Coastguard Worker.. tab-set::
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: Bazel
104*61c4878aSAndroid Build Coastguard Worker
105*61c4878aSAndroid Build Coastguard Worker      Add ``@pigweed//pw_kvs`` to your target's ``deps``:
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker      .. code-block::
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker         cc_binary(
110*61c4878aSAndroid Build Coastguard Worker           # ...
111*61c4878aSAndroid Build Coastguard Worker           deps = [
112*61c4878aSAndroid Build Coastguard Worker             # ...
113*61c4878aSAndroid Build Coastguard Worker             "@pigweed//pw_kvs",
114*61c4878aSAndroid Build Coastguard Worker             # ...
115*61c4878aSAndroid Build Coastguard Worker           ]
116*61c4878aSAndroid Build Coastguard Worker         )
117*61c4878aSAndroid Build Coastguard Worker
118*61c4878aSAndroid Build Coastguard Worker      This assumes that your Bazel ``WORKSPACE`` has a `repository
119*61c4878aSAndroid Build Coastguard Worker      <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed``
120*61c4878aSAndroid Build Coastguard Worker      that points to the upstream Pigweed repository.
121*61c4878aSAndroid Build Coastguard Worker
122*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: GN
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker      Add ``$dir_pw_kvs`` to the ``deps`` list in your ``pw_executable()``
125*61c4878aSAndroid Build Coastguard Worker      build target:
126*61c4878aSAndroid Build Coastguard Worker
127*61c4878aSAndroid Build Coastguard Worker      .. code-block::
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker         pw_executable("...") {
130*61c4878aSAndroid Build Coastguard Worker           # ...
131*61c4878aSAndroid Build Coastguard Worker           deps = [
132*61c4878aSAndroid Build Coastguard Worker             # ...
133*61c4878aSAndroid Build Coastguard Worker             "$dir_pw_kvs",
134*61c4878aSAndroid Build Coastguard Worker             # ...
135*61c4878aSAndroid Build Coastguard Worker           ]
136*61c4878aSAndroid Build Coastguard Worker         }
137*61c4878aSAndroid Build Coastguard Worker
138*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: CMake
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard Worker      Link your library to ``pw_kvs``:
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker      .. code-block::
143*61c4878aSAndroid Build Coastguard Worker
144*61c4878aSAndroid Build Coastguard Worker         add_library(my_lib ...)
145*61c4878aSAndroid Build Coastguard Worker         target_link_libraries(my_lib PUBLIC pw_kvs)
146*61c4878aSAndroid Build Coastguard Worker
147*61c4878aSAndroid Build Coastguard WorkerUse ``pw_kvs`` in your C++ code:
148*61c4878aSAndroid Build Coastguard Worker
149*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker   #include "pw_kvs/key_value_store.h"
152*61c4878aSAndroid Build Coastguard Worker
153*61c4878aSAndroid Build Coastguard Worker   // ...
154*61c4878aSAndroid Build Coastguard Worker
155*61c4878aSAndroid Build Coastguard Worker.. _pw_kvs/flash_memory.h: https://cs.opensource.google/pigweed/pigweed/+/main:pw_kvs/public/pw_kvs/flash_memory.h
156*61c4878aSAndroid Build Coastguard Worker
157*61c4878aSAndroid Build Coastguard WorkerImplement the :ref:`flash memory <module-pw_kvs-design-memory>` and
158*61c4878aSAndroid Build Coastguard Worker:ref:`flash partition <module-pw_kvs-design-partitions>` interfaces for
159*61c4878aSAndroid Build Coastguard Workeryour hardware. See `pw_kvs/flash_memory.h`_.
160*61c4878aSAndroid Build Coastguard Worker
161*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-reference:
162*61c4878aSAndroid Build Coastguard Worker
163*61c4878aSAndroid Build Coastguard Worker---------
164*61c4878aSAndroid Build Coastguard WorkerReference
165*61c4878aSAndroid Build Coastguard Worker---------
166*61c4878aSAndroid Build Coastguard Worker
167*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-reference-keyvaluestore:
168*61c4878aSAndroid Build Coastguard Worker
169*61c4878aSAndroid Build Coastguard Worker``pw::kvs::KeyValueStore``
170*61c4878aSAndroid Build Coastguard Worker==========================
171*61c4878aSAndroid Build Coastguard WorkerSee :ref:`module-pw_kvs-design` for architectural details.
172*61c4878aSAndroid Build Coastguard Worker
173*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::kvs::KeyValueStore
174*61c4878aSAndroid Build Coastguard Worker   :members:
175*61c4878aSAndroid Build Coastguard Worker
176*61c4878aSAndroid Build Coastguard WorkerConfiguration
177*61c4878aSAndroid Build Coastguard Worker=============
178*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_LOG_LEVEL
179*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_MAX_FLASH_ALIGNMENT
180*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_REMOVE_DELETED_KEYS_IN_HEAVY_MAINTENANCE
181*61c4878aSAndroid Build Coastguard Worker
182*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design:
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Worker------
185*61c4878aSAndroid Build Coastguard WorkerDesign
186*61c4878aSAndroid Build Coastguard Worker------
187*61c4878aSAndroid Build Coastguard Worker:cpp:class:`pw::kvs::KeyValueStore` ("the KVS") stores key and value data
188*61c4878aSAndroid Build Coastguard Workerpairs. The key-value pairs are stored in :ref:`flash partition
189*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-memory>` as a :ref:`key-value entry
190*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-entries>` (KV entry) that consists of a header/metadata,
191*61c4878aSAndroid Build Coastguard Workerthe key data, and value data. KV entries are accessed through ``Put()``,
192*61c4878aSAndroid Build Coastguard Worker``Get()``, and ``Delete()`` operations.
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-entries:
195*61c4878aSAndroid Build Coastguard Worker
196*61c4878aSAndroid Build Coastguard WorkerKey-value entries
197*61c4878aSAndroid Build Coastguard Worker=================
198*61c4878aSAndroid Build Coastguard WorkerEach key-value (KV) entry consists of a header/metadata, the key data, and
199*61c4878aSAndroid Build Coastguard Workervalue data. Individual KV entries are contained within a single flash sector;
200*61c4878aSAndroid Build Coastguard Workerthey do not cross sector boundaries. Because of this the maximum KV entry size
201*61c4878aSAndroid Build Coastguard Workeris the partition sector size.
202*61c4878aSAndroid Build Coastguard Worker
203*61c4878aSAndroid Build Coastguard WorkerKV entries are appended as needed to sectors, with append operations spread
204*61c4878aSAndroid Build Coastguard Workerover time. Each individual KV entry is written completely as a single
205*61c4878aSAndroid Build Coastguard Workerhigh-level operation. KV entries are appended to a sector as long as space is
206*61c4878aSAndroid Build Coastguard Workeravailable for a given KV entry. Multiple sectors can be active for writing at
207*61c4878aSAndroid Build Coastguard Workerany time.
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard WorkerWhen an entry is updated, an entirely new entry is written to a new location
210*61c4878aSAndroid Build Coastguard Workerthat may or may not be located in the same sectore as the old entry. The new
211*61c4878aSAndroid Build Coastguard Workerentry uses a transaction ID greater than the old entry. The old entry remains
212*61c4878aSAndroid Build Coastguard Workerunaltered "on-disk" but is considered "stale". It is :ref:`garbage collected
213*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-garbage>` at some future time.
214*61c4878aSAndroid Build Coastguard Worker
215*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-state:
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard WorkerState
218*61c4878aSAndroid Build Coastguard Worker=====
219*61c4878aSAndroid Build Coastguard WorkerThe KVS does not store any data/metadata/state in flash beyond the KV
220*61c4878aSAndroid Build Coastguard Workerentries. All KVS state can be derived from the stored KV entries.
221*61c4878aSAndroid Build Coastguard WorkerCurrent state is determined at boot from flash-stored KV entries and
222*61c4878aSAndroid Build Coastguard Workerthen maintained in RAM by the KVS. At all times the KVS is in a valid state
223*61c4878aSAndroid Build Coastguard Workeron-flash; there are no windows of vulnerability to unexpected power loss or
224*61c4878aSAndroid Build Coastguard Workercrash. The old entry for a key is maintained until the new entry for that key
225*61c4878aSAndroid Build Coastguard Workeris written and verified.
226*61c4878aSAndroid Build Coastguard Worker
227*61c4878aSAndroid Build Coastguard WorkerEach KV entry has a unique transaction ID that is incremented for each KVS
228*61c4878aSAndroid Build Coastguard Workerupdate transaction. When determining system state from flash-stored KV entries,
229*61c4878aSAndroid Build Coastguard Workerthe valid entry with the highest transaction ID is considered to be the
230*61c4878aSAndroid Build Coastguard Worker"current" entry of the key. All stored entries of the same key with lower
231*61c4878aSAndroid Build Coastguard Workertransaction IDs are considered old or "stale".
232*61c4878aSAndroid Build Coastguard Worker
233*61c4878aSAndroid Build Coastguard WorkerUpdates/rewrites of a key that has been previously stored is done as a new KV
234*61c4878aSAndroid Build Coastguard Workerentry with an updated transaction ID and the new value for the key. The
235*61c4878aSAndroid Build Coastguard Workerinternal state of the KVS is updated to reflect the new entry. The
236*61c4878aSAndroid Build Coastguard Workerpreviously stored KV entries for that key are not modified or removed from
237*61c4878aSAndroid Build Coastguard Workerflash storage, until garbage collection reclaims the "stale" entries.
238*61c4878aSAndroid Build Coastguard Worker
239*61c4878aSAndroid Build Coastguard Worker`Garbage collection`_ is done by copying any currently valid KV entries in the
240*61c4878aSAndroid Build Coastguard Workersector to be garbage collected to a different sector and then erasing the
241*61c4878aSAndroid Build Coastguard Workersector.
242*61c4878aSAndroid Build Coastguard Worker
243*61c4878aSAndroid Build Coastguard WorkerFlash sectors
244*61c4878aSAndroid Build Coastguard Worker=============
245*61c4878aSAndroid Build Coastguard WorkerEach flash sector is written sequentially in an append-only manner, with each
246*61c4878aSAndroid Build Coastguard Workerfollowing entry write being at a higher address than all of the previous entry
247*61c4878aSAndroid Build Coastguard Workerwrites to that sector since erase. Once information (header, metadata, data,
248*61c4878aSAndroid Build Coastguard Workeretc.) is written to flash, that information is not modified or cleared until a
249*61c4878aSAndroid Build Coastguard Workerfull sector erase occurs as part of garbage collection.
250*61c4878aSAndroid Build Coastguard Worker
251*61c4878aSAndroid Build Coastguard WorkerIndividual KV entries are contained within a single flash sector; they do
252*61c4878aSAndroid Build Coastguard Workernot cross sector boundaries. Flash sectors can contain as many KV entries as
253*61c4878aSAndroid Build Coastguard Workerfit in the sector.
254*61c4878aSAndroid Build Coastguard Worker
255*61c4878aSAndroid Build Coastguard WorkerSectors are the minimum erase size for both :ref:`module-pw_kvs-design-memory`
256*61c4878aSAndroid Build Coastguard Workerand :ref:`module-pw_kvs-design-partitions`. Partitions may have a different
257*61c4878aSAndroid Build Coastguard Workerlogical sector size than the memory they are part of. Partition logical sectors
258*61c4878aSAndroid Build Coastguard Workermay be smaller due to partition overhead (encryption, wear tracking, etc) or
259*61c4878aSAndroid Build Coastguard Workerlarger due to combining raw sectors into larger logical sectors.
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-layers:
262*61c4878aSAndroid Build Coastguard Worker
263*61c4878aSAndroid Build Coastguard WorkerStorage layers
264*61c4878aSAndroid Build Coastguard Worker==============
265*61c4878aSAndroid Build Coastguard WorkerThe flash storage used by the KVS is comprised of two layers, flash memory
266*61c4878aSAndroid Build Coastguard Workerand flash partitions.
267*61c4878aSAndroid Build Coastguard Worker
268*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-memory:
269*61c4878aSAndroid Build Coastguard Worker
270*61c4878aSAndroid Build Coastguard WorkerFlash memory
271*61c4878aSAndroid Build Coastguard Worker------------
272*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashMemory`` is the lower storage layer that manages the raw
273*61c4878aSAndroid Build Coastguard Workerread/write/erase of the flash memory device. It is an abstract base class that
274*61c4878aSAndroid Build Coastguard Workerneeds a concrete implementation before it can be used.
275*61c4878aSAndroid Build Coastguard Worker
276*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FakeFlashMemory`` is a variant that uses RAM rather than flash as
277*61c4878aSAndroid Build Coastguard Workerthe storage media. This is helpful for reducing physical flash wear during unit
278*61c4878aSAndroid Build Coastguard Workertests and development.
279*61c4878aSAndroid Build Coastguard Worker
280*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-partitions:
281*61c4878aSAndroid Build Coastguard Worker
282*61c4878aSAndroid Build Coastguard WorkerFlash partitions
283*61c4878aSAndroid Build Coastguard Worker----------------
284*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartition`` is a subset of a ``pw::kvs::FlashMemory``. Flash
285*61c4878aSAndroid Build Coastguard Workermemory may have one or multiple partition instances that represent different
286*61c4878aSAndroid Build Coastguard Workerparts of the memory, such as partitions for KVS, OTA, snapshots/crashlogs, etc.
287*61c4878aSAndroid Build Coastguard WorkerEach partition has its own separate logical address space starting from zero to
288*61c4878aSAndroid Build Coastguard Worker``size`` bytes of the partition. Partition logical addresses do not always map
289*61c4878aSAndroid Build Coastguard Workerdirectly to memory addresses due to partition encryption, sector headers, etc.
290*61c4878aSAndroid Build Coastguard Worker
291*61c4878aSAndroid Build Coastguard WorkerPartitions support access via ``pw::kvs::NonSeekableWriter`` and
292*61c4878aSAndroid Build Coastguard Worker``pw::kvs::SeekableReader``. The reader defaults to the full size of the
293*61c4878aSAndroid Build Coastguard Workerpartition but can optionally be limited to a smaller range.
294*61c4878aSAndroid Build Coastguard Worker
295*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartition`` is a concrete class that can be used directly. It
296*61c4878aSAndroid Build Coastguard Workerhas several derived variants available, such as
297*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartitionWithStats`` and
298*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartitionWithLogicalSectors``.
299*61c4878aSAndroid Build Coastguard Worker
300*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-alignment:
301*61c4878aSAndroid Build Coastguard Worker
302*61c4878aSAndroid Build Coastguard WorkerAlignment
303*61c4878aSAndroid Build Coastguard Worker=========
304*61c4878aSAndroid Build Coastguard WorkerWrites to flash must have a start address that is a multiple of the flash
305*61c4878aSAndroid Build Coastguard Workerwrite alignment. Write size must also be a multiple of flash write alignment.
306*61c4878aSAndroid Build Coastguard WorkerWrite alignment varies by flash device and partition type. Reads from flash do
307*61c4878aSAndroid Build Coastguard Workernot have any address or size alignment requirement; reads always have a
308*61c4878aSAndroid Build Coastguard Workerminimum alignment of 1.
309*61c4878aSAndroid Build Coastguard Worker
310*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-partitions` may have a different alignment than the
311*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-memory` they are part of, so long as the partition's
312*61c4878aSAndroid Build Coastguard Workeralignment is a multiple of the alignment for the memory.
313*61c4878aSAndroid Build Coastguard Worker
314*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-allocation:
315*61c4878aSAndroid Build Coastguard Worker
316*61c4878aSAndroid Build Coastguard WorkerAllocation
317*61c4878aSAndroid Build Coastguard Worker----------
318*61c4878aSAndroid Build Coastguard WorkerThe KVS requires more storage space than the size of the key-value data
319*61c4878aSAndroid Build Coastguard Workerstored. This is due to the always-free sector required for garbage collection
320*61c4878aSAndroid Build Coastguard Workerand the "write and garbage collect later" approach it uses.
321*61c4878aSAndroid Build Coastguard Worker
322*61c4878aSAndroid Build Coastguard WorkerThe KVS works poorly when stored data takes up more than 75% of the
323*61c4878aSAndroid Build Coastguard Workeravailable storage. It works best when stored data is less than 50%.
324*61c4878aSAndroid Build Coastguard WorkerApplications that need to do garbage collection at scheduled times or that
325*61c4878aSAndroid Build Coastguard Workerwrite very heavily can benefit from additional flash store space.
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard WorkerThe flash storage used by the KVS is multiplied by the amount of
328*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-redundancy` used. A redundancy of 2 will use twice
329*61c4878aSAndroid Build Coastguard Workerthe storage, for example.
330*61c4878aSAndroid Build Coastguard Worker
331*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-redundancy:
332*61c4878aSAndroid Build Coastguard Worker
333*61c4878aSAndroid Build Coastguard WorkerRedundancy
334*61c4878aSAndroid Build Coastguard Worker==========
335*61c4878aSAndroid Build Coastguard WorkerThe KVS supports storing redundant copies of KV entries. For a given redundancy
336*61c4878aSAndroid Build Coastguard Workerlevel (N), N total copies of each KV entry are stored. Redundant copies are
337*61c4878aSAndroid Build Coastguard Workeralways stored in different sectors. This protects against corruption or even
338*61c4878aSAndroid Build Coastguard Workerfull sector loss in N-1 sectors without data loss.
339*61c4878aSAndroid Build Coastguard Worker
340*61c4878aSAndroid Build Coastguard WorkerRedundancy increases flash usage proportional to the redundancy level. The RAM
341*61c4878aSAndroid Build Coastguard Workerusage for KVS internal state has a small increase with redundancy.
342*61c4878aSAndroid Build Coastguard Worker
343*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-garbage:
344*61c4878aSAndroid Build Coastguard Worker
345*61c4878aSAndroid Build Coastguard WorkerGarbage collection
346*61c4878aSAndroid Build Coastguard Worker==================
347*61c4878aSAndroid Build Coastguard WorkerStorage space occupied by stale :ref:`module-pw_kvs-design-entries` is
348*61c4878aSAndroid Build Coastguard Workerreclaimed and made available for reuse through a garbage collection process.
349*61c4878aSAndroid Build Coastguard WorkerThe base garbage collection operation is done to reclaim one sector at a time.
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard WorkerThe KVS always keeps at least one sector free at all times to ensure the
352*61c4878aSAndroid Build Coastguard Workerability to garbage collect. This free sector is used to copy valid entries from
353*61c4878aSAndroid Build Coastguard Workerthe sector to be garbage collected before erasing the sector to be garbage
354*61c4878aSAndroid Build Coastguard Workercollected. The always-free sector is rotated as part of the KVS
355*61c4878aSAndroid Build Coastguard Worker:ref:`wear leveling <module-pw_kvs-design-wear>`.
356*61c4878aSAndroid Build Coastguard Worker
357*61c4878aSAndroid Build Coastguard WorkerGarbage collection can be performed manually, by invoking the methods below,
358*61c4878aSAndroid Build Coastguard Workeror it can be configured to happen automatically.
359*61c4878aSAndroid Build Coastguard Worker
360*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::HeavyMaintenance()`
361*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::FullMaintenance()`
362*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::PartialMaintenance()`
363*61c4878aSAndroid Build Coastguard Worker
364*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-wear:
365*61c4878aSAndroid Build Coastguard Worker
366*61c4878aSAndroid Build Coastguard WorkerWear leveling (flash wear management)
367*61c4878aSAndroid Build Coastguard Worker=====================================
368*61c4878aSAndroid Build Coastguard WorkerWear leveling is accomplished by cycling selection of the next sector to write
369*61c4878aSAndroid Build Coastguard Workerto. This cycling spreads flash wear across all free sectors so that no one
370*61c4878aSAndroid Build Coastguard Workersector is prematurely worn out.
371*61c4878aSAndroid Build Coastguard Worker
372*61c4878aSAndroid Build Coastguard WorkerThe wear leveling decision-making process follows these guidelines:
373*61c4878aSAndroid Build Coastguard Worker
374*61c4878aSAndroid Build Coastguard Worker* Location of new writes/rewrites of KV entries will prefer sectors already
375*61c4878aSAndroid Build Coastguard Worker  in-use (partially filled), with new (blank) sectors used when no in-use
376*61c4878aSAndroid Build Coastguard Worker  sectors have large enough available space for the new write.
377*61c4878aSAndroid Build Coastguard Worker* New (blank) sectors selected cycle sequentially between available free
378*61c4878aSAndroid Build Coastguard Worker  sectors.
379*61c4878aSAndroid Build Coastguard Worker* The wear leveling system searches for the first available sector, starting
380*61c4878aSAndroid Build Coastguard Worker  from the current write sector + 1 and wraps around to start at the end of a
381*61c4878aSAndroid Build Coastguard Worker  partition. This spreads the erase/write cycles for heavily written/rewritten
382*61c4878aSAndroid Build Coastguard Worker  KV entries across all free sectors, reducing wear on any single sector.
383*61c4878aSAndroid Build Coastguard Worker* Erase count is not considered in the wear leveling decision-making process.
384*61c4878aSAndroid Build Coastguard Worker* Sectors with already written KV entries that are not modified will remain in
385*61c4878aSAndroid Build Coastguard Worker  the original sector and not participate in wear-leveling, so long as the
386*61c4878aSAndroid Build Coastguard Worker  KV entries in the sector remain unchanged.
387*61c4878aSAndroid Build Coastguard Worker
388*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-size:
389*61c4878aSAndroid Build Coastguard Worker
390*61c4878aSAndroid Build Coastguard Worker------------------
391*61c4878aSAndroid Build Coastguard WorkerCode size analysis
392*61c4878aSAndroid Build Coastguard Worker------------------
393*61c4878aSAndroid Build Coastguard WorkerThe following size report details the memory usage of ``KeyValueStore`` and
394*61c4878aSAndroid Build Coastguard Worker``FlashPartition``.
395*61c4878aSAndroid Build Coastguard Worker
396*61c4878aSAndroid Build Coastguard Worker.. include:: kvs_size
397