Pixie
Loading...
Searching...
No Matches
dfuds.h
1#pragma once
2
3#include <pixie/rmm/tree.h>
4#include <pixie/tree.h>
5
6#include <cstddef>
7#include <cstdint>
8#include <vector>
9
10namespace pixie {
11
16template <typename RMMTree>
17class DFUDSTree : public TreeBase<DFUDSTree<RMMTree>> {
18 private:
19 const size_t num_bits_;
20 RMMTree rmm_;
21
22 public:
23 using Node = TreeNode;
24
30 explicit DFUDSTree(const std::vector<std::uint64_t>& dfuds_sequence,
31 size_t tree_size)
32 : num_bits_(2 * tree_size - 1), rmm_(dfuds_sequence, 2 * tree_size - 1) {}
33
37 Node root_impl() const { return Node(0, 0); }
38
42 size_t size_impl() const { return (num_bits_ + 1) / 2; }
43
47 bool is_leaf_impl(const Node& node) const {
48 return (node.pos + 1 == num_bits_) or rmm_.bit(node.pos) == 0;
49 }
50
54 bool is_root_impl(const Node& node) const { return node.number == 0; }
55
59 size_t degree_impl(const Node& node) const {
60 return rmm_.select0(node.number + 1) - node.pos;
61 }
62
66 Node first_child_impl(const Node& node) const {
67 size_t pos = rmm_.select0(node.number + 1);
68 size_t num = node.number + 1;
69 return Node(num, pos + 1);
70 }
71
76 Node child_impl(const Node& node, size_t i) const {
77 Node child = first_child_impl(node);
78 while (i--) {
80 }
81 return child;
82 }
83
87 Node next_sibling_impl(const Node& node) const {
88 size_t end = rmm_.fwdsearch(node.pos, -1);
89 size_t pos = end + 1;
90 size_t num = rmm_.rank0(pos);
91 return Node(num, pos);
92 }
93
98 Node parent_impl(const Node& node) const {
99 if (node.number == 0) {
100 return root_impl();
101 }
102 size_t open = rmm_.open(
103 node.pos -
104 1); // node.pos in 0-based and rmm_.open uses 1-based argument.
105 // Thus, we use node.pos meaning the parenthesis before
106 // first parenthesis of the current node
107 size_t rank = rmm_.rank0(open);
108 size_t pos =
109 rmm_.select0(rank) +
110 1; // In here we use that rmm_select(0) equals size_t max value so
111 // rmm_.select(rank) can still be interpreted as pos-1
112 return Node(rank, pos);
113 }
114
118 bool is_last_child_impl(const Node& node) const {
119 size_t end = rmm_.fwdsearch(node.pos, -1);
120 size_t pos = end + 1;
121 size_t op = rmm_.open(node.pos - 1);
122 size_t op2 = rmm_.open(pos - 1);
123 return pos == num_bits_ || op != op2 + 1;
124 }
125};
126
127std::vector<uint64_t> adj_to_dfuds(
128 size_t tree_size,
129 const std::vector<std::vector<size_t>>& adj) {
130 size_t dfuds_size = tree_size * 2 - 1;
131 std::vector<uint64_t> dfuds((dfuds_size + 63) / 64, 0);
132 std::vector<size_t> stack;
133 stack.push_back(0);
134 size_t pos = 0;
135 while (!stack.empty()) {
136 auto v = stack.back();
137 stack.pop_back();
138 size_t edge_count = adj[v].size();
139 for (size_t i = 0; i < edge_count - 1; ++i) { // edge 0 goes to parent
140 dfuds[pos >> 6] = dfuds[pos >> 6] | (1ULL << (pos & 63));
141 pos++;
142 stack.push_back(adj[v][edge_count - 1 - i]);
143 }
144 pos++;
145 }
146 return dfuds;
147}
148
149} // namespace pixie
bool is_root_impl(const Node &node) const
Indicates if node is a root.
Definition dfuds.h:54
bool is_leaf_impl(const Node &node) const
Indicates if node is a leaf.
Definition dfuds.h:47
Node parent_impl(const Node &node) const
Returns the parent of a node if node is not root, else returns root.
Definition dfuds.h:98
DFUDSTree(const std::vector< std::uint64_t > &dfuds_sequence, size_t tree_size)
Constructor from an external array of uint64_t.
Definition dfuds.h:30
Node next_sibling_impl(const Node &node) const
Returns next sibling of a node.
Definition dfuds.h:87
Node root_impl() const
Returns the root node.
Definition dfuds.h:37
size_t degree_impl(const Node &node) const
Returns the number of children of a node.
Definition dfuds.h:59
Node first_child_impl(const Node &node) const
Returns first child of a node.
Definition dfuds.h:66
size_t size_impl() const
Returns the size of the tree.
Definition dfuds.h:42
Node child_impl(const Node &node, size_t i) const
Returns the i-th child of node Indexing starts at 0.
Definition dfuds.h:76
bool is_last_child_impl(const Node &node) const
Indicates if node is last child.
Definition dfuds.h:118
CRTP facade for rooted ordered trees.
Definition tree.h:43
Node child(const Node &node, std::size_t index) const
Definition tree.h:103
Logical node handle shared by succinct rooted-tree encodings.
Definition tree.h:18
std::size_t number
Logical node number in the encoding's traversal order.
Definition tree.h:20
std::size_t pos
Bit position representing the node in the succinct encoding.
Definition tree.h:23
Common interface and node handle for rooted ordered trees.