Skip to content

Commit 560e841

Browse files
committed
Added overloaded constructor that takes an AddDuplicateBehavior enum to specify how the tree should behave when you try to add a node with a duplicate coordinate
1 parent 52c0699 commit 560e841

File tree

2 files changed

+101
-3
lines changed

2 files changed

+101
-3
lines changed

KdTreeLib/KdTree.cs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,24 @@
55
using System.Linq;
66
using System.Runtime.Serialization.Formatters.Binary;
77
using System.Text;
8-
using System.Threading.Tasks;
9-
using KdTree.Math;
108

119
namespace KdTree
1210
{
11+
public enum AddDuplicateBehavior
12+
{
13+
Skip,
14+
Error,
15+
Update
16+
}
17+
18+
public class DuplicateNodeError : Exception
19+
{
20+
public DuplicateNodeError()
21+
: base("Cannot Add Node With Duplicate Coordinates")
22+
{
23+
}
24+
}
25+
1326
[Serializable]
1427
public class KdTree<TKey, TValue> : IKdTree<TKey, TValue>
1528
{
@@ -20,12 +33,20 @@ public KdTree(int dimensions, ITypeMath<TKey> typeMath)
2033
Count = 0;
2134
}
2235

36+
public KdTree(int dimensions, ITypeMath<TKey> typeMath, AddDuplicateBehavior addDuplicateBehavior)
37+
: this(dimensions, typeMath)
38+
{
39+
AddDuplicateBehavior = addDuplicateBehavior;
40+
}
41+
2342
private int dimensions;
2443

2544
private ITypeMath<TKey> typeMath = null;
2645

2746
private KdTreeNode<TKey, TValue> root = null;
2847

48+
public AddDuplicateBehavior AddDuplicateBehavior { get; private set; }
49+
2950
public bool Add(TKey[] point, TValue value)
3051
{
3152
var nodeToAdd = new KdTreeNode<TKey, TValue>(point, value);
@@ -46,7 +67,24 @@ public bool Add(TKey[] point, TValue value)
4667

4768
// Does the node we're adding have the same hyperpoint as this node?
4869
if (typeMath.AreEqual(point, parent.Point))
49-
return false;
70+
{
71+
switch (AddDuplicateBehavior)
72+
{
73+
case AddDuplicateBehavior.Skip:
74+
return false;
75+
76+
case AddDuplicateBehavior.Error:
77+
throw new DuplicateNodeError();
78+
79+
case AddDuplicateBehavior.Update:
80+
parent.Value = value;
81+
break;
82+
83+
default:
84+
// Should never happen
85+
throw new Exception("Unexpected AddDuplicateBehavior");
86+
}
87+
}
5088

5189
// Which side does this node sit under in relation to it's parent at this level?
5290
int compare = typeMath.Compare(point[dimension], parent.Point[dimension]);

KdTreeTestsLib/KdTreeTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,66 @@ public void TestAdd()
6464
Assert.AreEqual(testNodes.Count, tree.Count);
6565
}
6666

67+
[TestMethod]
68+
[TestCategory("KdTree")]
69+
public void TestAddDuplicateInSkipMode()
70+
{
71+
tree = new KdTree<float, string>(2, new FloatMath());
72+
73+
Assert.AreEqual(AddDuplicateBehavior.Skip, tree.AddDuplicateBehavior);
74+
75+
AddTestNodes();
76+
77+
var count = tree.Count;
78+
79+
var added = tree.Add(testNodes[0].Point, "Some other value");
80+
81+
Assert.AreEqual(false, added);
82+
Assert.AreEqual(count, tree.Count);
83+
}
84+
85+
[TestMethod]
86+
[TestCategory("KdTree")]
87+
public void TestAddDuplicateInErrorMode()
88+
{
89+
tree = new KdTree<float, string>(2, new FloatMath(), AddDuplicateBehavior.Error);
90+
91+
AddTestNodes();
92+
93+
var count = tree.Count;
94+
Exception error = null;
95+
96+
try
97+
{
98+
tree.Add(testNodes[0].Point, "Some other value");
99+
}
100+
catch (Exception e)
101+
{
102+
error = e;
103+
}
104+
105+
Assert.AreEqual(count, tree.Count);
106+
Assert.IsNotNull(error);
107+
Assert.IsInstanceOfType(error, typeof(DuplicateNodeError));
108+
}
109+
110+
[TestMethod]
111+
[TestCategory("KdTree")]
112+
public void TestAddDuplicateInUpdateMode()
113+
{
114+
tree = new KdTree<float, string>(2, new FloatMath(), AddDuplicateBehavior.Update);
115+
116+
AddTestNodes();
117+
118+
var newValue = "I love chicken, I love liver, Meow Mix Meow Mix please deliver";
119+
120+
tree.Add(testNodes[0].Point, newValue);
121+
122+
var actualValue = tree.FindValueAt(testNodes[0].Point);
123+
124+
Assert.AreEqual(newValue, actualValue);
125+
}
126+
67127
[TestMethod]
68128
[TestCategory("KdTree")]
69129
public void TestTryFindValueAt()

0 commit comments

Comments
 (0)