1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Ticker.systemTicker;
4 import static java.util.concurrent.TimeUnit.NANOSECONDS;
6 import java.util.concurrent.atomic.AtomicInteger;
8 import net.pterodactylus.sone.data.Sone;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Objects;
12 import com.google.common.base.Ticker;
15 * Class that detects {@link Sone} modifications (as per their {@link
16 * Sone#getFingerprint() fingerprints} and determines when a modified Sone may
19 class SoneModificationDetector {
21 private final Ticker ticker;
22 private final LockableFingerprintProvider lockableFingerprintProvider;
23 private final AtomicInteger insertionDelay;
24 private Long lastModificationTime;
25 private String lastInsertFingerprint;
26 private String lastCheckFingerprint;
28 SoneModificationDetector(LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
29 this(systemTicker(), lockableFingerprintProvider, insertionDelay);
33 SoneModificationDetector(Ticker ticker, LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
35 this.lockableFingerprintProvider = lockableFingerprintProvider;
36 this.insertionDelay = insertionDelay;
37 lastCheckFingerprint = lastInsertFingerprint;
40 public boolean isEligibleForInsert() {
41 if (lockableFingerprintProvider.isLocked()) {
42 lastModificationTime = null;
43 lastCheckFingerprint = "";
46 String fingerprint = lockableFingerprintProvider.getFingerprint();
47 if (fingerprint.equals(lastInsertFingerprint)) {
48 lastModificationTime = null;
49 lastCheckFingerprint = fingerprint;
52 if (!Objects.equal(lastCheckFingerprint, fingerprint)) {
53 lastModificationTime = ticker.read();
54 lastCheckFingerprint = fingerprint;
57 return insertionDelayHasPassed();
60 public String getLastInsertFingerprint() {
61 return lastInsertFingerprint;
64 public void setFingerprint(String fingerprint) {
65 lastInsertFingerprint = fingerprint;
66 lastCheckFingerprint = lastInsertFingerprint;
67 lastModificationTime = null;
70 private boolean insertionDelayHasPassed() {
71 return NANOSECONDS.toSeconds(ticker.read() - lastModificationTime) >= insertionDelay.get();
74 public boolean isModified() {
75 return !Objects.equal(lockableFingerprintProvider.getFingerprint(), lastInsertFingerprint);
79 * Provider for a fingerprint and the information if a {@link Sone} is locked. This
80 * prevents us from having to lug a Sone object around.
82 static interface LockableFingerprintProvider {
85 String getFingerprint();