Skip to content

Commit 0411a03

Browse files
committed
fix RedBlackTree
1 parent 217f66e commit 0411a03

File tree

7 files changed

+180
-8
lines changed

7 files changed

+180
-8
lines changed

net.lecousin.core/src/main/java/net/lecousin/framework/application/Application.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private Application(
9090
private LocalizedProperties localizedProperties;
9191
private String[] languageTag;
9292
private LoggerFactory loggerFactory;
93-
private Map<Class<?>, Object> instances = new HashMap<>();
93+
private Map<String, Object> instances = new HashMap<>();
9494
private Map<String, Object> data = new HashMap<>();
9595
private LinkedList<Pair<Integer, Object>> toClose = new LinkedList<>();
9696
private ArrayList<Thread> toInterrupt = new ArrayList<>();
@@ -265,23 +265,23 @@ public boolean isStopping() {
265265
@SuppressWarnings("unchecked")
266266
public <T> T getInstance(Class<T> clazz) {
267267
synchronized (instances) {
268-
return (T)instances.get(clazz);
268+
return (T)instances.get(clazz.getName());
269269
}
270270
}
271271

272272
/** Set the singleton stored for this application. */
273273
@SuppressWarnings("unchecked")
274274
public <T> T setInstance(Class<T> clazz, T instance) {
275275
synchronized (instances) {
276-
return (T)instances.put(clazz, instance);
276+
return (T)instances.put(clazz.getName(), instance);
277277
}
278278
}
279279

280280
/** Remove the singleton stored for this application. */
281281
@SuppressWarnings("unchecked")
282282
public <T> T removeInstance(Class<T> clazz) {
283283
synchronized (instances) {
284-
return (T)instances.remove(clazz);
284+
return (T)instances.remove(clazz.getName());
285285
}
286286
}
287287

net.lecousin.core/src/main/java/net/lecousin/framework/collections/sort/RedBlackTreeInteger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ private Node<T> add(int value, T element, Node<T> h) {
362362
} else if (value >= h.value) {
363363
if (h.right == null) {
364364
h.right = new Node<>(value, element, true);
365-
if (value > last.value) last = h.right;
365+
if (value > last.value || last == h) last = h.right;
366366
} else {
367367
h.right = add(value, element, h.right);
368368
}

net.lecousin.core/src/main/java/net/lecousin/framework/collections/sort/RedBlackTreeLong.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ private Node<T> add(long value, T element, Node<T> h) {
364364
} else if (value >= h.value) {
365365
if (h.right == null) {
366366
h.right = new Node<>(value, element, true);
367-
if (value > last.value) last = h.right;
367+
if (value > last.value || last == h) last = h.right;
368368
} else {
369369
h.right = add(value, element, h.right);
370370
}

net.lecousin.core/src/test/java/net/lecousin/framework/core/test/collections/sort/TestSortedAssociatedWithInteger.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void testAddDecrementRemoveIncrement() {
105105
}
106106

107107
@Test
108-
public void testAddRemoveRandom() {
108+
public void testAddThenRemoveRandom() {
109109
Sorted.AssociatedWithInteger<Object> list = createSorted();
110110
TreeSet<Integer> order = new TreeSet<>();
111111
Random rand = new Random();
@@ -125,6 +125,44 @@ public void testAddRemoveRandom() {
125125
}
126126
}
127127

128+
@Test
129+
public void testAddAndRemoveRandom() {
130+
Sorted.AssociatedWithInteger<Object> list = createSorted();
131+
Random rand = new Random();
132+
LinkedList<Integer> toAdd = new LinkedList<>();
133+
for (int i = 0; i < 2000; ++i) {
134+
Integer value = Integer.valueOf(rand.nextInt());
135+
while (toAdd.contains(value)) value = Integer.valueOf(rand.nextInt());
136+
toAdd.add(value);
137+
}
138+
LinkedList<Integer> toRemove = new LinkedList<>();
139+
TreeSet<Integer> order = new TreeSet<>();
140+
do {
141+
if (!toAdd.isEmpty()) {
142+
int nb = rand.nextInt(toAdd.size()) + 1;
143+
for (int i = 0; i < nb; ++i) {
144+
Integer value = toAdd.removeFirst();
145+
Assert.assertFalse(list.contains(value.intValue(), Integer.valueOf(-value.intValue())));
146+
list.add(value.intValue(), Integer.valueOf(-value.intValue()));
147+
Assert.assertTrue(list.contains(value.intValue(), Integer.valueOf(-value.intValue())));
148+
order.add(value);
149+
toRemove.add(value);
150+
}
151+
}
152+
int nb = rand.nextInt(toRemove.size()) + 1;
153+
for (int i = 0; i < nb; ++i) {
154+
Integer value = toRemove.remove(rand.nextInt(toRemove.size()));
155+
Assert.assertTrue(list.contains(value.intValue(), Integer.valueOf(-value.intValue())));
156+
list.remove(value.intValue(), Integer.valueOf(-value.intValue()));
157+
Assert.assertFalse(list.contains(value.intValue(), Integer.valueOf(-value.intValue())));
158+
order.remove(value);
159+
}
160+
check(list, order);
161+
} while (!toAdd.isEmpty() || !toRemove.isEmpty());
162+
Assert.assertEquals(0, order.size());
163+
Assert.assertEquals(0, list.size());
164+
}
165+
128166
protected void check(Sorted.AssociatedWithInteger<Object> sorted, TreeSet<Integer> order) {
129167
Assert.assertEquals(order.size(), sorted.size());
130168
if (order.isEmpty())

net.lecousin.core/src/test/java/net/lecousin/framework/core/test/collections/sort/TestSortedAssociatedWithLong.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void testAddDecrementRemoveIncrement() {
105105
}
106106

107107
@Test
108-
public void testAddRemoveRandom() {
108+
public void testAddThenRemoveRandom() {
109109
Sorted.AssociatedWithLong<Object> list = createSorted();
110110
TreeSet<Long> order = new TreeSet<>();
111111
Random rand = new Random();
@@ -125,6 +125,45 @@ public void testAddRemoveRandom() {
125125
}
126126
}
127127

128+
@Test
129+
public void testAddAndRemoveRandom() {
130+
Sorted.AssociatedWithLong<Object> list = createSorted();
131+
Random rand = new Random();
132+
LinkedList<Long> toAdd = new LinkedList<>();
133+
for (int i = 0; i < 2000; ++i) {
134+
Long value = Long.valueOf(rand.nextLong());
135+
while (toAdd.contains(value)) value = Long.valueOf(rand.nextLong());
136+
toAdd.add(value);
137+
}
138+
LinkedList<Long> toRemove = new LinkedList<>();
139+
TreeSet<Long> order = new TreeSet<>();
140+
do {
141+
if (!toAdd.isEmpty()) {
142+
int nb = rand.nextInt(toAdd.size()) + 1;
143+
for (int i = 0; i < nb; ++i) {
144+
Long value = toAdd.removeFirst();
145+
Assert.assertFalse(list.contains(value.longValue(), Long.valueOf(-value.longValue())));
146+
list.add(value.longValue(), Long.valueOf(-value.longValue()));
147+
Assert.assertTrue(list.contains(value.longValue(), Long.valueOf(-value.longValue())));
148+
order.add(value);
149+
toRemove.add(value);
150+
}
151+
}
152+
int nb = rand.nextInt(toRemove.size()) + 1;
153+
for (int i = 0; i < nb; ++i) {
154+
Long value = toRemove.remove(rand.nextInt(toRemove.size()));
155+
Assert.assertTrue(list.contains(value.longValue(), Long.valueOf(-value.longValue())));
156+
list.remove(value.longValue(), Long.valueOf(-value.longValue()));
157+
Assert.assertFalse(list.contains(value.longValue(), Long.valueOf(-value.longValue())));
158+
order.remove(value);
159+
}
160+
check(list, order);
161+
} while (!toAdd.isEmpty() || !toRemove.isEmpty());
162+
Assert.assertEquals(0, order.size());
163+
Assert.assertEquals(0, list.size());
164+
}
165+
166+
128167
protected void check(Sorted.AssociatedWithLong<Object> sorted, TreeSet<Long> order) {
129168
Assert.assertEquals(order.size(), sorted.size());
130169
if (order.isEmpty())

net.lecousin.core/src/test/java/net/lecousin/framework/core/tests/collections/sort/TestRedBlackTreeInteger.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,51 @@ public void tests() {
172172
Assert.assertNull(tree.searchNearestHigher(99, false));
173173
}
174174

175+
@Test
176+
public void testAddAndRemoveWithCommonValues() {
177+
RedBlackTreeInteger<Object> tree = new RedBlackTreeInteger<Object>();
178+
Object o1 = new Object();
179+
Object o2 = new Object();
180+
Object o3 = new Object();
181+
Object o4 = new Object();
182+
tree.add(10, o1);
183+
tree.add(10, o2);
184+
tree.add(10, o3);
185+
tree.add(10, o4);
186+
Assert.assertEquals(4, tree.size());
187+
188+
tree.remove(getNode(tree, o2));
189+
Assert.assertEquals(3, tree.size());
190+
Assert.assertTrue(tree.contains(10, o1));
191+
Assert.assertFalse(tree.contains(10, o2));
192+
Assert.assertTrue(tree.contains(10, o3));
193+
Assert.assertTrue(tree.contains(10, o4));
194+
195+
tree.remove(getNode(tree, o4));
196+
Assert.assertEquals(2, tree.size());
197+
Assert.assertTrue(tree.contains(10, o1));
198+
Assert.assertFalse(tree.contains(10, o2));
199+
Assert.assertTrue(tree.contains(10, o3));
200+
Assert.assertFalse(tree.contains(10, o4));
201+
202+
tree.remove(getNode(tree, o1));
203+
Assert.assertEquals(1, tree.size());
204+
Assert.assertFalse(tree.contains(10, o1));
205+
Assert.assertFalse(tree.contains(10, o2));
206+
Assert.assertTrue(tree.contains(10, o3));
207+
Assert.assertFalse(tree.contains(10, o4));
208+
209+
tree.remove(getNode(tree, o3));
210+
Assert.assertEquals(0, tree.size());
211+
}
212+
213+
private static RedBlackTreeInteger.Node<Object> getNode(RedBlackTreeInteger<Object> tree, Object o) {
214+
for (Iterator<RedBlackTreeInteger.Node<Object>> it = tree.nodeIterator(); it.hasNext(); ) {
215+
RedBlackTreeInteger.Node<Object> node = it.next();
216+
if (node.getElement().equals(o))
217+
return node;
218+
}
219+
throw new AssertionError("Node not found");
220+
}
221+
175222
}

net.lecousin.core/src/test/java/net/lecousin/framework/core/tests/collections/sort/TestRedBlackTreeLong.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,52 @@ public void tests() {
180180
Assert.assertNull(tree.searchNearestHigher(99, false));
181181
}
182182

183+
184+
@Test
185+
public void testAddAndRemoveWithCommonValues() {
186+
RedBlackTreeLong<Object> tree = new RedBlackTreeLong<Object>();
187+
Object o1 = new Object();
188+
Object o2 = new Object();
189+
Object o3 = new Object();
190+
Object o4 = new Object();
191+
tree.add(10, o1);
192+
tree.add(10, o2);
193+
tree.add(10, o3);
194+
tree.add(10, o4);
195+
Assert.assertEquals(4, tree.size());
196+
197+
tree.remove(getNode(tree, o2));
198+
Assert.assertEquals(3, tree.size());
199+
Assert.assertTrue(tree.contains(10, o1));
200+
Assert.assertFalse(tree.contains(10, o2));
201+
Assert.assertTrue(tree.contains(10, o3));
202+
Assert.assertTrue(tree.contains(10, o4));
203+
204+
tree.remove(getNode(tree, o4));
205+
Assert.assertEquals(2, tree.size());
206+
Assert.assertTrue(tree.contains(10, o1));
207+
Assert.assertFalse(tree.contains(10, o2));
208+
Assert.assertTrue(tree.contains(10, o3));
209+
Assert.assertFalse(tree.contains(10, o4));
210+
211+
tree.remove(getNode(tree, o1));
212+
Assert.assertEquals(1, tree.size());
213+
Assert.assertFalse(tree.contains(10, o1));
214+
Assert.assertFalse(tree.contains(10, o2));
215+
Assert.assertTrue(tree.contains(10, o3));
216+
Assert.assertFalse(tree.contains(10, o4));
217+
218+
tree.remove(getNode(tree, o3));
219+
Assert.assertEquals(0, tree.size());
220+
}
221+
222+
private static RedBlackTreeLong.Node<Object> getNode(RedBlackTreeLong<Object> tree, Object o) {
223+
for (Iterator<RedBlackTreeLong.Node<Object>> it = tree.nodeIterator(); it.hasNext(); ) {
224+
RedBlackTreeLong.Node<Object> node = it.next();
225+
if (node.getElement().equals(o))
226+
return node;
227+
}
228+
throw new AssertionError("Node not found");
229+
}
230+
183231
}

0 commit comments

Comments
 (0)