2 * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.opendaylight.yangtools.triemap;
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
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;
35 public class TestMultiThreadMapIterator {
36 private static final Logger LOG = LoggerFactory.getLogger(TestMultiThreadMapIterator.class);
37 private static final int NTHREADS = 7;
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)) {
48 LOG.debug("Size of initialized map is {}", bt.size());
51 final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
52 for (int i = 0; i < NTHREADS; i++) {
53 final int threadNo = i;
55 for (Entry<Object, Object> e : bt.entrySet()) {
56 if (accepts(threadNo, NTHREADS, e.getKey())) {
57 String newValue = "TEST:" + threadNo;
65 es.awaitTermination(5, TimeUnit.MINUTES);
69 for (final Map.Entry<Object, Object> kv : bt.entrySet()) {
70 assertTrue(kv.getValue() instanceof String);
73 assertEquals(50000 + 2000 + 1000 + 100, count);
75 final ConcurrentHashMap<Object, Object> removed = new ConcurrentHashMap<>();
77 final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
78 for (int i = 0; i < NTHREADS; i++) {
79 final int threadNo = i;
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);
89 if (null != bt.get(key)) {
90 LOG.error("Key {} is still present", key);
92 removed.put(key, key);
99 es.awaitTermination(5, TimeUnit.MINUTES);
103 for (final Object value : bt.keySet()) {
107 for (final Object o : bt.keySet()) {
108 if (!removed.contains(bt.get(o))) {
109 LOG.error("Not removed: {}", o);
112 assertEquals(0, count);
113 assertEquals(0, bt.size());
114 assertTrue(bt.isEmpty());
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;
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;
136 static Collection<Object> getObjects(final int j) {
137 final Collection<Object> results = new ArrayList<>(4);
138 results.add(Integer.valueOf(j));
140 results.add(Character.valueOf((char) j));
143 results.add(Short.valueOf((short) j));
146 results.add(Byte.valueOf((byte) j));