Migrate to tech.pantheon.TrieMap
[yangtools.git] / third-party / triemap / src / test / java / org / opendaylight / yangtools / triemap / TestMultiThreadMapIterator.java
1 /*
2  * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.opendaylight.yangtools.triemap;
17
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.TimeUnit;
30 import org.junit.Test;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 @Deprecated
35 public class TestMultiThreadMapIterator {
36     private static final Logger LOG = LoggerFactory.getLogger(TestMultiThreadMapIterator.class);
37     private static final int NTHREADS = 7;
38
39     @Test
40     public void testMultiThreadMapIterator() throws InterruptedException {
41         final Map<Object, Object> bt = TrieMap.create();
42         for (int j = 0; j < 50 * 1000; j++) {
43             for (final Object o : getObjects(j)) {
44                 bt.put(o, o);
45             }
46         }
47
48         LOG.debug("Size of initialized map is {}", bt.size());
49         int count = 0;
50         {
51             final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
52             for (int i = 0; i < NTHREADS; i++) {
53                 final int threadNo = i;
54                 es.execute(() -> {
55                     for (Entry<Object, Object> e : bt.entrySet()) {
56                         if (accepts(threadNo, NTHREADS, e.getKey())) {
57                             String newValue = "TEST:" + threadNo;
58                             e.setValue(newValue);
59                         }
60                     }
61                 });
62             }
63
64             es.shutdown();
65             es.awaitTermination(5, TimeUnit.MINUTES);
66         }
67
68         count = 0;
69         for (final Map.Entry<Object, Object> kv : bt.entrySet()) {
70             assertTrue(kv.getValue() instanceof String);
71             count++;
72         }
73         assertEquals(50000 + 2000 + 1000 + 100, count);
74
75         final ConcurrentHashMap<Object, Object> removed = new ConcurrentHashMap<>();
76         {
77             final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
78             for (int i = 0; i < NTHREADS; i++) {
79                 final int threadNo = i;
80                 es.execute(() -> {
81                     for (final Iterator<Map.Entry<Object, Object>> it = bt.entrySet().iterator(); it.hasNext();) {
82                         final Entry<Object, Object> e = it.next();
83                         Object key = e.getKey();
84                         if (accepts(threadNo, NTHREADS, key)) {
85                             if (null == bt.get(key)) {
86                                 LOG.error("Key {} is not present", key);
87                             }
88                             it.remove();
89                             if (null != bt.get(key)) {
90                                 LOG.error("Key {} is still present", key);
91                             }
92                             removed.put(key, key);
93                         }
94                     }
95                 });
96             }
97
98             es.shutdown();
99             es.awaitTermination(5, TimeUnit.MINUTES);
100         }
101
102         count = 0;
103         for (final Object value : bt.keySet()) {
104             value.toString();
105             count++;
106         }
107         for (final Object o : bt.keySet()) {
108             if (!removed.contains(bt.get(o))) {
109                 LOG.error("Not removed: {}", o);
110             }
111         }
112         assertEquals(0, count);
113         assertEquals(0, bt.size());
114         assertTrue(bt.isEmpty());
115     }
116
117     protected static boolean accepts(final int threadNo, final int nrThreads, final Object key) {
118         final int val = getKeyValue(key);
119         return val >= 0 ? val % nrThreads == threadNo : false;
120     }
121
122     private static int getKeyValue(final Object key) {
123         if (key instanceof Integer) {
124             return ((Integer) key).intValue();
125         } else if (key instanceof Character) {
126             return Math.abs(Character.getNumericValue((Character) key) + 1);
127         } else if (key instanceof Short) {
128             return ((Short) key).intValue() + 2;
129         } else if (key instanceof Byte) {
130             return ((Byte) key).intValue() + 3;
131         } else {
132             return -1;
133         }
134     }
135
136     static Collection<Object> getObjects(final int j) {
137         final Collection<Object> results = new ArrayList<>(4);
138         results.add(Integer.valueOf(j));
139         if (j < 2000) {
140             results.add(Character.valueOf((char) j));
141         }
142         if (j < 1000) {
143             results.add(Short.valueOf((short) j));
144         }
145         if (j < 100) {
146             results.add(Byte.valueOf((byte) j));
147         }
148
149         return results;
150     }
151 }