1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.linecorp.centraldogma.server.internal.storage.repository.cache;
18
19 import static com.google.common.base.MoreObjects.firstNonNull;
20 import static com.linecorp.centraldogma.server.internal.storage.repository.RepositoryCache.logger;
21 import static java.util.Objects.requireNonNull;
22
23 import java.util.Objects;
24 import java.util.concurrent.CompletableFuture;
25
26 import com.google.common.base.MoreObjects.ToStringHelper;
27
28 import com.linecorp.armeria.common.util.Exceptions;
29 import com.linecorp.centraldogma.common.EntryNotFoundException;
30 import com.linecorp.centraldogma.common.Revision;
31 import com.linecorp.centraldogma.server.storage.repository.AbstractCacheableCall;
32 import com.linecorp.centraldogma.server.storage.repository.Repository;
33
34 final class CacheableFindLatestRevCall extends AbstractCacheableCall<Revision> {
35
36 static final Revision EMPTY = new Revision(Integer.MIN_VALUE);
37 static final Revision ENTRY_NOT_FOUND = new Revision(Integer.MIN_VALUE);
38
39 private final Revision lastKnownRevision;
40 private final Revision headRevision;
41 private final String pathPattern;
42 private final boolean errorOnEntryNotFound;
43 private final int hashCode;
44
45 CacheableFindLatestRevCall(Repository repo, Revision lastKnownRevision, Revision headRevision,
46 String pathPattern, boolean errorOnEntryNotFound) {
47 super(repo);
48
49 this.lastKnownRevision = requireNonNull(lastKnownRevision, "lastKnownRevision");
50 this.headRevision = requireNonNull(headRevision, "headRevision");
51 this.pathPattern = requireNonNull(pathPattern, "pathPattern");
52 this.errorOnEntryNotFound = errorOnEntryNotFound;
53
54 hashCode = Objects.hash(lastKnownRevision, headRevision, pathPattern, errorOnEntryNotFound) +
55 System.identityHashCode(repo);
56
57 assert !lastKnownRevision.isRelative();
58 }
59
60 @Override
61 public int weigh(Revision value) {
62 return pathPattern.length();
63 }
64
65 @Override
66 public CompletableFuture<Revision> execute() {
67 logger.debug("Cache miss: {}", this);
68 return repo().findLatestRevision(lastKnownRevision, pathPattern, errorOnEntryNotFound)
69 .handle((revision, cause) -> {
70 if (cause != null) {
71 cause = Exceptions.peel(cause);
72 if (cause instanceof EntryNotFoundException) {
73 return ENTRY_NOT_FOUND;
74 }
75 return Exceptions.throwUnsafely(cause);
76 }
77 return firstNonNull(revision, EMPTY);
78 });
79 }
80
81 @Override
82 public int hashCode() {
83 return hashCode;
84 }
85
86 @Override
87 public boolean equals(Object o) {
88 if (!super.equals(o)) {
89 return false;
90 }
91
92 final CacheableFindLatestRevCall that = (CacheableFindLatestRevCall) o;
93 return lastKnownRevision.equals(that.lastKnownRevision) &&
94 headRevision.equals(that.headRevision) &&
95 pathPattern.equals(that.pathPattern) &&
96 errorOnEntryNotFound == that.errorOnEntryNotFound;
97 }
98
99 @Override
100 protected void toString(ToStringHelper helper) {
101 helper.add("lastKnownRevision", lastKnownRevision)
102 .add("headRevision", headRevision)
103 .add("pathPattern", pathPattern)
104 .add("errorOnEntryNotFound", errorOnEntryNotFound);
105 }
106 }