1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 using System.Linq;
11 
12 namespace Antmicro.Renode.Utilities.Collections
13 {
14 
15     public class MultiTree<TValue, TConnectionWay> : MultiTreeNode<TValue, TConnectionWay>
16     {
MultiTree(TValue value)17         public MultiTree(TValue value) : base(value, null)
18         {
19             valueToNode = new Dictionary<TValue, MultiTreeNode<TValue, TConnectionWay>>();
20             valueToNode.Add(value, this);
21         }
22 
GetNode(TValue value)23         public MultiTreeNode<TValue, TConnectionWay> GetNode(TValue value)
24         {
25             return valueToNode[value];
26         }
27 
TryGetNode(TValue value, out MultiTreeNode<TValue, TConnectionWay> node)28         public bool TryGetNode(TValue value, out MultiTreeNode<TValue, TConnectionWay> node)
29         {
30             node = null;
31             if(valueToNode.ContainsKey(value))
32             {
33                 node = valueToNode[value];
34                 return true;
35             }
36             return false;
37         }
38 
39         public IEnumerable<TValue> Values
40         {
41             get
42             {
43                 return valueToNode.Select(x => x.Key).ToArray();
44             }
45         }
46 
ContainsValue(TValue value)47         public bool ContainsValue(TValue value)
48         {
49             return valueToNode.ContainsKey(value);
50         }
51 
TraverseWithConnectionWaysParentFirst(Action<MultiTreeNode<TValue, TConnectionWay>, TConnectionWay, TValue, int> nodeHandler, int initialLevel)52         public void TraverseWithConnectionWaysParentFirst(Action<MultiTreeNode<TValue, TConnectionWay>, TConnectionWay, TValue, int> nodeHandler, int initialLevel)
53         {
54             nodeHandler(this, default(TConnectionWay), default(TValue), initialLevel);
55             TraverseWithConnectionWaysChildrenOnly(nodeHandler, initialLevel);
56         }
57 
FindOrCreateNode(TValue value)58         internal MultiTreeNode<TValue, TConnectionWay> FindOrCreateNode(TValue value)
59         {
60             if(valueToNode.ContainsKey(value))
61             {
62                 return valueToNode[value];
63             }
64             var newNode = new MultiTreeNode<TValue, TConnectionWay>(value, this);
65             valueToNode.Add(value, newNode);
66             return newNode;
67         }
68 
GarbageCollect()69         internal void GarbageCollect()
70         {
71             var toDelete = valueToNode.Select(x => x.Key).Except(this).ToArray();
72             foreach(var value in toDelete)
73             {
74                 valueToNode.Remove(value);
75             }
76         }
77 
78         private readonly Dictionary<TValue, MultiTreeNode<TValue, TConnectionWay>> valueToNode;
79     }
80 }
81