xref: /aosp_15_r20/external/pigweed/pw_blob_store/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_blob_store:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker=============
4*61c4878aSAndroid Build Coastguard Workerpw_blob_store
5*61c4878aSAndroid Build Coastguard Worker=============
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_blob_store
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard Worker``pw_blob_store`` is a storage container library for storing a single blob of
10*61c4878aSAndroid Build Coastguard Workerdata. ``BlobStore`` is a flash-backed persistent storage system with integrated
11*61c4878aSAndroid Build Coastguard Workerdata integrity checking that serves as a lightweight alternative to a file
12*61c4878aSAndroid Build Coastguard Workersystem.
13*61c4878aSAndroid Build Coastguard Worker
14*61c4878aSAndroid Build Coastguard Worker-----
15*61c4878aSAndroid Build Coastguard WorkerUsage
16*61c4878aSAndroid Build Coastguard Worker-----
17*61c4878aSAndroid Build Coastguard WorkerMost operations on a ``BlobStore`` are done using ``BlobReader`` and
18*61c4878aSAndroid Build Coastguard Worker``BlobWriter`` objects that have been constructed using a ``BlobStore``. Though
19*61c4878aSAndroid Build Coastguard Workera ``BlobStore`` may have multiple open ``BlobReader`` objects, no other
20*61c4878aSAndroid Build Coastguard Workerreaders/writers may be active if a ``BlobWriter`` is opened on a blob store.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard WorkerThe data state of a blob can be checked using the ``HasData()`` method.
23*61c4878aSAndroid Build Coastguard WorkerThe method returns true if the blob is currenty valid and has at least one data
24*61c4878aSAndroid Build Coastguard Workerbyte. This allows checking if a blob has stored data without needing to
25*61c4878aSAndroid Build Coastguard Workerinstantiate and open a reader or writer.
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard WorkerWrite buffer
28*61c4878aSAndroid Build Coastguard Worker============
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard WorkerBlobStore uses a write buffer to allow writes smaller than and/or unaligned to
31*61c4878aSAndroid Build Coastguard Workerthe flash write aligment. BlobStore also supports using the write buffer for
32*61c4878aSAndroid Build Coastguard Workerdeferred writes that can be enqueued and written to flash at a later time or by
33*61c4878aSAndroid Build Coastguard Workera different thread/context.
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard WorkerBlobStore can be used with a zero-size write buffer to reduce memory
36*61c4878aSAndroid Build Coastguard Workerrequirements. When using zero-size write buffer, the user is required to write
37*61c4878aSAndroid Build Coastguard Workermaintain write sizes that are a multiple of the flash write size the blob is
38*61c4878aSAndroid Build Coastguard Workerconfigured for.
39*61c4878aSAndroid Build Coastguard Worker
40*61c4878aSAndroid Build Coastguard WorkerIf a non-zero sized write buffer is used, the write buffer size must be a
41*61c4878aSAndroid Build Coastguard Workermultiple of the flash write size.
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard WorkerWriting to a BlobStore
44*61c4878aSAndroid Build Coastguard Worker----------------------
45*61c4878aSAndroid Build Coastguard Worker``BlobWriter`` objects are ``pw::stream::Writer`` compatible, but do not support
46*61c4878aSAndroid Build Coastguard Workerreading any of the blob's contents. Opening a ``BlobWriter`` on a ``BlobStore``
47*61c4878aSAndroid Build Coastguard Workerthat contains data will discard any existing data if ``Discard()``, ``Write
48*61c4878aSAndroid Build Coastguard Worker()``, or ``Erase()`` are called. Partially written blobs can be resumed using
49*61c4878aSAndroid Build Coastguard Worker``Resume()``. There is currently no mechanism to allow appending to completed
50*61c4878aSAndroid Build Coastguard Workerdata write.
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
53*61c4878aSAndroid Build Coastguard Worker
54*61c4878aSAndroid Build Coastguard Worker   BlobStore::BlobWriterWithBuffer writer(my_blob_store);
55*61c4878aSAndroid Build Coastguard Worker   writer.Open();
56*61c4878aSAndroid Build Coastguard Worker   writer.Write(my_data);
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard Worker   // ...
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard Worker   // A close is implied when a BlobWriter is destroyed. Manually closing a
61*61c4878aSAndroid Build Coastguard Worker   // BlobWriter enables error handling on Close() failure.
62*61c4878aSAndroid Build Coastguard Worker   writer.Close();
63*61c4878aSAndroid Build Coastguard Worker
64*61c4878aSAndroid Build Coastguard WorkerResuming a BlobStore write
65*61c4878aSAndroid Build Coastguard Worker--------------------------
66*61c4878aSAndroid Build Coastguard Worker``BlobWriter::Resume()`` supports resuming writes for blobs that have not been
67*61c4878aSAndroid Build Coastguard Workercompleted (``writer.Close()``). Supported resume situations are after ``Abandon()``
68*61c4878aSAndroid Build Coastguard Workerhas been called on a write or after a crash/reboot with a fresh ``BlobStore``
69*61c4878aSAndroid Build Coastguard Workerinstance.
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker``Resume()`` opens the ``BlobWriter`` at the most recent safe resume point.
72*61c4878aSAndroid Build Coastguard Worker``Resume()`` finds the furthest written point in the flash partition and then backs
73*61c4878aSAndroid Build Coastguard Workerup by erasing any partially written sector plus a full sector. This backing up is to
74*61c4878aSAndroid Build Coastguard Workertry to avoid any corrupted or otherwise wrong data that might have resulted from the
75*61c4878aSAndroid Build Coastguard Workerprevious write failing. ``Resume()`` returns the current number of valid bytes in the
76*61c4878aSAndroid Build Coastguard Workerresumed write.
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard WorkerIf the blob is using a ChecksumAlgorithm, the checksum of the resumed blob write instance
79*61c4878aSAndroid Build Coastguard Workercalculated from the content of the already written data. If it is desired to check the
80*61c4878aSAndroid Build Coastguard Workerintegrity of the already written data, ``BlobWriter::CurrentChecksum()`` can be used to
81*61c4878aSAndroid Build Coastguard Workercheck against the incoming data.
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard WorkerOnce ``Resume()`` has successfully completed, the writer is ready to continue writing
84*61c4878aSAndroid Build Coastguard Workeras normal.
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard WorkerErasing a BlobStore
87*61c4878aSAndroid Build Coastguard Worker===================
88*61c4878aSAndroid Build Coastguard WorkerThere are two distinctly different mechanisms to "erase" the contents of a BlobStore:
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard Worker#. ``Discard()``: Discards any ongoing writes and ensures ``BlobReader`` objects
91*61c4878aSAndroid Build Coastguard Worker   see the ``BlobStore`` as empty. This is the fastest way to logically erase a
92*61c4878aSAndroid Build Coastguard Worker   ``BlobStore``.
93*61c4878aSAndroid Build Coastguard Worker#. ``Erase()``: Performs an explicit flash erase of the ``BlobStore``'s
94*61c4878aSAndroid Build Coastguard Worker   underlying partition. This is useful for manually controlling when a flash
95*61c4878aSAndroid Build Coastguard Worker   erase is performed before a ``BlobWriter`` starts to write data (as flash
96*61c4878aSAndroid Build Coastguard Worker   erase operations may be time-consuming).
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard WorkerNaming a BlobStore's contents
99*61c4878aSAndroid Build Coastguard Worker=============================
100*61c4878aSAndroid Build Coastguard WorkerData in a ``BlobStore`` May be named similarly to a file. This enables
101*61c4878aSAndroid Build Coastguard Workeridentification of a BlobStore's contents in cases where different data may be
102*61c4878aSAndroid Build Coastguard Workerstored to a shared blob store. This requires an additional RAM buffer that can
103*61c4878aSAndroid Build Coastguard Workerbe used to encode the BlobStore's KVS metadata entry. Calling
104*61c4878aSAndroid Build Coastguard Worker``MaxFileNameLength()`` on a ``BlobWriter`` will provide the max file name
105*61c4878aSAndroid Build Coastguard Workerlength based on the ``BlobWriter``'s metadata encode buffer size.
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker``SetFileName()`` performs a copy of the provided file name, meaning it's safe
108*61c4878aSAndroid Build Coastguard Workerfor the ``std::string_view`` to be invalidated after the function returns.
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
111*61c4878aSAndroid Build Coastguard Worker
112*61c4878aSAndroid Build Coastguard Worker   constexpr size_t kMaxFileNameLength = 48;
113*61c4878aSAndroid Build Coastguard Worker   BlobStore::BlobWriterWithBuffer<kMaxFileNameLength> writer(my_blob_store);
114*61c4878aSAndroid Build Coastguard Worker   writer.Open();
115*61c4878aSAndroid Build Coastguard Worker   writer.SetFileName("stonks.jpg");
116*61c4878aSAndroid Build Coastguard Worker   writer.Write(my_data);
117*61c4878aSAndroid Build Coastguard Worker   // ...
118*61c4878aSAndroid Build Coastguard Worker   writer.Close();
119*61c4878aSAndroid Build Coastguard Worker
120*61c4878aSAndroid Build Coastguard WorkerReading from a BlobStore
121*61c4878aSAndroid Build Coastguard Worker------------------------
122*61c4878aSAndroid Build Coastguard WorkerA ``BlobStore`` may have multiple open ``BlobReader`` objects. No other
123*61c4878aSAndroid Build Coastguard Workerreaders/writers may be open/active if a ``BlobWriter`` is opened on a blob
124*61c4878aSAndroid Build Coastguard Workerstore.
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker0) Create BlobReader instance
127*61c4878aSAndroid Build Coastguard Worker1) BlobReader::Open()
128*61c4878aSAndroid Build Coastguard Worker2) Read data using BlobReader::Read() or
129*61c4878aSAndroid Build Coastguard Worker   BlobReader::GetMemoryMappedBlob(). BlobReader is seekable. Use
130*61c4878aSAndroid Build Coastguard Worker   BlobReader::Seek() to read from a desired offset.
131*61c4878aSAndroid Build Coastguard Worker3) BlobReader::Close()
132*61c4878aSAndroid Build Coastguard Worker
133*61c4878aSAndroid Build Coastguard Worker--------------------------
134*61c4878aSAndroid Build Coastguard WorkerFileSystem RPC integration
135*61c4878aSAndroid Build Coastguard Worker--------------------------
136*61c4878aSAndroid Build Coastguard Worker``pw_blob_store`` provides an optional ``FileSystemEntry`` implementation for
137*61c4878aSAndroid Build Coastguard Workeruse with ``pw_file``'s ``FlatFileSystemService``. This simplifies the process of
138*61c4878aSAndroid Build Coastguard Workerenumerating ``BlobStore`` objects as files via ``pw_file``'s ``FileSystem`` RPC
139*61c4878aSAndroid Build Coastguard Workerservice.
140*61c4878aSAndroid Build Coastguard Worker
141*61c4878aSAndroid Build Coastguard Worker-----------
142*61c4878aSAndroid Build Coastguard WorkerSize report
143*61c4878aSAndroid Build Coastguard Worker-----------
144*61c4878aSAndroid Build Coastguard WorkerThe following size report showcases the memory usage of the blob store.
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker.. include:: blob_size
147*61c4878aSAndroid Build Coastguard Worker
148*61c4878aSAndroid Build Coastguard Worker.. note::
149*61c4878aSAndroid Build Coastguard Worker  The documentation for this module is currently incomplete.
150