Skip to content

Commit

Permalink
Policies documented
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Aug 6, 2024
1 parent 60a47ea commit b624696
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 8 deletions.
18 changes: 16 additions & 2 deletions immer/extra/persist/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------
Expand Down
94 changes: 88 additions & 6 deletions immer/extra/persist/json/policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class T, class Value>
concept Policy =
Expand All @@ -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 <class Archive, class T>
Expand Down Expand Up @@ -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<std::decay_t<decltype(value)>>{};
}

/**
* @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 <class T>
Expand All @@ -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
Expand All @@ -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 <class T>
Expand All @@ -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<decltype(value)>>{};
}

/**
* @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 <class Map>
struct via_map_policy : value0_serialize_t
{
Expand Down

0 comments on commit b624696

Please sign in to comment.