-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
CachedUidGeneratorTest.java
127 lines (108 loc) · 3.65 KB
/
CachedUidGeneratorTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.baidu.fsg.uid;
import com.baidu.fsg.uid.impl.CachedUidGenerator;
import org.apache.commons.lang.StringUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Test for {@link CachedUidGenerator}
*
* @author yutianbao
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:uid/cached-uid-spring.xml" })
public class CachedUidGeneratorTest {
private static final int SIZE = 7000000; // 700w
private static final boolean VERBOSE = false;
private static final int THREADS = Runtime.getRuntime().availableProcessors() << 1;
@Resource
private UidGenerator uidGenerator;
/**
* Test for serially generate
*
* @throws IOException
*/
@Test
public void testSerialGenerate() throws IOException {
// Generate UID serially
Set<Long> uidSet = new HashSet<>(SIZE);
for (int i = 0; i < SIZE; i++) {
doGenerate(uidSet, i);
}
// Check UIDs are all unique
checkUniqueID(uidSet);
}
/**
* Test for parallel generate
*
* @throws InterruptedException
* @throws IOException
*/
@Test
public void testParallelGenerate() throws InterruptedException, IOException {
AtomicInteger control = new AtomicInteger(-1);
Set<Long> uidSet = new ConcurrentSkipListSet<>();
// Initialize threads
List<Thread> threadList = new ArrayList<>(THREADS);
for (int i = 0; i < THREADS; i++) {
Thread thread = new Thread(() -> workerRun(uidSet, control));
thread.setName("UID-generator-" + i);
threadList.add(thread);
thread.start();
}
// Wait for worker done
for (Thread thread : threadList) {
thread.join();
}
// Check generate 700w times
Assert.assertEquals(SIZE, control.get());
// Check UIDs are all unique
checkUniqueID(uidSet);
}
/**
* Woker run
*/
private void workerRun(Set<Long> uidSet, AtomicInteger control) {
for (;;) {
int myPosition = control.updateAndGet(old -> (old == SIZE ? SIZE : old + 1));
if (myPosition == SIZE) {
return;
}
doGenerate(uidSet, myPosition);
}
}
/**
* Do generating
*/
private void doGenerate(Set<Long> uidSet, int index) {
long uid = uidGenerator.getUID();
String parsedInfo = uidGenerator.parseUID(uid);
boolean existed = !uidSet.add(uid);
if (existed) {
System.out.println("Found duplicate UID " + uid);
}
// Check UID is positive, and can be parsed
Assert.assertTrue(uid > 0L);
Assert.assertTrue(StringUtils.isNotBlank(parsedInfo));
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + " No." + index + " >>> " + parsedInfo);
}
}
/**
* Check UIDs are all unique
*/
private void checkUniqueID(Set<Long> uidSet) throws IOException {
System.out.println(uidSet.size());
Assert.assertEquals(SIZE, uidSet.size());
}
}