BUG-7464: Apply copyright headers
[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 java.util.Collection;
19 import java.util.Iterator;
20 import java.util.LinkedList;
21 import java.util.Map;
22 import java.util.Map.Entry;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ExecutorService;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.TimeUnit;
27 import org.junit.Test;
28
29 public class TestMultiThreadMapIterator {
30     private static final int NTHREADS = 7;
31
32     @Test
33     public void testMultiThreadMapIterator () {
34         final Map<Object, Object> bt = new TrieMap<> ();
35         for (int j = 0; j < 50 * 1000; j++) {
36             final Object[] objects = getObjects (j);
37             for (final Object o : objects) {
38                 bt.put (o, o);
39             }
40         }
41
42       System.out.println ("Size of initialized map is " + bt.size ());
43       int count = 0;
44         {
45             final ExecutorService es = Executors.newFixedThreadPool (NTHREADS);
46             for (int i = 0; i < NTHREADS; i++) {
47                 final int threadNo = i;
48                 es.execute (new Runnable () {
49                     @Override
50                     public void run () {
51                         for (Entry<Object, Object> e : bt.entrySet ()) {
52                             if (accepts (threadNo, NTHREADS, e.getKey ())) {
53                                 String newValue = "TEST:" + threadNo;
54                                 e.setValue (newValue);
55                             }
56                         }
57                     }
58                 });
59             }
60
61             es.shutdown ();
62             try {
63                 es.awaitTermination (3600L, TimeUnit.SECONDS);
64             } catch (final InterruptedException e) {
65                 e.printStackTrace ();
66             }
67         }
68
69         count = 0;
70         for (final Map.Entry<Object, Object> kv : bt.entrySet ()) {
71             Object value = kv.getValue ();
72             TestHelper.assertTrue (value instanceof String);
73             count++;
74         }
75         TestHelper.assertEquals (50000 + 2000 + 1000 + 100, count);
76
77         final ConcurrentHashMap<Object, Object> removed = new ConcurrentHashMap<> ();
78
79         {
80             final ExecutorService es = Executors.newFixedThreadPool (NTHREADS);
81             for (int i = 0; i < NTHREADS; i++) {
82                 final int threadNo = i;
83                 es.execute (new Runnable () {
84                     @Override
85                     public void run () {
86                         for (final Iterator<Map.Entry<Object, Object>> i = bt.entrySet ().iterator (); i.hasNext ();) {
87                             final Entry<Object, Object> e = i.next ();
88                             Object key = e.getKey ();
89                             if (accepts (threadNo, NTHREADS, key)) {
90                                 if (null == bt.get (key)) {
91                                     System.out.println (key);
92                                 }
93                                 i.remove ();
94                                 if (null != bt.get (key)) {
95                                     System.out.println (key);
96                                 }
97                                 removed.put (key, key);
98                             }
99                         }
100                     }
101                 });
102             }
103
104             es.shutdown ();
105             try {
106                 es.awaitTermination (3600L, TimeUnit.SECONDS);
107             } catch (final InterruptedException e) {
108                 e.printStackTrace ();
109             }
110         }
111
112         count = 0;
113         for (final Object value : bt.keySet ()) {
114             value.toString ();
115             count++;
116         }
117         for (final Object o : bt.keySet ()) {
118             if (!removed.contains (bt.get (o))) {
119                 System.out.println ("Not removed: " + o);
120             }
121         }
122         TestHelper.assertEquals (0, count);
123         TestHelper.assertEquals (0, bt.size ());
124         TestHelper.assertTrue (bt.isEmpty ());
125     }
126
127     protected static boolean accepts (final int threadNo, final int nThreads, final Object key) {
128         int val = getKeyValue (key);
129         if(val>=0) {
130             return val % nThreads == threadNo;
131         } else {
132             return false;
133         }
134     }
135
136     private static int getKeyValue (final Object key) {
137         int val = 0;
138         if (key instanceof Integer) {
139             val = ((Integer) key).intValue ();
140         }
141         else if (key instanceof Character) {
142             val = Math.abs (Character.getNumericValue ((Character) key) + 1);
143         }
144         else if (key instanceof Short) {
145             val = ((Short) key).intValue () + 2;
146         }
147         else if (key instanceof Byte) {
148             val = ((Byte) key).intValue () + 3;
149         } else {
150             return -1;
151         }
152         return val;
153     }
154
155     static Object[] getObjects (final int j) {
156         final Collection<Object> results = new LinkedList<> ();
157         results.add (Integer.valueOf (j));
158         if (j < 2000) {
159             results.add (Character.valueOf ((char) j));
160         }
161         if (j < 1000) {
162             results.add (Short.valueOf ((short) j));
163         }
164         if (j < 100) {
165             results.add (Byte.valueOf ((byte) j));
166         }
167
168         return results.toArray ();
169     }
170 }