Pixie
Loading...
Searching...
No Matches
dfuds_tree.h
1#pragma once
2
3#include <pixie/rmm_tree.h>
4
5#include <cstdint>
6
7#include "utils.h"
8
9namespace pixie {
10
15class DFUDSTree {
16 private:
17 const size_t num_bits_;
18 RmMTree rmm_;
19
20 public:
21 struct Node {
22 size_t number;
23
24 size_t pos;
25
29 Node(size_t node_number, size_t dfuds_pos)
30 : number(node_number), pos(dfuds_pos) {}
31 };
32
38 explicit DFUDSTree(const std::vector<std::uint64_t>& dfuds_sequence,
39 size_t tree_size)
40 : num_bits_(2 * tree_size - 1), rmm_(dfuds_sequence, 2 * tree_size - 1) {}
41
45 static Node root() { return Node(0, 0); }
46
50 size_t size() const { return (num_bits_ + 1) / 2; }
51
55 bool is_leaf(const Node& node) const {
56 return (node.pos + 1 == num_bits_) or rmm_.bit(node.pos) == 0;
57 }
58
62 bool is_root(const Node& node) const { return node.number == 0; }
63
67 size_t degree(const Node& node) const {
68 return rmm_.select0(node.number + 1) - node.pos;
69 }
70
74 Node first_child(const Node& node) {
75 size_t pos = rmm_.select0(node.number + 1);
76 size_t num = node.number + 1;
77 return Node(num, pos + 1);
78 }
79
84 Node child(const Node& node, size_t i) const {
85 size_t pos = rmm_.close(rmm_.select0(node.number + 1) - i) + 1;
86 size_t num = rmm_.rank0(pos);
87 return Node(num, pos);
88 }
89
93 Node next_sibling(const Node& node) const {
94 size_t end = rmm_.fwdsearch(node.pos, -1);
95 size_t pos = end + 1;
96 size_t num = rmm_.rank0(pos);
97 return Node(num, pos);
98 }
99
104 Node parent(const Node& node) const {
105 if (node.number == 0) {
106 return root();
107 }
108 size_t open = rmm_.open(
109 node.pos -
110 1); // node.pos in 0-based and rmm_.open uses 1-based argument.
111 // Thus, we use node.pos meaning the parenthesis before
112 // first parenthesis of the current node
113 size_t rank = rmm_.rank0(open);
114 size_t pos =
115 rmm_.select0(rank) +
116 1; // In here we use that rmm_select(0) equals size_t max value so
117 // rmm_.select(rank) can still be interpreted as pos-1
118 return Node(rank, pos);
119 }
120
124 bool is_last_child(const Node& node) const {
125 size_t end = rmm_.fwdsearch(node.pos, -1);
126 size_t pos = end + 1;
127 size_t op = rmm_.open(node.pos - 1);
128 size_t op2 = rmm_.open(pos - 1);
129 return pos == num_bits_ || op != op2 + 1;
130 }
131};
132
133std::vector<uint64_t> adj_to_dfuds(
134 size_t tree_size,
135 const std::vector<std::vector<size_t>>& adj) {
136 size_t dfuds_size = tree_size * 2 - 1;
137 std::vector<uint64_t> dfuds((dfuds_size + 63) / 64, 0);
138 std::vector<size_t> stack;
139 stack.push_back(0);
140 size_t pos = 0;
141 while (!stack.empty()) {
142 auto v = stack.back();
143 stack.pop_back();
144 size_t edge_count = adj[v].size();
145 for (size_t i = 0; i < edge_count - 1; ++i) { // edge 0 goes to parent
146 dfuds[pos >> 6] = dfuds[pos >> 6] | (1ULL << (pos & 63));
147 pos++;
148 stack.push_back(adj[v][edge_count - 1 - i]);
149 }
150 pos++;
151 }
152 return dfuds;
153}
154
155bool operator==(const AdjListNode& a, const DFUDSTree::Node& b) {
156 return a.number == b.number;
157}
158
159bool operator==(const DFUDSTree::Node& b, const AdjListNode& a) {
160 return a.number == b.number;
161}
162
163} // namespace pixie
Node child(const Node &node, size_t i) const
Returns the i-th child of node Indexing starts at 0.
Definition dfuds_tree.h:84
Node first_child(const Node &node)
Returns first child of a node.
Definition dfuds_tree.h:74
bool is_leaf(const Node &node) const
Indicates if node is a leaf.
Definition dfuds_tree.h:55
static Node root()
Returns the root node.
Definition dfuds_tree.h:45
bool is_root(const Node &node) const
Indicates if node is a root.
Definition dfuds_tree.h:62
size_t degree(const Node &node) const
Returns the number of children of a node.
Definition dfuds_tree.h:67
Node next_sibling(const Node &node) const
Returns next sibling of a node.
Definition dfuds_tree.h:93
Node parent(const Node &node) const
Returns the parent of a node if node is not root, else returns root.
Definition dfuds_tree.h:104
DFUDSTree(const std::vector< std::uint64_t > &dfuds_sequence, size_t tree_size)
Constructor from an external array of uint64_t.
Definition dfuds_tree.h:38
bool is_last_child(const Node &node) const
Indicates if node is last child.
Definition dfuds_tree.h:124
size_t size() const
Returns the size of the tree.
Definition dfuds_tree.h:50
Range min–max tree over a bitvector (LSB-first) tailored for balanced-parentheses (BP).
Definition rmm_tree.h:38
Definition dfuds_tree.h:21
Node(size_t node_number, size_t dfuds_pos)
A node class of DFUDS tree.
Definition dfuds_tree.h:29