From b624696266854e9ddf39339ba54d2fae8ca9cf17 Mon Sep 17 00:00:00 2001 From: Alex Shabalin Date: Tue, 6 Aug 2024 17:29:10 +0200 Subject: [PATCH] Policies documented --- immer/extra/persist/README.rst | 18 +++++- immer/extra/persist/json/policy.hpp | 94 +++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/immer/extra/persist/README.rst b/immer/extra/persist/README.rst index b9266440..1d17192f 100644 --- a/immer/extra/persist/README.rst +++ b/immer/extra/persist/README.rst @@ -79,8 +79,22 @@ Which generates some JSON like this: As you can see, the value is serialized with every ``immer`` container replaced by an identifier. This identifier is a key into a pool, which is serialized just after. -- XXX: what's a pool? -- XXX: to_json_with_pool uses cereal +A pool is a data structure that ``immer-persist`` uses to work with the underlying structure of the ``immer`` containers. +For example, ``vector`` and ``flex_vector`` use Radix Balanced Trees internally that have inner nodes and leaf nodes. These +nodes can be seen in the JSON above. In other words, containers can be put into a pool and later can be retrieved from it, all while preserving +the structural sharing. One pool can only work with one container type. + +Currently, ``immer-persist`` focuses on JSON as the serialization format and uses the ``cereal`` library internally. In principle, other formats +and serialization libraries could be supported in the future. + + +Policy +------ + +.. doxygengroup:: Persist-policy + :project: immer + :content-only: + API Overview ------------ diff --git a/immer/extra/persist/json/policy.hpp b/immer/extra/persist/json/policy.hpp index b880d201..e90a66fe 100644 --- a/immer/extra/persist/json/policy.hpp +++ b/immer/extra/persist/json/policy.hpp @@ -5,18 +5,22 @@ namespace immer::persist { +/** + * @defgroup persist-policy + */ + /** * @brief Policy is a type that describes certain aspects of serialization for - * immer-persist. - * - How to call into the cereal archive to save and load the + * `immer-persist`. + * - How to call into the `cereal` archive to save and load the * user-provided value. Can be used to serealize the value inline (without the - * "value0" node) by taking a dependency on + * `value0` node) by taking a dependency on * https://github.com/LowCostCustoms/cereal-inline, for example. - * - Types of immer containers that will be serialized using pools. One - * pool contains nodes of only one immer container type. + * - Types of `immer` containers that will be serialized using pools. One + * pool contains nodes of only one `immer` container type. * - Names for each per-type pool. * - * @ingroup persist-api + * @ingroup persist-policy */ template concept Policy = @@ -34,6 +38,18 @@ auto get_pools_types(const T&) return boost::hana::make_set(); } +/** + * @brief This struct provides functions that `immer-persist` uses to serialize + * the user-provided value using `cereal`. In this case, we use `cereal`'s + * default name, `value0`. It's used in all policies provided by + * `immer-persist`. + * + * Other possible way would be to use a third-party library to serialize the + * value inline (without the `value0` node) by taking a dependency on + * https://github.com/LowCostCustoms/cereal-inline, for example. + * + * @ingroup persist-policy + */ struct value0_serialize_t { template @@ -66,11 +82,33 @@ struct via_get_pools_names_policy_t : value0_serialize_t } }; +/** + * @brief Create an `immer-persist` policy that uses the user-provided + * `get_pools_names` function (located in the same namespace as the value user + * serializes) to determine: + * - the types of `immer` containers that should be serialized in a pool + * - the names of those pools in JSON (and possibly other formats). + * + * The `get_pools_names` function is expected to return a `boost::hana::map` + * where key is a container type and value is the name for this container's pool + * as a `BOOST_HANA_STRING`. + * + * @param value Value that is going to be serialized, only type of the value + * matters. + * + * @ingroup persist-policy + */ auto via_get_pools_names_policy(const auto& value) { return via_get_pools_names_policy_t>{}; } +/** + * @brief This struct is used in some policies to provide names to each pool + * by using a demangled name of the `immer` container corresponding to the pool. + * + * @ingroup persist-policy + */ struct demangled_names_t { template @@ -80,6 +118,18 @@ struct demangled_names_t } }; +/** + * @brief An `immer-persist` policy that uses the user-provided + * `get_pools_types` function to determine the types of `immer` containers that + * should be serialized in a pool. + * + * The `get_pools_types` function is expected to return a `boost::hana::set` of + * types of the desired containers. + * + * The names for the pools are determined via `demangled_names_t`. + * + * @ingroup persist-policy + */ struct via_get_pools_types_policy : demangled_names_t , value0_serialize_t @@ -91,6 +141,14 @@ struct via_get_pools_types_policy } }; +/** + * @brief An `immer-persist` policy that recursively finds all `immer` + * containers in a serialized value. The value must be a `boost::hana::Struct`. + * + * The names for the pools are determined via `demangled_names_t`. + * + * @ingroup persist-policy + */ struct hana_struct_auto_policy : demangled_names_t { template @@ -117,12 +175,36 @@ struct hana_struct_auto_member_name_policy_t : value0_serialize_t } }; +/** + * @brief Create an `immer-persist` policy that recursively finds all `immer` + * containers in a serialized value and uses member names to name the pools. + * The value must be a `boost::hana::Struct`. + * + * @param value Value that is going to be serialized, only type of the value + * matters. + * + * @ingroup persist-policy + */ auto hana_struct_auto_member_name_policy(const auto& value) { return hana_struct_auto_member_name_policy_t< std::decay_t>{}; } +/** + * @brief An `immer-persist` policy that uses the provided `boost::hana::map` + * to determine: + * - the types of `immer` containers that should be serialized in a pool + * - the names of those pools in JSON (and possibly other formats). + * + * The given map's key is a container type and value is the name for this + * container's pool as a `BOOST_HANA_STRING`. + * + * It is similar to `via_get_pools_names_policy` but the map is provided + * explicitly. + * + * @ingroup persist-policy + */ template struct via_map_policy : value0_serialize_t {