update CacheRepository

This commit is contained in:
Glavo 2025-08-01 19:44:54 +08:00
parent f6711aeec9
commit b8ecbbc1cb

View File

@ -35,6 +35,7 @@ import java.nio.channels.FileLock;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileTime;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
@ -50,6 +51,7 @@ public class CacheRepository {
private Path commonDirectory; private Path commonDirectory;
private Path cacheDirectory; private Path cacheDirectory;
private Path indexFile; private Path indexFile;
private FileTime indexFileLastModified;
private Map<URI, ETagItem> index; private Map<URI, ETagItem> index;
private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final ReadWriteLock lock = new ReentrantReadWriteLock();
@ -61,16 +63,16 @@ public class CacheRepository {
lock.writeLock().lock(); lock.writeLock().lock();
try { try {
if (Files.isRegularFile(indexFile)) { if (Files.isRegularFile(indexFile)) {
FileTime lastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile));
ETagIndex raw = JsonUtils.fromJsonFile(indexFile, ETagIndex.class); ETagIndex raw = JsonUtils.fromJsonFile(indexFile, ETagIndex.class);
if (raw == null) index = raw != null ? joinETagIndexes(raw.eTag) : new LinkedHashMap<>();
index = new HashMap<>(); indexFileLastModified = lastModified;
else } else {
index = joinETagIndexes(raw.eTag); index = new LinkedHashMap<>();
} else }
index = new HashMap<>();
} catch (IOException | JsonParseException e) { } catch (IOException | JsonParseException e) {
LOG.warning("Unable to read index file", e); LOG.warning("Unable to read index file", e);
index = new HashMap<>(); index = new LinkedHashMap<>();
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
} }
@ -278,29 +280,29 @@ public class CacheRepository {
} }
public void saveETagIndex() throws IOException { public void saveETagIndex() throws IOException {
try (FileChannel channel = FileChannel.open(indexFile, StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE)) { try (FileChannel channel = FileChannel.open(indexFile, StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE);
FileLock lock = channel.lock(); FileLock lock = channel.lock()) {
try { FileTime lastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile));
ETagIndex indexOnDisk; if (indexFileLastModified == null || lastModified == null || indexFileLastModified.compareTo(lastModified) < 0) {
try { try {
indexOnDisk = GSON.fromJson( ETagIndex indexOnDisk = GSON.fromJson(
// Should not be closed // Should not be closed
new BufferedReader(new InputStreamReader(Channels.newInputStream(channel))), new BufferedReader(new InputStreamReader(Channels.newInputStream(channel))),
ETagIndex.class ETagIndex.class
); );
} catch (JsonSyntaxException e) { if (indexOnDisk != null)
indexOnDisk = null; index = joinETagIndexes(index.values(), indexOnDisk.eTag);
} catch (JsonSyntaxException ignored) {
} }
Map<URI, ETagItem> newIndex = joinETagIndexes(index.values(), indexOnDisk == null ? null : indexOnDisk.eTag);
channel.truncate(0);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Channels.newOutputStream(channel), UTF_8));
JsonUtils.GSON.toJson(new ETagIndex(newIndex.values()), writer);
writer.flush();
this.index = newIndex;
} finally {
lock.release();
} }
channel.truncate(0);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Channels.newOutputStream(channel), UTF_8));
JsonUtils.GSON.toJson(new ETagIndex(index.values()), writer);
writer.flush();
channel.force(true);
this.indexFileLastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile));
} }
} }