< Summary

Information
Class: MoreStructures.SuffixStructures.Conversions.FullyRecursiveConverter
Assembly: MoreStructures
File(s): /home/runner/work/MoreStructures/MoreStructures/MoreStructures/SuffixStructures/Conversions/FullyRecursiveConverter.cs
Line coverage
100%
Covered lines: 55
Uncovered lines: 0
Coverable lines: 55
Total lines: 98
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
TrieToTree(...)100%4100%
RecursiveCoalesce(...)100%6100%
TreeToTrie(...)100%4100%
RecursiveExpand(...)100%2100%

File(s)

/home/runner/work/MoreStructures/MoreStructures/MoreStructures/SuffixStructures/Conversions/FullyRecursiveConverter.cs

#LineLine coverage
 1using MoreStructures.SuffixTrees;
 2using MoreStructures.SuffixTries;
 3
 4namespace MoreStructures.SuffixStructures.Conversions;
 5
 6/// <summary>
 7/// <inheritdoc cref="IConverter"/>
 8/// </summary>
 9/// <remarks>
 10/// Implemented fully recursively, with one level of recursion per level of the input <see cref="SuffixTrieNode"/>.
 11/// Limited by call stack depth and usable with input trees of a "reasonable" height (i.e. trees having a height &lt;
 12/// ~1K nodes).
 13/// </remarks>
 14public class FullyRecursiveConverter : IConverter
 15{
 16    /// <inheritdoc path="//*[not(self::summary or self::remarks)]"/>
 17    /// <summary>
 18    ///     <inheritdoc/>
 19    /// </summary>
 20    /// <remarks>
 21    ///     <inheritdoc cref="FullyRecursiveConverter" path="/remarks"/>
 22    ///     <inheritdoc cref="IConverter.TrieToTree(SuffixTrieNode)" path="/remarks"/>
 23    /// </remarks>
 24    public SuffixTreeNode TrieToTree(SuffixTrieNode trieNode) =>
 3625        trieNode switch
 3626        {
 3627            SuffixTrieNode.Leaf(var leafStart) =>
 1828                new SuffixTreeNode.Leaf(leafStart),
 3629
 3630            SuffixTrieNode.Intermediate(var trieNodeChildren) =>
 1731                new SuffixTreeNode.Intermediate(new Dictionary<SuffixTreeEdge, SuffixTreeNode>(
 1732                    from trieChild in trieNodeChildren
 2433                    let treeChildEdge = new SuffixTreeEdge(trieChild.Key.Start, trieChild.Key.Length)
 2434                    let coaleascedChild = RecursiveCoalesce(treeChildEdge, trieChild.Value)
 2335                    let treeChildEdge1 = coaleascedChild.Item1
 2336                    let trieChildNode1 = coaleascedChild.Item2
 2337                    select KeyValuePair.Create(treeChildEdge1, TrieToTree(trieChildNode1))
 1738                )),
 3639
 140            _ => throw new NotSupportedException($"{trieNode} of type {trieNode.GetType().Name} not supported"),
 3641        };
 42
 43    private static (SuffixTreeEdge, SuffixTrieNode) RecursiveCoalesce(
 44        SuffixTreeEdge treeEdge, SuffixTrieNode trieNode) =>
 14345        trieNode switch
 14346        {
 14347            SuffixTrieNode.Leaf =>
 1748                (treeEdge, trieNode),
 14349
 12550            SuffixTrieNode.Intermediate(var children) when children.Count != 1 =>
 651                (treeEdge, trieNode),
 14352
 11953            SuffixTrieNode.Intermediate(var children) when children.Single() is var (trieChildEdge, trieChildNode) =>
 11954                RecursiveCoalesce(
 11955                    new SuffixTreeEdge(treeEdge.Start, treeEdge.Length + trieChildEdge.Length), trieChildNode),
 14356
 157            _ => throw new NotSupportedException($"{trieNode} of type {trieNode.GetType().Name} not supported"),
 14358        };
 59
 60    /// <inheritdoc path="//*[not(self::summary or self::remarks)]"/>
 61    /// <summary>
 62    ///     <inheritdoc/>
 63    /// </summary>
 64    /// <remarks>
 65    ///     <inheritdoc cref="FullyRecursiveConverter" path="/remarks"/>
 66    ///     <inheritdoc cref="IConverter.TreeToTrie(SuffixTreeNode)" path="/remarks"/>
 67    /// </remarks>
 68    public SuffixTrieNode TreeToTrie(SuffixTreeNode treeNode) =>
 3769        treeNode switch
 3770        {
 3771            SuffixTreeNode.Leaf(var leafStart) =>
 1872                new SuffixTrieNode.Leaf(leafStart),
 3773
 3774            SuffixTreeNode.Intermediate(var nodeChildren) =>
 1775                new SuffixTrieNode.Intermediate(new Dictionary<SuffixTrieEdge, SuffixTrieNode>(
 1776                    from treeChild in nodeChildren
 2477                    let expandedChild = RecursiveExpand(treeChild.Key, TreeToTrie(treeChild.Value), 0)
 3978                    select KeyValuePair.Create(expandedChild.expandedTrieEdge, expandedChild.expandedTrieNode))),
 3779
 280            _ => throw new NotSupportedException($"{treeNode} of type {treeNode.GetType().Name} not supported"),
 3781        };
 82
 83    private static (SuffixTrieEdge expandedTrieEdge, SuffixTrieNode expandedTrieNode) RecursiveExpand(
 84        SuffixTreeEdge treeEdge, SuffixTrieNode trieNode, int edgeIndexDelta)
 14185    {
 14186        var expandedTrieEdge = new SuffixTrieEdge(treeEdge.Start + edgeIndexDelta);
 87
 14188        if (treeEdge.Length == edgeIndexDelta + 1)
 2289            return (expandedTrieEdge, trieNode);
 90
 11991        var (childExpandedTrieEdge, childExpandedTrieNode) = RecursiveExpand(treeEdge, trieNode, edgeIndexDelta + 1);
 11992        return (expandedTrieEdge,
 11993            new SuffixTrieNode.Intermediate(new Dictionary<SuffixTrieEdge, SuffixTrieNode>
 11994            {
 11995                [childExpandedTrieEdge] = childExpandedTrieNode
 11996            }));
 14197    }
 98}