2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.util
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertFalse
;
23 import java
.io
.IOException
;
24 import java
.util
.ArrayList
;
25 import java
.util
.Collections
;
26 import java
.util
.Iterator
;
27 import java
.util
.List
;
28 import java
.util
.concurrent
.CompletableFuture
;
29 import java
.util
.concurrent
.CompletionException
;
30 import java
.util
.concurrent
.ExecutionException
;
31 import java
.util
.concurrent
.atomic
.AtomicInteger
;
32 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
33 import org
.apache
.hadoop
.hbase
.testclassification
.MiscTests
;
34 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
35 import org
.apache
.hadoop
.hbase
.util
.PoolMap
.PoolType
;
36 import org
.junit
.ClassRule
;
37 import org
.junit
.Test
;
38 import org
.junit
.experimental
.categories
.Category
;
40 @Category({ MiscTests
.class, SmallTests
.class })
41 public class TestRoundRobinPoolMap
extends PoolMapTestBase
{
44 public static final HBaseClassTestRule CLASS_RULE
=
45 HBaseClassTestRule
.forClass(TestRoundRobinPoolMap
.class);
48 protected PoolType
getPoolType() {
49 return PoolType
.RoundRobin
;
53 public void testGetOrCreate() throws IOException
{
55 String value
= "value";
56 String result
= poolMap
.getOrCreate(key
, () -> value
);
58 assertEquals(value
, result
);
59 assertEquals(1, poolMap
.values().size());
63 public void testMultipleKeys() throws IOException
{
64 for (int i
= 0; i
< KEY_COUNT
; i
++) {
65 String key
= Integer
.toString(i
);
66 String value
= Integer
.toString(2 * i
);
67 String result
= poolMap
.getOrCreate(key
, () -> value
);
69 assertEquals(value
, result
);
72 assertEquals(KEY_COUNT
, poolMap
.values().size());
76 public void testMultipleValues() throws IOException
{
79 for (int i
= 0; i
< POOL_SIZE
; i
++) {
80 String value
= Integer
.toString(i
);
81 String result
= poolMap
.getOrCreate(key
, () -> value
);
83 assertEquals(value
, result
);
86 assertEquals(POOL_SIZE
, poolMap
.values().size());
90 public void testRoundRobin() throws IOException
{
93 for (int i
= 0; i
< POOL_SIZE
; i
++) {
94 String value
= Integer
.toString(i
);
95 poolMap
.getOrCreate(key
, () -> value
);
98 assertEquals(POOL_SIZE
, poolMap
.values().size());
100 /* pool is filled, get() should return elements round robin order */
101 for (int i
= 0; i
< 2 * POOL_SIZE
; i
++) {
102 String expected
= Integer
.toString(i
% POOL_SIZE
);
103 assertEquals(expected
, poolMap
.getOrCreate(key
, () -> {
104 throw new IOException("must not call me");
108 assertEquals(POOL_SIZE
, poolMap
.values().size());
112 public void testMultiThreadedRoundRobin() throws ExecutionException
, InterruptedException
{
114 AtomicInteger id
= new AtomicInteger();
115 List
<String
> results
= Collections
.synchronizedList(new ArrayList
<>());
117 Runnable runnable
= () -> {
119 for (int i
= 0; i
< POOL_SIZE
; i
++) {
120 String value
= Integer
.toString(id
.getAndIncrement());
121 String result
= poolMap
.getOrCreate(key
, () -> value
);
126 } catch (IOException e
) {
127 throw new CompletionException(e
);
131 CompletableFuture
<Void
> future1
= CompletableFuture
.runAsync(runnable
);
132 CompletableFuture
<Void
> future2
= CompletableFuture
.runAsync(runnable
);
134 /* test for successful completion */
138 assertEquals(POOL_SIZE
, poolMap
.values().size());
140 /* check every elements occur twice */
141 Collections
.sort(results
);
142 Iterator
<String
> iterator
= results
.iterator();
144 for (int i
= 0; i
< POOL_SIZE
; i
++) {
145 String next1
= iterator
.next();
146 String next2
= iterator
.next();
147 assertEquals(next1
, next2
);
150 assertFalse(iterator
.hasNext());