1 package com.atlassian.vcache.internal.core;
2
3 import com.atlassian.marshalling.api.MarshallingException;
4 import com.atlassian.marshalling.api.MarshallingPair;
5 import com.atlassian.vcache.ExternalCacheException;
6
7 import javax.annotation.Nullable;
8 import java.time.Duration;
9 import java.util.Optional;
10 import java.util.concurrent.CompletableFuture;
11 import java.util.concurrent.CompletionStage;
12 import java.util.function.LongConsumer;
13
14 import static com.atlassian.vcache.ExternalCacheException.Reason.MARSHALLER_FAILURE;
15 import static java.util.Objects.requireNonNull;
16
17
18
19
20
21
22 public class VCacheCoreUtils {
23
24
25
26
27
28
29
30 public static <T> CompletionStage<T> successful(T value) {
31 final CompletableFuture<T> result = new CompletableFuture<>();
32 result.complete(value);
33 return result;
34 }
35
36
37
38
39
40
41
42
43
44
45 public static <T> CompletionStage<T> failed(CompletionStage<T> result, Throwable cause) {
46 result.toCompletableFuture().completeExceptionally(cause);
47 return result;
48 }
49
50 public static int roundUpToSeconds(Duration time) {
51 if (time.isNegative()) {
52 throw new IllegalArgumentException("duration cannot be negative: " + time);
53 }
54
55 final long result = (time.getNano() > 0) ? time.getSeconds() + 1 : time.getSeconds();
56
57 if (result > Integer.MAX_VALUE) {
58 throw new IllegalArgumentException("duration exceeds maximum number that can be held in an int");
59 }
60
61 return (int) result;
62 }
63
64 public static void whenPositive(long number, LongConsumer handler) {
65 if (number > 0) {
66 handler.accept(number);
67 }
68 }
69
70 public static <V> byte[] marshall(V data, MarshallingPair<V> valueMarshalling) throws ExternalCacheException {
71 try {
72 return valueMarshalling.getMarshaller().marshallToBytes(requireNonNull(data));
73 } catch (MarshallingException e) {
74 throw new ExternalCacheException(MARSHALLER_FAILURE, e);
75 }
76 }
77
78 public static <V> Optional<V> unmarshall(@Nullable byte[] data, MarshallingPair<V> valueMarshalling) throws ExternalCacheException {
79 if (data == null) {
80 return Optional.empty();
81 }
82
83 try {
84 return Optional.of(valueMarshalling.getUnmarshaller().unmarshallFrom(data));
85 } catch (MarshallingException ex) {
86 throw new ExternalCacheException(MARSHALLER_FAILURE, ex);
87 }
88 }
89
90 public static <K> boolean isEmpty(Iterable<K> iter) {
91 return !iter.iterator().hasNext();
92 }
93 }