function bytes_to_human_readable(bytes::Int64) units = ["B", "KiB", "MiB", "GiB", "TiB"] unit_index = 1 while bytes >= 1024 && unit_index < length(units) bytes /= 1024 unit_index += 1 end return string(round(bytes, sigdigits=4), " ", units[unit_index]) end # Trie data structure for node reduction, inserts nodes by children # Assumes that given nodes have ordered sets of children (see sort_node) mutable struct NodeTrie value::Set{Node} children::Dict{UUID, NodeTrie} end NodeTrie() = NodeTrie(Set{Node}(), Dict{UUID, NodeTrie}()) function insert_helper!(trie::NodeTrie, node::Node, depth::Int) if (length(node.children) == depth) push!(trie.value, node) return nothing end depth = depth + 1 id = node.children[depth].id if (!haskey(trie.children, id)) trie.children[id] = NodeTrie() end insert_helper!(trie.children[id], node, depth) end function insert!(trie::NodeTrie, node::Node) insert_helper!(trie, node, 0) end function collect_helper(trie::NodeTrie, acc::Set{Set{Node}}) if (length(trie.value) >= 2) push!(acc, trie.value) end for (id,child) in trie.children collect_helper(child, acc) end return nothing end # returns all sets of multiple nodes that have accumulated in leaves function collect(trie::NodeTrie) acc = Set{Set{Node}}() collect_helper(trie, acc) return acc end function lt_nodes(n1::Node, n2::Node) return n1.id < n2.id end function sort_node!(node::Node) sort!(node.children, lt=lt_nodes) end