76 template <
class Derived2,
class Tree2>
89 static constexpr MapType
const Type = MapType::LABEL_SET;
98 using coord_t =
typename Tree::coord_t;
99 using depth_t =
typename Tree::depth_t;
100 using offset_t =
typename Tree::offset_t;
101 using length_t =
typename Tree::length_t;
102 using pos_t =
typename Tree::pos_t;
105 using labels_t =
typename LabelsBlock<BF>::labels_t;
114 template <
class NodeType,
115 std::enable_if_t<Tree::template is_node_type_v<NodeType>,
bool> =
true>
116 [[nodiscard]] labels_t labels(NodeType node)
const
118 Index n = derived().index(node);
119 return labelsBlock(n.pos)[n.offset].labels;
139 template <
class NodeType,
140 std::enable_if_t<Tree::template is_node_type_v<NodeType>,
bool> =
true>
141 void labelsSet(NodeType node, labels_t value,
bool propagate =
true)
145 auto node_f = [
this, elem](Index node) { labelsBlock(node.pos)[node.offset] = elem; };
147 auto block_f = [
this, elem](pos_t pos) { labelsBlock(pos).fill(elem); };
149 auto update_f = [
this](Index node, pos_t children) {
150 onPropagateChildren(node, children);
153 derived().recursParentFirst(node, node_f, block_f, update_f, propagate);
156 template <
class NodeType,
157 std::enable_if_t<Tree::template is_node_type_v<NodeType>,
bool> =
true>
158 void labelsUpdate(NodeType node, label_t value,
bool propagate =
true)
162 [
this, value](Index node) {
163 labelsBlock(node.pos)[node.offset].labels.insert(value);
164 return labelsBlock(node.pos)[node.offset].labels;
170 class NodeType,
class UnaryOp,
171 std::enable_if_t<Tree::template is_node_type_v<NodeType>,
bool> =
true,
172 std::enable_if_t<std::is_invocable_r_v<labels_t, UnaryOp, Index>,
bool> =
true>
173 void labelsUpdate(NodeType node, UnaryOp unary_op,
bool propagate =
true)
175 auto node_f = [
this, unary_op](Index node) {
176 labels_t value = unary_op(node);
178 auto& lb = labelsBlock(node.pos)[node.offset];
182 auto block_f = [
this, node_f](pos_t pos) {
183 for (std::size_t i{}; BF > i; ++i) {
184 node_f(Index(pos, i));
188 auto update_f = [
this](Index node, pos_t children) {
189 onPropagateChildren(node, children);
192 derived().recursLeaves(node, node_f, block_f, update_f, propagate);
199 [[nodiscard]]
constexpr LabelsPropagationCriteria labelsPropagationCriteria()
202 return prop_criteria_;
205 void labelsSetPropagationCriteria(LabelsPropagationCriteria prop_criteria,
206 bool propagate =
true)
208 if (LabelsPropagationCriteria() == prop_criteria) {
212 prop_criteria_ = prop_criteria;
231 LabelsMap() { onInitRoot(); }
233 LabelsMap(LabelsMap
const& other) =
default;
235 LabelsMap(LabelsMap&& other) =
default;
237 template <
class Derived2,
class Tree2>
238 LabelsMap(LabelsMap<Derived2, Tree2>
const& other)
239 : prop_criteria_(other.prop_criteria_)
243 template <
class Derived2,
class Tree2>
244 LabelsMap(LabelsMap<Derived2, Tree2>&& other)
245 : prop_criteria_(
std::move(other.prop_criteria_))
255 ~LabelsMap() =
default;
263 LabelsMap& operator=(LabelsMap
const& rhs) =
default;
265 LabelsMap& operator=(LabelsMap&& rhs) =
default;
267 template <
class Derived2,
class Tree2>
268 LabelsMap& operator=(LabelsMap<Derived2, Tree2>
const& rhs)
270 prop_criteria_ = rhs.prop_criteria_;
274 template <
class Derived2,
class Tree2>
275 LabelsMap& operator=(LabelsMap<Derived2, Tree2>&& rhs)
277 prop_criteria_ = std::move(rhs.prop_criteria_);
285 void swap(LabelsMap& other)
noexcept
287 std::swap(prop_criteria_, other.prop_criteria_);
296 [[nodiscard]]
constexpr Derived& derived() {
return *
static_cast<Derived*
>(
this); }
298 [[nodiscard]]
constexpr Derived
const& derived()
const
300 return *
static_cast<Derived const*
>(
this);
309 [[nodiscard]] LabelsBlock<BF>& labelsBlock(pos_t pos)
311 return derived().template data<LabelsBlock<BF>>(pos);
314 [[nodiscard]] LabelsBlock<BF>
const& labelsBlock(pos_t pos)
const
316 return derived().template data<LabelsBlock<BF>>(pos);
327 auto& block = labelsBlock(0);
330 block[0].labels = value;
333 void onInitChildren(Index node, pos_t children)
335 labelsBlock(children).fill(labelsBlock(node.pos)[node.offset]);
338 void onPruneChildren(Index node, pos_t children)
344 void onPropagateChildren(Index node, pos_t children)
346 auto const& children_block = labelsBlock(children);
347 auto& lb = labelsBlock(node.pos)[node.offset];
349 switch (prop_criteria_) {
350 case LabelsPropagationCriteria::ALL: {
351 for (std::size_t i{}; BF > i; ++i) {
352 lb.labels.insert(children_block[i].labels.begin(),
353 children_block[i].labels.end());
357 case LabelsPropagationCriteria::SUMMARY: {
359 for (std::size_t i{}; BF > i; ++i) {
361 std::accumulate(children_block[i].labels.begin(),
362 children_block[i].labels.end(), 0, std::bit_or<label_t>());
367 case LabelsPropagationCriteria::MAX: {
368 label_t value = std::numeric_limits<label_t>::lowest();
369 for (std::size_t i{}; BF > i; ++i) {
370 value = UFO_MAX(value, children_block[i].labels.empty()
371 ? std::numeric_limits<label_t>::lowest()
372 : *children_block[i].labels.rbegin());
377 case LabelsPropagationCriteria::MIN: {
378 label_t value = std::numeric_limits<label_t>::max();
379 for (std::size_t i{}; BF > i; ++i) {
380 value = UFO_MIN(value, children_block[i].labels.empty()
381 ? std::numeric_limits<label_t>::max()
382 : *children_block[i].labels.rbegin());
387 case LabelsPropagationCriteria::NONE:
return;
395 [[nodiscard]]
bool onIsPrunable(pos_t block)
const
400 begin(labelsBlock(block).data) + 1, end(labelsBlock(block).data),
401 [v = labelsBlock(block)[0].labels](
auto const& e) {
return v == e.labels; });
408 [[nodiscard]]
static constexpr std::size_t serializedSizeNode() noexcept
410 return sizeof(labels_t);
413 [[nodiscard]]
constexpr std::size_t serializedSize(
414 std::vector<std::pair<pos_t, BitSet<BF>>>
const& ,
415 std::size_t num_nodes)
const
417 return num_nodes * serializedSizeNode();
420 void onRead(ReadBuffer& in, std::vector<std::pair<pos_t, BitSet<BF>>>
const& nodes)
422 for (
auto [block, offset] : nodes) {
423 auto& cb = labelsBlock(block);
426 std::array<labels_t, BF> labels;
428 for (offset_t i{}; BF > i; ++i) {
429 cb[i] = LabelsElement(labels[i]);
432 for (offset_t i{}; BF > i; ++i) {
436 cb[i] = LabelsElement(value);
443 void onWrite(WriteBuffer& out, std::vector<std::pair<pos_t, BitSet<BF>>>
const& nodes)
445 for (
auto [block, offset] : nodes) {
446 auto const& lb = labelsBlock(block);
449 std::array<labels_t, BF> labels;
450 for (offset_t i{}; BF > i; ++i) {
451 labels[i] = lb[i].labels;
455 for (offset_t i{}; BF > i; ++i) {
457 out.write(lb[i].labels);
468 void onDotFileInfo(std::ostream& out, Index node)
const
472 if (labelsBlock(node.pos)[node.offset].labels.empty())
return;
474 auto it = labelsBlock(node.pos)[node.offset].labels.begin();
477 while (it != labelsBlock(node.pos)[node.offset].labels.end()) {
484 LabelsPropagationCriteria prop_criteria_ = LabelsPropagationCriteria::ALL;