]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.acr/src/org/argeo/api/acr/uuid/AbstractAsyncUuidFactory.java
Experiment with package level A2 metadata
[lgpl/argeo-commons.git] / org.argeo.api.acr / src / org / argeo / api / acr / uuid / AbstractAsyncUuidFactory.java
1 package org.argeo.api.acr.uuid;
2
3 import java.security.SecureRandom;
4 import java.util.UUID;
5 import java.util.concurrent.Callable;
6 import java.util.concurrent.CompletableFuture;
7 import java.util.concurrent.CompletionStage;
8 import java.util.concurrent.ForkJoinPool;
9 import java.util.concurrent.ForkJoinTask;
10 import java.util.concurrent.ThreadLocalRandom;
11
12 /**
13 * Execute {@link UUID} creations in {@link ForkJoinPool#commonPool()}. The goal
14 * is to provide good performance while staying within the parallelism defined
15 * for the system, so as to overwhelm it if many UUIDs are requested.
16 * Additionally, with regard to time based UUIDs, since we use
17 * {@link ConcurrentTimeUuidState}, which maintains one "clock sequence" per
18 * thread, we want to limit the number of threads accessing the actual
19 * generation method.
20 */
21 public abstract class AbstractAsyncUuidFactory extends AbstractUuidFactory implements AsyncUuidFactory {
22 private SecureRandom secureRandom;
23 protected TimeUuidState timeUuidState;
24
25 public AbstractAsyncUuidFactory() {
26 secureRandom = newSecureRandom();
27 timeUuidState = new ConcurrentTimeUuidState(secureRandom, null);
28 }
29 /*
30 * ABSTRACT METHODS
31 */
32
33 protected abstract UUID newTimeUUID();
34
35 protected abstract UUID newTimeUUIDwithMacAddress();
36
37 protected abstract SecureRandom newSecureRandom();
38
39 /*
40 * SYNC OPERATIONS
41 */
42 protected UUID newRandomUUIDStrong() {
43 return newRandomUUID(secureRandom);
44 }
45
46 public UUID randomUUIDWeak() {
47 return newRandomUUID(ThreadLocalRandom.current());
48 }
49
50 /*
51 * ASYNC OPERATIONS (heavy)
52 */
53 protected CompletionStage<UUID> request(ForkJoinTask<UUID> newUuid) {
54 return CompletableFuture.supplyAsync(newUuid::invoke).minimalCompletionStage();
55 }
56
57 @Override
58 public CompletionStage<UUID> requestNameUUIDv5(UUID namespace, byte[] data) {
59 return request(futureNameUUIDv5(namespace, data));
60 }
61
62 @Override
63 public CompletionStage<UUID> requestNameUUIDv3(UUID namespace, byte[] data) {
64 return request(futureNameUUIDv3(namespace, data));
65 }
66
67 @Override
68 public CompletionStage<UUID> requestRandomUUIDStrong() {
69 return request(futureRandomUUIDStrong());
70 }
71
72 @Override
73 public CompletionStage<UUID> requestTimeUUID() {
74 return request(futureTimeUUID());
75 }
76
77 @Override
78 public CompletionStage<UUID> requestTimeUUIDwithMacAddress() {
79 return request(futureTimeUUIDwithMacAddress());
80 }
81
82 /*
83 * ASYNC OPERATIONS (light)
84 */
85 protected ForkJoinTask<UUID> submit(Callable<UUID> newUuid) {
86 return ForkJoinTask.adapt(newUuid);
87 }
88
89 @Override
90 public ForkJoinTask<UUID> futureNameUUIDv5(UUID namespace, byte[] data) {
91 return submit(() -> newNameUUIDv5(namespace, data));
92 }
93
94 @Override
95 public ForkJoinTask<UUID> futureNameUUIDv3(UUID namespace, byte[] data) {
96 return submit(() -> newNameUUIDv3(namespace, data));
97 }
98
99 @Override
100 public ForkJoinTask<UUID> futureRandomUUIDStrong() {
101 return submit(this::newRandomUUIDStrong);
102 }
103
104 @Override
105 public ForkJoinTask<UUID> futureTimeUUID() {
106 return submit(this::newTimeUUID);
107 }
108
109 @Override
110 public ForkJoinTask<UUID> futureTimeUUIDwithMacAddress() {
111 return submit(this::newTimeUUIDwithMacAddress);
112 }
113
114 // @Override
115 // public UUID timeUUID() {
116 // if (ConcurrentTimeUuidState.isTimeUuidThread.get())
117 // return newTimeUUID();
118 // else
119 // return futureTimeUUID().join();
120 // }
121 //
122 // @Override
123 // public UUID timeUUIDwithMacAddress() {
124 // if (ConcurrentTimeUuidState.isTimeUuidThread.get())
125 // return newTimeUUIDwithMacAddress();
126 // else
127 // return futureTimeUUIDwithMacAddress().join();
128 // }
129
130 }