Skip to content

Commit

Permalink
Remove loaders from the pools for the normal scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed May 30, 2024
1 parent aa97845 commit d3311d9
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 74 deletions.
6 changes: 2 additions & 4 deletions immer/extra/persist/alias.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ struct type_alias
{
}

friend bool operator==(const type_alias& left, const type_alias& right)
{
return left.value == right.value;
}
friend bool operator==(const type_alias& left,
const type_alias& right) = default;

/**
* This works only starting with fmt v10.
Expand Down
6 changes: 2 additions & 4 deletions immer/extra/persist/box/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,8 @@ struct input_pool
{
immer::vector<immer::box<T, MemoryPolicy>> boxes;

friend bool operator==(const input_pool& left, const input_pool& right)
{
return left.boxes == right.boxes;
}
friend bool operator==(const input_pool& left,
const input_pool& right) = default;

template <class Archive>
void load(Archive& ar)
Expand Down
5 changes: 1 addition & 4 deletions immer/extra/persist/champ/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,7 @@ struct container_input_pool
nodes_load<T, champ_t::bits> nodes;

friend bool operator==(const container_input_pool& left,
const container_input_pool& right)
{
return left.nodes == right.nodes;
}
const container_input_pool& right) = default;

template <class Archive>
void load(Archive& ar)
Expand Down
6 changes: 2 additions & 4 deletions immer/extra/persist/common/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ struct values_load
{
}

friend bool operator==(const values_load& left, const values_load& right)
{
return left.data == right.data;
}
friend bool operator==(const values_load& left,
const values_load& right) = default;
};

template <class Archive, class T>
Expand Down
17 changes: 15 additions & 2 deletions immer/extra/persist/json/json_immer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,16 @@ class json_immer_input_archive
{
}

Pools& get_input_pools() { return pools; }
const Pools& get_input_pools() const { return pools; }
template <class Container>
auto& get_loader()
{
auto& loader = loaders[boost::hana::type_c<Container>];
if (!loader) {
const auto& type_pool = pools.template get_pool<Container>();
loader.emplace(type_pool.pool, type_pool.transform);
}
return *loader;
}

template <class T>
friend void prologue(json_immer_input_archive& ar, T&& v)
Expand Down Expand Up @@ -322,10 +330,15 @@ class json_immer_input_archive
CEREAL_LOAD_FUNCTION_NAME(ar.previous, st);
}

bool ignore_pool_exceptions = false;

private:
WrapF wrap;
Previous previous;
Pools pools;

using Loaders = decltype(Pools::generate_loaders());
Loaders loaders;
};

} // namespace immer::persist
Expand Down
103 changes: 67 additions & 36 deletions immer/extra/persist/json/json_with_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,53 @@ struct output_pools
}
};

template <class Derived, class Loader>
struct no_loader
{};

template <class Derived, class Loader>
struct with_loader
{
std::optional<Loader> loader;

auto& get_loader_from_per_type_pool()
{
if (!loader) {
auto& self = static_cast<Derived&>(*this);
loader.emplace(self.pool, self.transform);
}
return *loader;
}
};

/**
* A pool for one container type.
* Normally, the pool does not contain a loader, which is located inside the
* json_immer_input_archive.
*
* But in case of transformations, there is no json_immer_input_archive involved
* and it becomes convenient to have the corresponding loader stored here, too,
* via with_loader.
*/
template <class Container,
class Pool = typename container_traits<Container>::input_pool_t,
class TransformF = boost::hana::id_t,
class OldContainerType = boost::hana::id_t>
class OldContainerType = boost::hana::id_t,
template <class, class> class LoaderMixin = no_loader>
struct input_pool
: LoaderMixin<input_pool<Container,
Pool,
TransformF,
OldContainerType,
LoaderMixin>,
typename container_traits<
Container>::template loader_t<Pool, TransformF>>
{
using container_t = Container;
using old_container_t = OldContainerType;

Pool pool = {};
TransformF transform;
std::optional<typename container_traits<
Container>::template loader_t<Pool, TransformF>>
loader;

input_pool() = default;

Expand All @@ -142,27 +175,6 @@ struct input_pool
{
}

input_pool(const input_pool& other)
: pool{other.pool}
, transform{other.transform}
{
}

input_pool& operator=(const input_pool& other)
{
pool = other.pool;
transform = other.transform;
return *this;
}

auto& get_loader()
{
if (!loader) {
loader.emplace(pool, transform);
}
return *loader;
}

template <class Func>
auto with_transform(Func&& func) const
{
Expand All @@ -174,8 +186,8 @@ struct input_pool
func))>;
using TransF = std::function<new_value_type(const value_type&)>;
// the transform function must be filled in later
return input_pool<NewContainer, Pool, TransF, Container>{pool,
TransF{}};
return input_pool<NewContainer, Pool, TransF, Container, with_loader>{
pool, TransF{}};
}

