BUG-7464: eliminate console output
[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 public class TestMultiThreadMapIterator {
35     private static final Logger LOG = LoggerFactory.getLogger(TestMultiThreadMapIterator.class);
36     private static final int NTHREADS = 7;
37
38     @Test
39     public void testMultiThreadMapIterator() throws InterruptedException {
40         final Map<Object, Object> bt = TrieMap.create();
41         for (int j = 0; j < 50 * 1000; j++) {
42             for (final Object o : getObjects(j)) {
43                 bt.put(o, o);
44             }
45         }
46
47         LOG.debug("Size of initialized map is {}", bt.size());
48         int count = 0;
49         {
50             final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
51             for (int i = 0; i < NTHREADS; i++) {
52                 final int threadNo = i;
53                 es.execute(() -> {
54                     for (Entry<Object, Object> e : bt.entrySet()) {
55                         if (accepts(threadNo, NTHREADS, e.getKey())) {
56                             String newValue = "TEST:" + threadNo;
57                             e.setValue(newValue);
58                         }
59                     }
60                 });
61             }
62
63             es.shutdown();
64             es.awaitTermination(5, TimeUnit.MINUTES);
65         }
66
67         count = 0;
68         for (final Map.Entry<Object, Object> kv : bt.entrySet()) {
69             assertTrue(kv.getValue() instanceof String);
70             count++;
71         }
72         assertEquals(50000 + 2000 + 1000 + 100, count);
73
74         final ConcurrentHashMap<Object, Object> removed = new ConcurrentHashMap<>();
75         {
76             final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
77             for (int i = 0; i < NTHREADS; i++) {
78                 final int threadNo = i;
79                 es.execute(() -> {
80                     for (final Iterator<Map.Entry<Object, Object>> it = bt.entrySet().iterator(); it.hasNext();) {
81                         final Entry<Object, Object> e = it.next();
82                         Object key = e.getKey();
83                         if (accepts(threadNo, NTHREADS, key)) {
84                             if (null == bt.get(key)) {
85                                 LOG.error("Key {} is not present", key);
86                             }
87                             it.remove();
88                             if (null != bt.get(key)) {
89                                 LOG.error("Key {} is still present", key);
90                             }
91                             removed.put(key, key);
92                         }
93                     }
94                 });
95             }
96
97             es.shutdown();
98             es.awaitTermination(5, TimeUnit.MINUTES);
99         }
100
101         count = 0;
102         for (final Object value : bt.keySet()) {
103             value.toString();
104             count++;
105         }
106         for (final Object o : bt.keySet()) {
107             if (!removed.contains(bt.get(o))) {
108                 LOG.error("Not removed: {}", o);
109             }
110         }
111         assertEquals(0, count);
112         assertEquals(0, bt.size());
113         assertTrue(bt.isEmpty());
114     }
115
116     protected static boolean accepts(final int threadNo, final int nrThreads, final Object key) {
117         final int val = getKeyValue(key);
118         return val >= 0 ? val % nrThreads == threadNo : false;
119     }
120
121     private static int getKeyValue(final Object key) {
122         if (key instanceof Integer) {
123             return ((Integer) key).intValue();
124         } else if (key instanceof Character) {
125             return Math.abs(Character.getNumericValue((Character) key) + 1);
126         } else if (key instanceof Short) {
127             return ((Short) key).intValue() + 2;
128         } else if (key instanceof Byte) {
129             return ((Byte) key).intValue() + 3;
130         } else {
131             return -1;
132         }
133     }
134
135     static Collection<Object> getObjects(final int j) {
136         final Collection<Object> results = new ArrayList<>(4);
137         results.add(Integer.valueOf(j));
138         if (j < 2000) {
139             results.add(Character.valueOf((char) j));
140         }
141         if (j < 1000) {
142             results.add(Short.valueOf((short) j));
143         }
144         if (j < 100) {
145             results.add(Byte.valueOf((byte) j));
146         }
147
148         return results;
149     }
150 }