update CacheRepository

This commit is contained in:
Glavo 2025-08-01 20:02:50 +08:00
parent b8ecbbc1cb
commit f54a9e9ad1

View File

@ -52,7 +52,7 @@ public class CacheRepository {
private Path cacheDirectory; private Path cacheDirectory;
private Path indexFile; private Path indexFile;
private FileTime indexFileLastModified; private FileTime indexFileLastModified;
private Map<URI, ETagItem> index; private LinkedHashMap<URI, ETagItem> index;
private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void changeDirectory(Path commonDir) { public void changeDirectory(Path commonDir) {
@ -63,20 +63,23 @@ 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)); try (FileChannel channel = FileChannel.open(indexFile, StandardOpenOption.READ);
ETagIndex raw = JsonUtils.fromJsonFile(indexFile, ETagIndex.class); @SuppressWarnings("unused") FileLock lock = channel.tryLock(0, Long.MAX_VALUE, true)) {
index = raw != null ? joinETagIndexes(raw.eTag) : new LinkedHashMap<>(); FileTime lastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile));
indexFileLastModified = lastModified; ETagIndex raw = JsonUtils.GSON.fromJson(new BufferedReader(Channels.newReader(channel, UTF_8)), ETagIndex.class);
index = raw != null ? joinETagIndexes(raw.eTag) : new LinkedHashMap<>();
indexFileLastModified = lastModified;
}
} else { } else {
index = new LinkedHashMap<>(); index = new LinkedHashMap<>();
} }
} 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 LinkedHashMap<>(); index = new LinkedHashMap<>();
indexFileLastModified = null;
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
} }
} }
public Path getCommonDirectory() { public Path getCommonDirectory() {
@ -267,8 +270,8 @@ public class CacheRepository {
} }
@SafeVarargs @SafeVarargs
private Map<URI, ETagItem> joinETagIndexes(Collection<ETagItem>... indexes) { private LinkedHashMap<URI, ETagItem> joinETagIndexes(Collection<ETagItem>... indexes) {
Map<URI, ETagItem> eTags = new LinkedHashMap<>(); var eTags = new LinkedHashMap<URI, ETagItem>();
for (Collection<ETagItem> eTagItems : indexes) { for (Collection<ETagItem> eTagItems : indexes) {
if (eTagItems != null) { if (eTagItems != null) {
for (ETagItem eTag : eTagItems) { for (ETagItem eTag : eTagItems) {
@ -281,23 +284,25 @@ 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()) { @SuppressWarnings("unused") FileLock lock = channel.lock()) {
FileTime lastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile)); FileTime lastModified = Lang.ignoringException(() -> Files.getLastModifiedTime(indexFile));
if (indexFileLastModified == null || lastModified == null || indexFileLastModified.compareTo(lastModified) < 0) { if (indexFileLastModified == null || lastModified == null || indexFileLastModified.compareTo(lastModified) < 0) {
try { try {
ETagIndex indexOnDisk = GSON.fromJson( ETagIndex indexOnDisk = GSON.fromJson(
// Should not be closed // Should not be closed
new BufferedReader(new InputStreamReader(Channels.newInputStream(channel))), new BufferedReader(Channels.newReader(channel, UTF_8)),
ETagIndex.class ETagIndex.class
); );
if (indexOnDisk != null) if (indexOnDisk != null) {
index = joinETagIndexes(index.values(), indexOnDisk.eTag); index = joinETagIndexes(index.values(), indexOnDisk.eTag);
indexFileLastModified = lastModified;
}
} catch (JsonSyntaxException ignored) { } catch (JsonSyntaxException ignored) {
} }
} }
channel.truncate(0); channel.truncate(0);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Channels.newOutputStream(channel), UTF_8)); BufferedWriter writer = new BufferedWriter(Channels.newWriter(channel, UTF_8));
JsonUtils.GSON.toJson(new ETagIndex(index.values()), writer); JsonUtils.GSON.toJson(new ETagIndex(index.values()), writer);
writer.flush(); writer.flush();
channel.force(true); channel.force(true);