103 lines
2.7 KiB
Julia
Raw Normal View History

"""
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
2023-08-25 10:48:22 +02:00
depth = depth + 1
id = node.children[depth].id
2023-08-25 10:48:22 +02:00
if (!haskey(trie.children, id))
trie.children[id] = NodeIdTrie()
end
2023-08-25 10:48:22 +02:00
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
2023-08-25 10:48:22 +02:00
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
2023-08-25 10:48:22 +02:00
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}}()
2023-08-25 10:48:22 +02:00
for (t, child) in trie.children
collect_helper(child, acc)
end
return acc
end