Skip to content

Commit 8d59a64

Browse files
authored
Merge pull request #2023 from tyrielv/tyrielv/fix-prefetch-merge
Fix build break: bad merge in prefetch cache parameters
2 parents fa0c3c5 + 2d17f9d commit 8d59a64

4 files changed

Lines changed: 55 additions & 7 deletions

File tree

GVFS/GVFS.Common/Prefetch/BlobPrefetcher.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,42 @@ private void SavePrefetchArgs(string targetCommit, bool hydrate)
688688
}
689689
}
690690

691+
/// <summary>
692+
/// Updates the noop prefetch cache after a successful prefetch that was
693+
/// handled externally (e.g. offloaded to the mount process). This mirrors
694+
/// the logic in <see cref="SavePrefetchArgs"/> but is callable without a
695+
/// BlobPrefetcher instance.
696+
/// </summary>
697+
public static void UpdateNoopCache(
698+
FileBasedDictionary<string, string> prefetchCache,
699+
int maxCacheSize,
700+
string commitId,
701+
List<string> files,
702+
List<string> folders,
703+
bool hydrate)
704+
{
705+
if (prefetchCache == null || maxCacheSize <= 0)
706+
{
707+
return;
708+
}
709+
710+
string cacheKey = ComputeCacheKey(files, folders, hydrate);
711+
712+
Dictionary<string, string> allEntries = prefetchCache.GetAllKeysAndValues();
713+
if (allEntries.Count >= maxCacheSize && !allEntries.ContainsKey(cacheKey))
714+
{
715+
using (Dictionary<string, string>.Enumerator enumerator = allEntries.GetEnumerator())
716+
{
717+
if (enumerator.MoveNext())
718+
{
719+
prefetchCache.RemoveAndFlush(enumerator.Current.Key);
720+
}
721+
}
722+
}
723+
724+
prefetchCache.SetValueAndFlush(cacheKey, commitId);
725+
}
726+
691727
internal static string ComputeCacheKey(List<string> files, List<string> folders, bool hydrate)
692728
{
693729
List<string> sortedFiles = new List<string>(files);

GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/PrefetchBlobsOffloadTests.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ public void PrefetchBlobsMountedReportsStats()
4242
public void PrefetchBlobsUnmountedFallsBackToDirectAuth()
4343
{
4444
// Unmount, then blob prefetch should fall back to direct auth
45-
// and still succeed.
45+
// and still succeed. Use a file not prefetched by earlier tests
46+
// so the noop cache doesn't short-circuit.
4647
this.Enlistment.UnmountGVFS();
4748

4849
try
4950
{
50-
string output = this.Enlistment.Prefetch($"--files {Path.Combine("GVFS", "GVFS", "Program.cs")}");
51+
string output = this.Enlistment.Prefetch($"--files {Path.Combine("GVFS", "GVFS.Common", "GVFSEnlistment.cs")}");
5152
output.ShouldContain("Matched blobs:");
5253
output.ShouldContain("Downloaded:");
5354
}
@@ -69,12 +70,14 @@ public void PrefetchBlobsMountedWithFolders()
6970
public void PrefetchBlobsMountedAfterRemount()
7071
{
7172
// After unmount + remount, blob prefetch should work via
72-
// the mount process again.
73+
// the mount process again. Since this file was already
74+
// prefetched in Order(1), the noop cache correctly detects
75+
// there's nothing new to download.
7376
this.Enlistment.UnmountGVFS();
7477
this.Enlistment.MountGVFS();
7578

7679
string output = this.Enlistment.Prefetch($"--files {Path.Combine("GVFS", "GVFS", "Program.cs")}");
77-
output.ShouldContain("Matched blobs:");
80+
output.ShouldContain("Nothing new to prefetch.");
7881
}
7982
}
8083
}

GVFS/GVFS.Mount/InProcessMount.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,8 @@ private void HandlePrefetchBlobsRequest(NamedPipeMessages.Message message, Named
11231123
objectRequestor,
11241124
request.Files,
11251125
request.Folders,
1126-
lastPrefetchArgs,
1126+
prefetchCache: null,
1127+
maxCacheSize: 0,
11271128
chunkSize: 4000,
11281129
searchThreadCount: maxThreads,
11291130
downloadThreadCount: downloadThreads,

GVFS/GVFS/CommandLine/PrefetchVerb.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,15 @@ protected override void Execute(GVFSEnlistment enlistment)
231231
cacheServerFromConfig,
232232
out objectRequestor,
233233
out resolvedCacheServer);
234-
this.PrefetchBlobs(tracer, enlistment, headCommitId, filesList, foldersList, lastPrefetchArgs, objectRequestor, resolvedCacheServer);
234+
this.PrefetchBlobs(tracer, enlistment, headCommitId, filesList, foldersList, prefetchCache, prefetchCacheSize, objectRequestor, resolvedCacheServer);
235235
}
236236
else
237237
{
238-
// Mount handled download — now hydrate locally
238+
// Mount handled download — hydrate locally, then update noop
239+
// cache. Cache update is after hydration so a hydration failure
240+
// doesn't suppress the retry on the next run.
239241
this.HydrateMatchingFiles(tracer, enlistment, filesList, foldersList);
242+
BlobPrefetcher.UpdateNoopCache(prefetchCache, prefetchCacheSize, headCommitId, filesList, foldersList, this.HydrateFiles);
240243
}
241244
}
242245
else if (!this.TryPrefetchBlobsViaMountProcess(tracer, enlistment, filesList, foldersList, headCommitId))
@@ -251,6 +254,11 @@ protected override void Execute(GVFSEnlistment enlistment)
251254
out resolvedCacheServer);
252255
this.PrefetchBlobs(tracer, enlistment, headCommitId, filesList, foldersList, prefetchCache, prefetchCacheSize, objectRequestor, resolvedCacheServer);
253256
}
257+
else
258+
{
259+
// Mount handled download — update noop cache so repeat runs are skipped
260+
BlobPrefetcher.UpdateNoopCache(prefetchCache, prefetchCacheSize, headCommitId, filesList, foldersList, hydrate: false);
261+
}
254262
}
255263
}
256264
catch (VerbAbortedException)

0 commit comments

Comments
 (0)