diff --git a/en/device-dev/subsystems/Readme-EN.md b/en/device-dev/subsystems/Readme-EN.md index e6c5f66624a5eb958520423c154ada32b0a96a49..9e3d89ce67af10918fda94b84e2fd6043945c2bf 100644 --- a/en/device-dev/subsystems/Readme-EN.md +++ b/en/device-dev/subsystems/Readme-EN.md @@ -39,14 +39,21 @@ - [KWS SDK](subsys-aiframework-demo-sdk.md) - [KWS Plug-in](subsys-aiframework-demo-plugin.md) - [KWS Configuration File](subsys-aiframework-demo-conf.md) -- [Data Management](subsys-database.md) - - [RDB](subsys-database-relational.md) - - [RDB Overview](subsys-database-relational-overview.md) - - [RDB Development](subsys-database-relational-guide.md) +- [Data Management](subsys-data.md) + - [RDB](subsys-data-relational-database.md) + - [RDB Overview](subsys-data-relational-database-overview.md) + - [RDB Development](subsys-data-relational-database-guide.md) + - [Lightweight Data Store](subsys-data-storage.md) + - [Lightweight Data Store Overview](subsys-data-storage-overview.md) + - [Lightweight Data Store Development](subsys-data-storage-guide.md) - [Sensors](subsys-sensor.md) - [Sensors Overview](subsys-sensor-overview.md) - [Sensors Usage Guidelines](subsys-sensor-guide.md) - [Sensors Usage Example](subsys-sensor-demo.md) +- [USB](subsys-usbservice.md) + - [[USB Overview](subsys-usbservice-overview.md) + - [USB Usage Guidelines](subsys-usbservice-guide.md) + - [USB Usage Example](subsys-usbservice-demo.md) - [Application Framework](subsys-application-framework.md) - [Overview](subsys-application-framework-overview.md) - [Setting Up a Development Environment](subsys-application-framework-envbuild.md) diff --git a/en/device-dev/subsystems/figure/en-us_image_0000001192123772.png b/en/device-dev/subsystems/figure/en-us_image_0000001192123772.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1dabae78c438928544864ca2cada41260aa2f5 Binary files /dev/null and b/en/device-dev/subsystems/figure/en-us_image_0000001192123772.png differ diff --git a/en/device-dev/subsystems/subsys-data-storage-guide.md b/en/device-dev/subsystems/subsys-data-storage-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..152935dc1a60c17cfda5ba745e98321ec3a2c912 --- /dev/null +++ b/en/device-dev/subsystems/subsys-data-storage-guide.md @@ -0,0 +1,193 @@ +# Lightweight Data Store Development + +## When to Use + +The lightweight data store is ideal for storing lightweight and frequently used data, but not for storing a large amount of data or data with frequent changes. The application data is persistently stored on a device in the form of files. Note that the instance accessed by an application contains all data of the file. The data is always loaded to the memory of the device until the application removes it from the memory. The application can perform data operations using the Preferences APIs. + +## Available APIs + +The lightweight data store provides applications with data processing capability and allows applications to perform lightweight data storage and query. Data is stored in key-value pairs. Keys are of the string type, and values can be of the string, Boolean, integer, long integer, float, double, or string array type. + +**Creating a Preferences Instance** + +Create a **Preferences** instance for data operations. A **Preferences** instance is created after data is read from a specified file and loaded to the instance. + +**Table 1** API for creating a Preferences instance + +| Class| Method| Description| +| --- | ----- | ----| +| PreferencesHelper | static std::shared_ptr GetPreferences(const std::string &path, int &errCode); | Creates a **Preferences** instance.
**path**: storage path of the application data.
**errCode**: error code.
Return value: **Preferences** instance created.| + +**Writing Data** + +Call the **put()** method to add or modify data in a **Preferences** instance. + +**Table 2** APIs for writing data + +| Class| Method| Description| +| --- | ----- | ----| +| Preferences | int PutInt(const std::string &key, int value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutString(const std::string &key, const std::string &value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutBool(const std::string &key, bool value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutLong(const std::string &key, int64_t value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutFloat(const std::string &key, float value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutDouble(const std::string &key, double value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| +| Preferences | int PutStringSet(const std::string &key, const std::set\ &value); | **key**: key of the data to write. It cannot be empty.
**value**: value of the data to write.
Return value: error code.| + +**Reading Data** + +Call the **get()** method to read data from a **Preferences** instance. + +**Table 3** APIs for reading data + +| Class| Method| Description| +| --- | ----- | ----| +| Preferences | bool GetBool(const std::string &key, bool defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | std::string GetString(const std::string &key, const std::string &defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | bool GetBool(const std::string &key, bool defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | float GetFloat(const std::string &key, float defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | double GetDouble(const std::string &key, double defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | int64_t GetLong(const std::string &key, int64_t defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| +| Preferences | std::set\ GetStringSet(const std::string &key, std::set\ &defValue); | **key**: key of the data to read. It cannot be empty.
**defValue**: default value to return if the operation fails or the value does not exist.
Return value: Returns the value read if the operation is successful; returns **defValue** otherwise.| + +**Storing Data Persistently** + +Call the **flush()** or **flushSync** method to write the cached data back to its text file for persistent storage. + +**Table 4** APIs for data persistence + +| Class| Method| Description| +| --- | ----- | ----| +| Preferences | void Flush(); | Writes data in the **Preferences** instance back to its file through an asynchronous thread.| +| Preferences | int FlushSync(); | Writes data in the **Preferences** instance back to its file through a synchronous thread.| + +**Observing Data Changes** + +Specify **PreferencesObserver** as the callback to subscribe to data changes. When the value of the subscribed key is changed and the **flush()** method is executed, **PreferencesObserver** will be invoked. + +**Table 5** APIs for subscribing to data changes + +| Class| Method| Description| +| --- | ----- | ----| +| Preferences | void RegisterObserver(std::shared_ptr preferencesObserver); | Subscribes to data changes.
**preferencesObserver**: callback invoked to return the data changes.| +| Preferences | void UnRegisterObserver(std::shared_ptr preferencesObserver); | Unsubscribes from data changes.
**preferencesObserver**: callback used to report data changes.| + +**Deleting Data** + +Use the following APIs to delete a **Preferences** instance or data file. + +**Table 6** APIs for deleting data + +| Class| Method| Description| +| --- | ----- | ----| +| PreferencesHelper | int DeletePreferences(const std::string &path); | Deletes a **Preferences** instance from the memory and deletes its file from the device.
**path**: storage path of the application data.
Return value: error code.| +| PreferencesHelper | int RemovePreferencesFromCache(const std::string &path); | Deletes a **Preferences** instance from the memory.
**path**: storage path of the application data.
Return value: error code.| + +## How to Develop + +1. Import the Preferences module and related header files to the development environment. + + ``` C++ + Header file path: //distributeddatamgr_appdatamgr/interfaces/innerkits/native_preferences/include + ``` + +2. Create a **Preferences** instance. + + Read the specified file and load its data to the **Preferences** instance for data operations. + + ``` C++ + int errCode = E_OK; + Preferences pref = PreferencesHelper::GetPreferences(PREF_TEST_PATH + "test.xml", errCode); // PREF_TEST_PATH must be the application sandbox path. + EXPECT_EQ(errCode, E_OK); + ``` + + +3. Write data. + + Use the **put()** method of the **Preferences** class to write data to the cached **Preferences** instance. + + ```C++ + pref->PutString("test", "remove"); + ``` + +4. Read data. + + Use the **get()** method of the **Preferences** class to read data. + + ``` C++ + std::string ret = pref->GetString("test", "defaultValue"); + EXPECT_EQ(ret, "remove"); + ``` + + +5. Store data persistently. + + Use the **flush()** or **flushSync()** method to flush data in the **Preferences** instance to its file. + + ```C++ + int err = pref->FlushSync(); + EXPECT_EQ(ret, E_OK); + ``` + + +6. Subscribe to data changes. + + Specify **PreferencesObserver** as the callback to subscribe to data changes for an application. When the value of the subscribed key is changed and the **flush()** or **flushSync()** method is executed, **PreferencesObserver** will be invoked. Unregister the **PreferencesObserver** when it is no longer required. + + Customize a class to implement the **PreferencesObserver**: + ``` C++ + class PreferencesObserverCounter : public PreferencesObserver { + public: + virtual ~PreferencesObserverCounter(); + void OnChange(Preferences &preferences, const std::string &key) override; + + std::atomic_int notifyTimes; + static const std::vector NOTIFY_KEYS_VECTOR; + }; + + PreferencesObserverCounter::~PreferencesObserverCounter() {} + + void PreferencesObserverCounter::OnChange(Preferences &preferences, const std::string &key) + { + for (auto it = NOTIFY_KEYS_VECTOR.cbegin(); it != NOTIFY_KEYS_VECTOR.cend(); it++) { + if (key.compare(*it)) { + notifyTimes++; + break; + } + } + } + + const std::vector PreferencesObserverCounter::NOTIFY_KEYS_VECTOR = { PreferencesTest::KEY_TEST_INT_ELEMENT, + PreferencesTest::KEY_TEST_LONG_ELEMENT, PreferencesTest::KEY_TEST_FLOAT_ELEMENT, + PreferencesTest::KEY_TEST_BOOL_ELEMENT, PreferencesTest::KEY_TEST_STRING_ELEMENT }; + ``` + + Subscribe to data changes and invoke the callback: + ``` C++ + std::shared_ptr counter = + std::shared_ptr(new PreferencesObserverCounter()); + pref->RegisterObserver(counter); // Register a callback to return data changes. + + pref->PutString(PreferencesTest::KEY_TEST_STRING_ELEMENT, "test"); + pref->Flush(); // Trigger the onChanged callback of the counter. + EXPECT_EQ(static_cast(counter.get())->notifyTimes, 1); + + /* same value */ + pref->PutInt(PreferencesTest::KEY_TEST_INT_ELEMENT, 2); + pref->PutString(PreferencesTest::KEY_TEST_STRING_ELEMENT, "test"); + pref->Flush(); + EXPECT_EQ(static_cast(counter.get())->notifyTimes, 2); + + pref->UnRegisterObserver(counter); // Unregister the callback for data changes. + ``` + + +7. Delete the specified file. + + Delete the **Preferences** singleton of the specified file from the memory, and delete the specified file, its backup file, and damaged files. After the specified files are deleted, the application cannot use that instance to perform any data operation. Otherwise, data inconsistency will occur. The deleted data and files cannot be restored. + + ``` C++ + pref = nullptr; + int ret = PreferencesHelper::DeletePreferences("/data/test/test"); + EXPECT_EQ(ret, E_OK); + ``` diff --git a/en/device-dev/subsystems/subsys-data-storage-overview.md b/en/device-dev/subsystems/subsys-data-storage-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..fee188e448354c1a09825b2880d7a2485c69818f --- /dev/null +++ b/en/device-dev/subsystems/subsys-data-storage-overview.md @@ -0,0 +1,31 @@ +# Lightweight Data Store Overview + +The lightweight data store is applicable to access and persistence operations on the data in key-value pairs. When an application accesses a lightweight store instance, the data in the instance will be cached in the memory for faster access. The cached data can also be written back to the text file for persistent storage. Since file read and write consume system resources, you are advised to minimize the frequency of reading and writing persistent files. + +## Basic Concepts + +- **Key-Value data structure** + + A type of data structure. The key is the unique identifier for a piece of data, and the value is the specific data being identified. + +- **Non-relational databases** + + A database not in compliance with the atomicity, consistency, isolation, and durability (ACID) database management properties of relational data transactions. The data in a non-relational database is independent. + + +## Working Principles + +When an application loads data from a specified Preferences file to a **Preferences** instance, the system stores the instance in the memory through a static container. Each file of an application or process has only one **Preferences** instance in the memory, till the application removes the instance from the memory or deletes the **Preferences** file. + +When obtaining a **Preferences** instance, the application can read data from or write data to the instance. The data in the instance can be flushed to its **Preferences** file by calling the **flush()** or **flushSync()** method. + +**Figure 1** How lightweight data store works + + +![](figure/en-us_image_0000001192123772.png) + +## Constraints + +- **Preferences** instances are loaded to the memory. To minimize non-memory overhead, the number of data records stored in a Preferences instance cannot exceed 10,000. Delete the instances that are no longer used in a timely manner. +- The key in the key-value pairs is of the string type. It cannot be empty or exceed 80 characters. +- If the value in the key-value pairs is of the string type, it can be empty or contain a maximum of 8192 characters. diff --git a/en/device-dev/subsystems/subsys-data-storage.md b/en/device-dev/subsystems/subsys-data-storage.md new file mode 100644 index 0000000000000000000000000000000000000000..2c6e163303a36670ad51995de94bc22bde31deed --- /dev/null +++ b/en/device-dev/subsystems/subsys-data-storage.md @@ -0,0 +1,5 @@ +# Lightweight Data Store + +- **[Lightweight Data Store Overview](subsys-data-storage-overview.md)** + +- **[Lightweight Data Store Development] (subsys-data-storage-guide.md)** diff --git a/en/device-dev/subsystems/subsys.md b/en/device-dev/subsystems/subsys.md index 74cc4fa005d4ed12c8011f05d7beff8a2476c714..06318d2b2abd90d69be1f43052432d103f5c3330 100644 --- a/en/device-dev/subsystems/subsys.md +++ b/en/device-dev/subsystems/subsys.md @@ -8,6 +8,8 @@ - **[Multimedia](subsys-multimedia.md)** +- **[Data Management](subsys-data.md)** + - **[Utils](subsys-utils.md)** - **[AI Framework](subsys-aiframework.md)**