23#include <nlohmann/json.hpp>
27namespace shamrock::scheduler {
28 u64 PatchTree::insert_node(Node n) {
34 void PatchTree::remove_node(
u64 id) {
tree.erase(
id); }
42 auto &tree_node = curr.tree_node;
43 if (tree_node.parent_nid !=
u64_max) {
48 tree_node.is_leaf =
false;
49 tree_node.child_are_all_leafs =
true;
51 std::array<Node, Node::split_count> splitted_node = curr.get_split_nodes(
id);
54 for (
u32 i = 0; i < Node::split_count; i++) {
55 curr.tree_node.
childs_nid[i] = insert_node(splitted_node[i]);
61 for (
u32 i = 0; i < Node::split_count; i++) {
69 auto &parent_tnode = parent_node.tree_node;
71 if (!parent_tnode.child_are_all_leafs) {
73 "node should be parent of only leafs");
76 leaf_key.erase(parent_tnode.childs_nid[0]);
77 leaf_key.erase(parent_tnode.childs_nid[1]);
78 leaf_key.erase(parent_tnode.childs_nid[2]);
79 leaf_key.erase(parent_tnode.childs_nid[3]);
80 leaf_key.erase(parent_tnode.childs_nid[4]);
81 leaf_key.erase(parent_tnode.childs_nid[5]);
82 leaf_key.erase(parent_tnode.childs_nid[6]);
83 leaf_key.erase(parent_tnode.childs_nid[7]);
85 remove_node(parent_tnode.childs_nid[0]);
86 remove_node(parent_tnode.childs_nid[1]);
87 remove_node(parent_tnode.childs_nid[2]);
88 remove_node(parent_tnode.childs_nid[3]);
89 remove_node(parent_tnode.childs_nid[4]);
90 remove_node(parent_tnode.childs_nid[5]);
91 remove_node(parent_tnode.childs_nid[6]);
92 remove_node(parent_tnode.childs_nid[7]);
94 parent_tnode.childs_nid[0] =
u64_max;
95 parent_tnode.childs_nid[1] =
u64_max;
96 parent_tnode.childs_nid[2] =
u64_max;
97 parent_tnode.childs_nid[3] =
u64_max;
98 parent_tnode.childs_nid[4] =
u64_max;
99 parent_tnode.childs_nid[5] =
u64_max;
100 parent_tnode.childs_nid[6] =
u64_max;
101 parent_tnode.childs_nid[7] =
u64_max;
104 parent_tnode.is_leaf =
true;
107 parent_tnode.child_are_all_leafs =
false;
110 if (parent_tnode.parent_nid !=
u64_max) {
111 bool only_leafs =
true;
113 Node &parent_node =
tree[parent_tnode.parent_nid];
115 for (
u8 idc = 0; idc < 8; idc++) {
116 only_leafs = only_leafs &&
tree[parent_node.get_child_nid(idc)].is_leaf();
128 root.patch_coord = coords;
129 root.tree_node.level = 0;
130 root.tree_node.parent_nid =
u64_max;
131 root.tree_node.is_leaf =
true;
132 root.tree_node.child_are_all_leafs =
false;
133 root.linked_patchid = patch_id;
135 u64 root_id = insert_node(root);
141 std::vector<shamrock::patch::Patch> &plist,
u64 max_val_1axis) {
143 if (plist.size() > 1) {
145 root.patch_coord.coord_max[0] = max_val_1axis;
146 root.patch_coord.coord_max[1] = max_val_1axis;
147 root.patch_coord.coord_max[2] = max_val_1axis;
148 root.patch_coord.coord_min[0] = 0;
149 root.patch_coord.coord_min[1] = 0;
150 root.patch_coord.coord_min[2] = 0;
151 root.tree_node.
level = 0;
154 u64 root_id = insert_node(root);
158 std::vector<u64> complete_vec;
159 for (
u64 i = 0; i < plist.size(); i++) {
160 complete_vec.push_back(i);
163 std::vector<std::tuple<u64, std::vector<u64>>> tree_vec(1);
165 tree_vec[0] = {root_id, complete_vec};
167 while (tree_vec.size() > 0) {
168 std::vector<std::tuple<u64, std::vector<u64>>> next_tree_vec;
169 for (
auto &[idtree, idvec] : tree_vec) {
175 for (
u8 child_id = 0; child_id < 8; child_id++) {
178 std::vector<u64> buf;
180 auto &curr =
tree[ptnode_id].patch_coord;
182 for (
u64 idxptch : idvec) {
185 bool is_inside = BBAA::iscellb_inside_a<u32_3>(
186 {curr.coord_min[0], curr.coord_min[1], curr.coord_min[2]},
187 {curr.coord_max[0], curr.coord_max[1], curr.coord_max[2]},
188 {p.coord_min[0], p.coord_min[1], p.coord_min[2]},
189 {p.coord_max[0], p.coord_max[1], p.coord_max[2]});
192 buf.push_back(idxptch);
212 if (buf.size() == 1) {
215 tree[ptnode_id].linked_patchid = plist[buf[0]].id_patch;
217 next_tree_vec.push_back({ptnode_id, buf});
223 tree_vec = next_tree_vec;
225 }
else if (plist.size() == 1) {
228 patch_coord.coord_max[0] = max_val_1axis;
229 patch_coord.coord_max[1] = max_val_1axis;
230 patch_coord.coord_max[2] = max_val_1axis;
231 patch_coord.coord_min[0] = 0;
232 patch_coord.coord_min[1] = 0;
233 patch_coord.coord_min[2] = 0;
234 insert_root_node(plist[0].id_patch, patch_coord);
238 void PatchTree::update_ptnode(
240 std::vector<shamrock::patch::Patch> &plist,
241 const std::unordered_map<u64, u64> &id_patch_to_global_idx) {
243 auto &tnode = n.tree_node;
245 if (n.linked_patchid !=
u64_max) {
247 n.load_value += plist[id_patch_to_global_idx.at(n.linked_patchid)].load_value;
248 }
else if (tnode.childs_nid[0] !=
u64_max) {
250 bool has_err_val =
false;
253 for (
u8 idc = 0; idc < 8; idc++) {
255 if (
tree[tnode.childs_nid[idc]].load_value ==
u64_max)
258 n.load_value +=
tree[tnode.childs_nid[idc]].load_value;
269 std::vector<shamrock::patch::Patch> &plist,
270 const std::unordered_map<u64, u64> &id_patch_to_global_idx) {
275 for (
auto &[key, ptnode] :
tree) {
276 update_ptnode(ptnode, plist, id_patch_to_global_idx);
282 std::vector<shamrock::patch::Patch> &plist,
283 const std::unordered_map<u64, u64> &id_patch_to_global_idx) {
287 update_ptnode(
tree[id_leaf], plist, id_patch_to_global_idx);
291 update_ptnode(
tree[id_leaf], plist, id_patch_to_global_idx);
297 std::unordered_set<u64> rq;
300 if (
tree[a].load_value > crit_load_split) {
310 std::unordered_set<u64> rq;
313 if (
tree[a].load_value < crit_load_merge) {
339 {
"next_id", next_id}};
350 j.at(
"tree").get_to(
tree);
353 j.at(
"next_id").get_to(next_id);
362 void to_json(nlohmann::json &j,
const PatchTree &p) { j = p.serialize_patch_metadata(); }
370 void from_json(
const nlohmann::json &j,
PatchTree &p) { p.load_json(j); }
Header file for the patch struct and related function.
std::uint8_t u8
8 bit unsigned integer
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
bool child_are_all_leafs
Store true if all childrens of this node are leafs.
std::array< u64, 8 > childs_nid
Array of childs node ids.
u32 level
Level of the tree node.
u64 parent_nid
Parent node id.
Node information in the patchtree + held patch info.
Patch Tree : Tree structure organisation for an abstract list of patches Nb : this tree is compatible...
void load_json(const nlohmann::json &j)
Load the metadata of the patch tree from a JSON object.
std::unordered_set< u64 > roots_id
set of root nodes ids
std::unordered_set< u64 > leaf_key
key of leaf nodes in tree
std::unordered_set< u64 > get_merge_request(u64 crit_load_merge)
Get list of nodes id to merge.
void build_from_patchtable(std::vector< Patch > &plist, u64 max_val_1axis)
make tree from a patch table
nlohmann::json serialize_patch_metadata() const
Serialize the metadata of the patch tree.
std::unordered_set< u64 > get_split_request(u64 crit_load_split)
Get list of nodes id to split.
void update_values_node(std::vector< Patch > &plist, const std::unordered_map< u64, u64 > &id_patch_to_global_idx)
update value in nodes (tree reduction)
std::unordered_set< u64 > parent_of_only_leaf_key
key of nodes that have only leafs as child
void partial_values_reduction(std::vector< Patch > &plist, const std::unordered_map< u64, u64 > &id_patch_to_global_idx)
update values in leafs and parent_of_only_leaf_key only
void merge_node_dm1(u64 idparent)
merge childs of idparent (id parent should have only leafs as childs)
std::unordered_map< u64, Node > tree
store the tree using a map
void split_node(u64 id)
split a leaf node
This header file contains utility functions related to exception handling in the code.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
constexpr u64 u64_max
u64 max value
This file contains the definition for the stacktrace related functionality.
Patch object that contain generic patch information.