friend bool operator==(const input_pool& left, const input_pool& right)
Expand All @@ -187,6 +199,12 @@ struct input_pool
{
pool.merge_previous(original.pool);
}

static auto generate_loader()
{
return std::optional<typename container_traits<
Container>::template loader_t<Pool, TransformF>>{};
}
};

/**
Expand Down Expand Up @@ -230,20 +248,18 @@ class input_pools
{
}

bool ignore_pool_exceptions = false;

auto& storage() { return storage_(); }
const auto& storage() const { return storage_(); }

template <class Container>
auto& get_loader()
const auto& get_pool()
{
using Contains =
decltype(hana::contains(storage(), hana::type_c<Container>));
if constexpr (!Contains::value) {
auto err = error_missing_pool_for_type<Container>{};
}
return storage()[hana::type_c<Container>].get_loader();
return storage()[hana::type_c<Container>];
}

template <class OldContainer>
Expand All @@ -261,7 +277,7 @@ class input_pools
if constexpr (!IsJust::value) {
auto err = error_missing_pool_for_type<OldContainer>{};
}
return storage()[Key{}.value()].get_loader();
return storage()[Key{}.value()].get_loader_from_per_type_pool();
}

template <class Archive>
Expand Down Expand Up @@ -353,7 +369,8 @@ class input_pools
auto err = error_missing_pool_for_type<
typename decltype(new_type)::type>{};
}
auto& loader = get_data()[new_type].get_loader();
auto& loader =
get_data()[new_type].get_loader_from_per_type_pool();
return loader.load(id);
};
};
Expand Down Expand Up @@ -395,6 +412,20 @@ class input_pools
s[key].merge_previous(original_s[key]);
});
}

static auto generate_loaders()
{
using Storage = std::decay_t<decltype(std::declval<StorageF>()())>;
using Types = decltype(hana::keys(std::declval<Storage>()));
auto storage =
hana::fold_left(Types{}, hana::make_map(), [](auto map, auto type) {
using TypePool =
std::decay_t<decltype(std::declval<Storage>()[type])>;
return hana::insert(
map, hana::make_pair(type, TypePool::generate_loader()));
});
return storage;
}
};

inline auto generate_output_pools(auto type_names)
Expand Down Expand Up @@ -468,11 +499,11 @@ auto load_pools(std::istream& is, const auto& wrap)
{
const auto reload_pool =
[wrap](std::istream& is, Pools pools, bool ignore_pool_exceptions) {
auto restore = immer::util::istream_snapshot{is};
const auto original_pools = pools;
pools.ignore_pool_exceptions = ignore_pool_exceptions;
auto restore = immer::util::istream_snapshot{is};
const auto original_pools = pools;
auto ar = json_immer_input_archive<Archive, Pools, decltype(wrap)>{
std::move(pools), wrap, is};
ar.ignore_pool_exceptions = ignore_pool_exceptions;
/**
* NOTE: Critical to clear the pools before loading into it
* again. I hit a bug when pools contained a vector and every
Expand Down
23 changes: 3 additions & 20 deletions immer/extra/persist/json/persistable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,8 @@ struct persistable
{
}

persistable(const persistable& other)
: container{other.container}
{
}

persistable& operator=(const persistable&) = default;

persistable(persistable&& other)
: container{std::move(other.container)}
{
}

persistable& operator=(persistable&&) = default;

friend bool operator==(const persistable& left, const persistable& right)
{
return left.container == right.container;
}
friend bool operator==(const persistable& left,
const persistable& right) = default;

// template <std::enable_if_t<detail::is_iterable<Container>, bool> = true>
// friend auto begin(const persistable& value)
Expand Down Expand Up @@ -131,7 +115,6 @@ void load_minimal(
{
auto& loader =
const_cast<json_immer_input_archive<Previous, Pools, WrapF>&>(ar)
.get_input_pools()
.template get_loader<Container>();

// Have to be specific because for vectors container_id is different from
Expand All @@ -142,7 +125,7 @@ void load_minimal(
try {
value.container = loader.load(container_id_{id});
} catch (const pool_exception& ex) {
if (!ar.get_input_pools().ignore_pool_exceptions) {
if (!ar.ignore_pool_exceptions) {
throw ::cereal::Exception{fmt::format(
"Failed to load a container ID {} from the pool of {}: {}",
id,
Expand Down

0 comments on commit d3311d9

Please sign in to comment.