mirror of
https://github.com/TotalFreedomMC/TF-PlotSquared.git
synced 2024-12-23 00:15:06 +00:00
Cache both backup profiles and backup objects
This commit is contained in:
parent
d0dbb495b0
commit
2bd30af361
2 changed files with 79 additions and 30 deletions
|
@ -56,42 +56,53 @@ public class PlayerBackupProfile implements BackupProfile {
|
|||
private final Plot plot;
|
||||
private final BackupManager backupManager;
|
||||
|
||||
private volatile List<Backup> backupCache;
|
||||
private final Object backupLock = new Object();
|
||||
|
||||
private static boolean isValidFile(@NotNull final Path path) {
|
||||
final String name = path.getFileName().toString();
|
||||
return name.endsWith(".schem") || name.endsWith(".schematic");
|
||||
}
|
||||
|
||||
@Override @NotNull public CompletableFuture<List<Backup>> listBackups() {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
final Path path = this.getBackupDirectory();
|
||||
if (!Files.exists(path)) {
|
||||
try {
|
||||
Files.createDirectories(path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
synchronized (this.backupLock) {
|
||||
if (this.backupCache != null) {
|
||||
return CompletableFuture.completedFuture(backupCache);
|
||||
}
|
||||
final List<Backup> backups = new ArrayList<>();
|
||||
try {
|
||||
Files.walk(path).filter(PlayerBackupProfile::isValidFile).forEach(file -> {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
final Path path = this.getBackupDirectory();
|
||||
if (!Files.exists(path)) {
|
||||
try {
|
||||
final BasicFileAttributes
|
||||
basicFileAttributes = Files.readAttributes(file, BasicFileAttributes.class);
|
||||
backups.add(new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
|
||||
Files.createDirectories(path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return backups;
|
||||
});
|
||||
}
|
||||
final List<Backup> backups = new ArrayList<>();
|
||||
try {
|
||||
Files.walk(path).filter(PlayerBackupProfile::isValidFile).forEach(file -> {
|
||||
try {
|
||||
final BasicFileAttributes basicFileAttributes =
|
||||
Files.readAttributes(file, BasicFileAttributes.class);
|
||||
backups.add(
|
||||
new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return backups;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void destroy() throws IOException {
|
||||
Files.delete(this.getBackupDirectory());
|
||||
// Invalidate backup cache
|
||||
this.backupCache = null;
|
||||
}
|
||||
|
||||
@NotNull public Path getBackupDirectory() {
|
||||
|
@ -102,14 +113,17 @@ public class PlayerBackupProfile implements BackupProfile {
|
|||
@Override @NotNull public CompletableFuture<Backup> createBackup() {
|
||||
final CompletableFuture<Backup> future = new CompletableFuture<>();
|
||||
this.listBackups().thenAcceptAsync(backups -> {
|
||||
if (backups.size() == backupManager.getBackupLimit()) {
|
||||
backups.get(backups.size() - 1).delete();
|
||||
}
|
||||
final List<Plot> plots = Collections.singletonList(plot);
|
||||
final boolean result = SchematicHandler.manager.exportAll(plots, null, null, () ->
|
||||
future.complete(new Backup(this, System.currentTimeMillis(), null)));
|
||||
if (!result) {
|
||||
future.completeExceptionally(new RuntimeException("Failed to complete the backup"));
|
||||
synchronized (this.backupLock) {
|
||||
if (backups.size() == backupManager.getBackupLimit()) {
|
||||
backups.get(backups.size() - 1).delete();
|
||||
}
|
||||
final List<Plot> plots = Collections.singletonList(plot);
|
||||
final boolean result = SchematicHandler.manager.exportAll(plots, null, null, () ->
|
||||
future.complete(new Backup(this, System.currentTimeMillis(), null)));
|
||||
if (!result) {
|
||||
future.completeExceptionally(new RuntimeException("Failed to complete the backup"));
|
||||
}
|
||||
this.backupCache = null;
|
||||
}
|
||||
});
|
||||
return future;
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
*/
|
||||
package com.plotsquared.core.backup;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.configuration.Settings;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -36,6 +39,8 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
|
@ -45,6 +50,8 @@ import java.util.concurrent.CompletableFuture;
|
|||
@Getter private final Path backupPath;
|
||||
private final boolean automaticBackup;
|
||||
@Getter private final int backupLimit;
|
||||
private final Cache<PlotCacheKey, BackupProfile> backupProfileCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(3, TimeUnit.MINUTES).build();
|
||||
|
||||
public SimpleBackupManager() throws Exception {
|
||||
this.backupPath = Objects.requireNonNull(PlotSquared.imp()).getDirectory().toPath().resolve("backups");
|
||||
|
@ -57,7 +64,13 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
@Override @NotNull public BackupProfile getProfile(@NotNull final Plot plot) {
|
||||
if (plot.hasOwner() && !plot.isMerged()) {
|
||||
return new PlayerBackupProfile(plot.getOwnerAbs(), plot, this);
|
||||
try {
|
||||
return backupProfileCache.get(new PlotCacheKey(plot), () -> new PlayerBackupProfile(plot.getOwnerAbs(), plot, this));
|
||||
} catch (ExecutionException e) {
|
||||
final BackupProfile profile = new PlayerBackupProfile(plot.getOwnerAbs(), plot, this);
|
||||
this.backupProfileCache.put(new PlotCacheKey(plot), profile);
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
return new NullBackupProfile();
|
||||
}
|
||||
|
@ -74,4 +87,26 @@ import java.util.concurrent.CompletableFuture;
|
|||
return this.automaticBackup;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE) private static final class PlotCacheKey {
|
||||
|
||||
private final Plot plot;
|
||||
|
||||
@Override public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final PlotCacheKey that = (PlotCacheKey) o;
|
||||
return com.google.common.base.Objects.equal(plot.getArea(), that.plot.getArea())
|
||||
&& com.google.common.base.Objects.equal(plot.getId(), that.plot.getId())
|
||||
&& com.google.common.base.Objects.equal(plot.getOwnerAbs(), that.plot.getOwnerAbs());
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return com.google.common.base.Objects.hashCode(plot.getArea(), plot.getId(), plot.getOwnerAbs());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue