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;
34 public class TestMultiThreadMapIterator {
35 private static final Logger LOG = LoggerFactory.getLogger(TestMultiThreadMapIterator.class);
36 private static final int NTHREADS = 7;
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)) {
47 LOG.debug("Size of initialized map is {}", bt.size());
50 final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
51 for (int i = 0; i < NTHREADS; i++) {
52 final int threadNo = i;
54 for (Entry<Object, Object> e : bt.entrySet()) {
55 if (accepts(threadNo, NTHREADS, e.getKey())) {
56 String newValue = "TEST:" + threadNo;
64 es.awaitTermination(5, TimeUnit.MINUTES);
68 for (final Map.Entry<Object, Object> kv : bt.entrySet()) {
69 assertTrue(kv.getValue() instanceof String);
72 assertEquals(50000 + 2000 + 1000 + 100, count);
74 final ConcurrentHashMap<Object, Object> removed = new ConcurrentHashMap<>();
76 final ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
77 for (int i = 0; i < NTHREADS; i++) {
78 final int threadNo = i;
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);
88 if (null != bt.get(key)) {
89 LOG.error("Key {} is still present", key);
91 removed.put(key, key);
98 es.awaitTermination(5, TimeUnit.MINUTES);
102 for (final Object value : bt.keySet()) {
106 for (final Object o : bt.keySet()) {
107 if (!removed.contains(bt.get(o))) {
108 LOG.error("Not removed: {}", o);
111 assertEquals(0, count);
112 assertEquals(0, bt.size());
113 assertTrue(bt.isEmpty());
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;
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;
135 static Collection<Object> getObjects(final int j) {
136 final Collection<Object> results = new ArrayList<>(4);
137 results.add(Integer.valueOf(j));
139 results.add(Character.valueOf((char) j));
142 results.add(Short.valueOf((short) j));
145 results.add(Byte.valueOf((byte) j));