|
12 | 12 |
|
13 | 13 | import static java.util.Collections.emptyList;
|
14 | 14 | import static java.util.Collections.singletonList;
|
15 |
| -import static java.util.Comparator.comparing; |
16 |
| -import static java.util.Comparator.naturalOrder; |
17 | 15 | import static java.util.stream.Collectors.groupingBy;
|
18 | 16 | import static java.util.stream.Collectors.toList;
|
19 | 17 | import static org.junit.platform.commons.util.CollectionUtils.getOnlyElement;
|
20 |
| -import static org.junit.platform.engine.support.hierarchical.ExclusiveResource.GLOBAL_KEY; |
| 18 | +import static org.junit.platform.commons.util.CollectionUtils.toUnmodifiableList; |
21 | 19 | import static org.junit.platform.engine.support.hierarchical.ExclusiveResource.GLOBAL_READ;
|
22 | 20 | import static org.junit.platform.engine.support.hierarchical.ExclusiveResource.GLOBAL_READ_WRITE;
|
23 | 21 | import static org.junit.platform.engine.support.hierarchical.ExclusiveResource.LockMode.READ;
|
24 | 22 |
|
25 | 23 | import java.util.Collection;
|
26 |
| -import java.util.Comparator; |
27 | 24 | import java.util.LinkedHashMap;
|
28 | 25 | import java.util.List;
|
29 | 26 | import java.util.Map;
|
|
32 | 29 | import java.util.concurrent.locks.ReadWriteLock;
|
33 | 30 | import java.util.concurrent.locks.ReentrantReadWriteLock;
|
34 | 31 |
|
35 |
| -import org.junit.platform.engine.support.hierarchical.SingleLock.GlobalReadLock; |
36 |
| -import org.junit.platform.engine.support.hierarchical.SingleLock.GlobalReadWriteLock; |
37 |
| - |
38 | 32 | /**
|
39 | 33 | * @since 1.3
|
40 | 34 | */
|
41 | 35 | class LockManager {
|
42 | 36 |
|
43 |
| - private static final Comparator<ExclusiveResource> COMPARATOR // |
44 |
| - = comparing(ExclusiveResource::getKey, globalKeyFirst().thenComparing(naturalOrder())) // |
45 |
| - .thenComparing(ExclusiveResource::getLockMode); |
46 |
| - |
47 |
| - private static Comparator<String> globalKeyFirst() { |
48 |
| - return comparing(key -> !GLOBAL_KEY.equals(key)); |
49 |
| - } |
50 |
| - |
51 | 37 | private final Map<String, ReadWriteLock> locksByKey = new ConcurrentHashMap<>();
|
52 |
| - private final GlobalReadLock globalReadLock; |
53 |
| - private final GlobalReadWriteLock globalReadWriteLock; |
| 38 | + private final SingleLock globalReadLock; |
| 39 | + private final SingleLock globalReadWriteLock; |
54 | 40 |
|
55 | 41 | public LockManager() {
|
56 |
| - globalReadLock = new GlobalReadLock(toLock(GLOBAL_READ)); |
57 |
| - globalReadWriteLock = new GlobalReadWriteLock(toLock(GLOBAL_READ_WRITE)); |
| 42 | + globalReadLock = new SingleLock(GLOBAL_READ, toLock(GLOBAL_READ)); |
| 43 | + globalReadWriteLock = new SingleLock(GLOBAL_READ_WRITE, toLock(GLOBAL_READ_WRITE)); |
58 | 44 | }
|
59 | 45 |
|
60 | 46 | ResourceLock getLockForResources(Collection<ExclusiveResource> resources) {
|
61 |
| - return toResourceLock(toDistinctSortedLocks(resources)); |
| 47 | + return toResourceLock(toDistinctSortedResources(resources)); |
62 | 48 | }
|
63 | 49 |
|
64 | 50 | ResourceLock getLockForResource(ExclusiveResource resource) {
|
65 |
| - return toResourceLock(toLock(resource)); |
| 51 | + return toResourceLock(singletonList(resource)); |
66 | 52 | }
|
67 | 53 |
|
68 |
| - private List<Lock> toDistinctSortedLocks(Collection<ExclusiveResource> resources) { |
| 54 | + private List<ExclusiveResource> toDistinctSortedResources(Collection<ExclusiveResource> resources) { |
69 | 55 | if (resources.isEmpty()) {
|
70 | 56 | return emptyList();
|
71 | 57 | }
|
72 | 58 | if (resources.size() == 1) {
|
73 |
| - return singletonList(toLock(getOnlyElement(resources))); |
| 59 | + return singletonList(getOnlyElement(resources)); |
74 | 60 | }
|
75 | 61 | // @formatter:off
|
76 | 62 | Map<String, List<ExclusiveResource>> resourcesByKey = resources.stream()
|
77 |
| - .sorted(COMPARATOR) |
| 63 | + .sorted(ExclusiveResource.COMPARATOR) |
78 | 64 | .distinct()
|
79 | 65 | .collect(groupingBy(ExclusiveResource::getKey, LinkedHashMap::new, toList()));
|
80 | 66 |
|
81 | 67 | return resourcesByKey.values().stream()
|
82 | 68 | .map(resourcesWithSameKey -> resourcesWithSameKey.get(0))
|
83 |
| - .map(this::toLock) |
84 |
| - .collect(toList()); |
| 69 | + .collect(toUnmodifiableList()); |
85 | 70 | // @formatter:on
|
86 | 71 | }
|
87 | 72 |
|
88 |
| - private Lock toLock(ExclusiveResource resource) { |
89 |
| - ReadWriteLock lock = this.locksByKey.computeIfAbsent(resource.getKey(), key -> new ReentrantReadWriteLock()); |
90 |
| - return resource.getLockMode() == READ ? lock.readLock() : lock.writeLock(); |
91 |
| - } |
92 |
| - |
93 |
| - private ResourceLock toResourceLock(List<Lock> locks) { |
94 |
| - switch (locks.size()) { |
| 73 | + private ResourceLock toResourceLock(List<ExclusiveResource> resources) { |
| 74 | + switch (resources.size()) { |
95 | 75 | case 0:
|
96 | 76 | return NopLock.INSTANCE;
|
97 | 77 | case 1:
|
98 |
| - return toResourceLock(locks.get(0)); |
| 78 | + return toSingleLock(getOnlyElement(resources)); |
99 | 79 | default:
|
100 |
| - return new CompositeLock(locks); |
| 80 | + return new CompositeLock(resources, toLocks(resources)); |
101 | 81 | }
|
102 | 82 | }
|
103 | 83 |
|
104 |
| - private ResourceLock toResourceLock(Lock lock) { |
105 |
| - if (lock == toLock(GLOBAL_READ)) { |
| 84 | + private SingleLock toSingleLock(ExclusiveResource resource) { |
| 85 | + if (GLOBAL_READ.equals(resource)) { |
106 | 86 | return globalReadLock;
|
107 | 87 | }
|
108 |
| - if (lock == toLock(GLOBAL_READ_WRITE)) { |
| 88 | + if (GLOBAL_READ_WRITE.equals(resource)) { |
109 | 89 | return globalReadWriteLock;
|
110 | 90 | }
|
111 |
| - return new SingleLock(lock); |
| 91 | + return new SingleLock(resource, toLock(resource)); |
| 92 | + } |
| 93 | + |
| 94 | + private List<Lock> toLocks(List<ExclusiveResource> resources) { |
| 95 | + return resources.stream().map(this::toLock).collect(toUnmodifiableList()); |
| 96 | + } |
| 97 | + |
| 98 | + private Lock toLock(ExclusiveResource resource) { |
| 99 | + ReadWriteLock lock = this.locksByKey.computeIfAbsent(resource.getKey(), key -> new ReentrantReadWriteLock()); |
| 100 | + return resource.getLockMode() == READ ? lock.readLock() : lock.writeLock(); |
112 | 101 | }
|
113 | 102 |
|
114 | 103 | }
|
0 commit comments