Anton Reinhard 065236be22 Add documentation to every function and automatic doc html building ()
Reviewed-on: 
Co-authored-by: Anton Reinhard <anton.reinhard@proton.me>
Co-committed-by: Anton Reinhard <anton.reinhard@proton.me>
2023-08-29 12:57:46 +02:00

103 lines
2.7 KiB
Julia

"""
NodeIdTrie
Helper struct for [`NodeTrie`](@ref). After the Trie's first level, every Trie level contains the vector of nodes that had children up to that level, and the TrieNode's children by UUID of the node's children.
"""
mutable struct NodeIdTrie
value::Vector{Node}
children::Dict{UUID, NodeIdTrie}
end
"""
NodeTrie
Trie data structure for node reduction, inserts nodes by children.
Assumes that given nodes have ordered vectors of children (see [`sort_node!`](@ref)).
First insertion level is the node's own task type and thus does not have a value (every node has a task type).
See also: [`insert!`](@ref) and [`collect`](@ref)
"""
mutable struct NodeTrie
children::Dict{DataType, NodeIdTrie}
end
"""
NodeTrie()
Constructor for an empty [`NodeTrie`](@ref).
"""
function NodeTrie()
return NodeTrie(Dict{DataType, NodeIdTrie}())
end
"""
NodeIdTrie()
Constructor for an empty [`NodeIdTrie`](@ref).
"""
function NodeIdTrie()
return NodeIdTrie(Vector{Node}(), Dict{UUID, NodeIdTrie}())
end
"""
insert_helper!(trie::NodeIdTrie, node::Node, depth::Int)
Insert the given node into the trie. The depth is used to iterate through the trie layers, while the function calls itself recursively until it ran through all children of the node.
"""
function insert_helper!(trie::NodeIdTrie, 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] = NodeIdTrie()
end
return insert_helper!(trie.children[id], node, depth)
end
"""
insert!(trie::NodeTrie, node::Node)
Insert the given node into the trie. It's sorted by its type in the first layer, then by its children in the following layers.
"""
function insert!(trie::NodeTrie, node::Node)
t = typeof(node.task)
if (!haskey(trie.children, t))
trie.children[t] = NodeIdTrie()
end
return insert_helper!(trie.children[typeof(node.task)], node, 0)
end
"""
collect_helper(trie::NodeIdTrie, acc::Set{Vector{Node}})
Collects the Vectors of this [`NodeIdTrie`](@ref) node and all its children and puts them in the `acc` argument.
"""
function collect_helper(trie::NodeIdTrie, acc::Set{Vector{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
"""
collect(trie::NodeTrie)
Return all sets of at least 2 [`Node`](@ref)s that have accumulated in leaves of the trie.
"""
function collect(trie::NodeTrie)
acc = Set{Vector{Node}}()
for (t, child) in trie.children
collect_helper(child, acc)
end
return acc
end