diff --git a/partition_version.cc b/partition_version.cc index 331b914a10..0a37dc61c4 100644 --- a/partition_version.cc +++ b/partition_version.cc @@ -62,6 +62,60 @@ partition_version::~partition_version() } } +namespace { + +GCC6_CONCEPT( + +// A functor which transforms objects from Domain into objects from CoDomain +template +concept bool Mapper() { + return requires(U obj, const Domain& src) { + { obj(src) } -> const CoDomain& + }; +} + +// A functor which merges two objects from Domain into one. The result is stored in the first argument. +template +concept bool Reducer() { + return requires(U obj, Domain& dst, const Domain& src) { + { obj(dst, src) } -> void; + }; +} + +) + +// Calculates the value of particular part of mutation_partition represented by +// the version chain starting from v. +// |map| extracts the part from each version. +// |reduce| Combines parts from the two versions. +template +GCC6_CONCEPT( +requires Mapper() && Reducer() +) +inline Result squashed(const partition_version_ref& v, Map&& map, Reduce&& reduce) { + Result r = map(v->partition()); + auto it = v->next(); + while (it) { + reduce(r, map(it->partition())); + it = it->next(); + } + return r; +} + +} + +row partition_snapshot::static_row() const { + return ::squashed(version(), + [] (const mutation_partition& mp) -> const row& { return mp.static_row(); }, + [this] (row& a, const row& b) { a.apply(*_schema, column_kind::static_column, b); }); +} + +tombstone partition_snapshot::partition_tombstone() const { + return ::squashed(version(), + [] (const mutation_partition& mp) { return mp.partition_tombstone(); }, + [] (tombstone& a, tombstone b) { a.apply(b); }); +} + partition_snapshot::~partition_snapshot() { if (_version && _version.is_unique_owner()) { auto v = &*_version; diff --git a/partition_version.hh b/partition_version.hh index b3a8d61f69..9e68c00057 100644 --- a/partition_version.hh +++ b/partition_version.hh @@ -221,6 +221,8 @@ public: } unsigned version_count(); + tombstone partition_tombstone() const; + row static_row() const; }; class partition_entry {