From 9329d25fa9158f47485d6895ee3293dc7571e603 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Wed, 11 Dec 2024 14:01:12 +0100 Subject: [PATCH] delta-based index cache: improved read loop to take document end token into account instead of throwing exceptions --- .../cache/IndexCacheOnDiscDeltaBased.java | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDiscDeltaBased.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDiscDeltaBased.java index dc73f46cf5..df06fb7d2a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDiscDeltaBased.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDiscDeltaBased.java @@ -10,10 +10,13 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.index.cache; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Type; import java.nio.file.Files; @@ -59,8 +62,10 @@ import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import com.google.gson.Strictness; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; /** * @author Martin Lippert @@ -119,45 +124,40 @@ public Pair> retrieve(I File cacheStore = new File(cacheDirectory, cacheKey.toString() + ".json"); if (cacheStore.exists()) { - try (JsonReader reader = new JsonReader(new FileReader(cacheStore))) { - IndexCacheStore store = retrieveStoreFromIncrementalStorage(cacheKey, type); + IndexCacheStore store = retrieveStoreFromIncrementalStorage(cacheKey, type); - SortedMap timestampedFiles = Arrays.stream(files) - .filter(file -> new File(file).exists()) - .collect(Collectors.toMap(file -> file, file -> { - try { - return Files.getLastModifiedTime(new File(file).toPath()).toMillis(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }, (v1,v2) -> { throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2));}, TreeMap::new)); + SortedMap timestampedFiles = Arrays.stream(files) + .filter(file -> new File(file).exists()) + .collect(Collectors.toMap(file -> file, file -> { + try { + return Files.getLastModifiedTime(new File(file).toPath()).toMillis(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }, (v1,v2) -> { throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2));}, TreeMap::new)); - if (isFileMatch(timestampedFiles, store.getTimestampedFiles())) { + if (isFileMatch(timestampedFiles, store.getTimestampedFiles())) { - List symbols = store.getSymbols(); + List symbols = store.getSymbols(); - Map> storedDependencies = store.getDependencies(); - Multimap dependencies = MultimapBuilder.hashKeys().hashSetValues().build(); + Map> storedDependencies = store.getDependencies(); + Multimap dependencies = MultimapBuilder.hashKeys().hashSetValues().build(); - if (storedDependencies!=null && !storedDependencies.isEmpty()) { - for (Entry> entry : storedDependencies.entrySet()) { - dependencies.replaceValues(entry.getKey(), entry.getValue()); - } + if (storedDependencies!=null && !storedDependencies.isEmpty()) { + for (Entry> entry : storedDependencies.entrySet()) { + dependencies.replaceValues(entry.getKey(), entry.getValue()); } - - // update local timestamp cache - ConcurrentMap timestampMap = timestampedFiles.entrySet().stream() - .collect(Collectors.toConcurrentMap(e -> InternalFileIdentifier.fromPath(e.getKey()), e -> e.getValue())); - this.timestamps.put(cacheKey, timestampMap); - - return Pair.of( - (T[]) symbols.toArray((T[]) Array.newInstance(type, symbols.size())), - MultimapBuilder.hashKeys().hashSetValues().build(dependencies) - ); } - } - catch (Exception e) { - log.error("error reading cached symbols", e); + + // update local timestamp cache + ConcurrentMap timestampMap = timestampedFiles.entrySet().stream() + .collect(Collectors.toConcurrentMap(e -> InternalFileIdentifier.fromPath(e.getKey()), e -> e.getValue())); + this.timestamps.put(cacheKey, timestampMap); + + return Pair.of( + (T[]) symbols.toArray((T[]) Array.newInstance(type, symbols.size())), + MultimapBuilder.hashKeys().hashSetValues().build(dependencies) + ); } } return null; @@ -292,7 +292,7 @@ else if (key != null && !key.equals(cacheKey) private void persist(IndexCacheKey cacheKey, DeltaElement delta, boolean append) { DeltaStorage deltaStorage = new DeltaStorage(delta); - try (FileWriter writer = new FileWriter(new File(cacheDirectory, cacheKey.toString() + ".json"), append)) + try (Writer writer = new BufferedWriter(new FileWriter(new File(cacheDirectory, cacheKey.toString() + ".json"), append))) { Gson gson = createGson(); gson.toJson(deltaStorage, writer); @@ -313,15 +313,14 @@ private IndexCacheStore retrieveStoreFromIncrement if (cacheStore.exists()) { Gson gson = createGson(); - - try (JsonReader reader = new JsonReader(new FileReader(cacheStore))) { - - DeltaStorage readElement; - while ((readElement = gson.fromJson(reader, DeltaStorage.class)) != null) { - DeltaElement delta = readElement.storedElement; - store = delta.apply(store); + try (JsonReader reader = new JsonReader(new BufferedReader(new FileReader(cacheStore)))) { + reader.setStrictness(Strictness.LENIENT); + while (reader.peek() != JsonToken.END_DOCUMENT) { + DeltaStorage delta = gson.fromJson(reader, DeltaStorage.class); + store = delta.storedElement.apply(store); } + } catch (Exception e) { log.error("error reading cached symbols", e);