Skip to content

Commit d5218c4

Browse files
Create shorter cache file names
1 parent f6eb22b commit d5218c4

3 files changed

Lines changed: 32 additions & 18 deletions

File tree

src/ImageSharp.Web/Caching/PhysicalFileSystemCache.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public PhysicalFileSystemCache(
5757
Guard.NotNull(options, nameof(options));
5858
Guard.NotNullOrWhiteSpace(environment.WebRootPath, nameof(environment.WebRootPath));
5959

60-
// Allow configuration of the cache without having to register everything.
60+
// Allow configuration of the cache without having to register everything
6161
PhysicalFileSystemCacheOptions cacheOptions = options != null ? options.Value : new PhysicalFileSystemCacheOptions();
6262
this.cacheRootPath = GetCacheRoot(cacheOptions, environment.WebRootPath, environment.ContentRootPath);
6363
this.cacheFolderDepth = (int)cacheOptions.CacheFolderDepth;
@@ -146,17 +146,28 @@ private string ToImageFilePath(string path, in ImageCacheMetadata metaData)
146146
/// </summary>
147147
/// <param name="key">The cache key.</param>
148148
/// <param name="cacheFolderDepth">The depth of the nested cache folders structure to store the images.</param>
149-
/// <returns>The <see cref="string"/>.</returns>
149+
/// <returns>
150+
/// The <see cref="string" />.
151+
/// </returns>
150152
[MethodImpl(MethodImplOptions.AggressiveInlining)]
151153
internal static unsafe string ToFilePath(string key, int cacheFolderDepth)
152154
{
153-
if (cacheFolderDepth > key.Length)
155+
int length;
156+
int nameStartIndex;
157+
if (cacheFolderDepth >= key.Length)
154158
{
159+
// Keep all characters in file name (legacy behavior)
155160
cacheFolderDepth = key.Length;
161+
length = (cacheFolderDepth * 2) + key.Length;
162+
nameStartIndex = 0;
163+
}
164+
else
165+
{
166+
// Remove characters used in folders from file name
167+
length = cacheFolderDepth + key.Length;
168+
nameStartIndex = cacheFolderDepth;
156169
}
157170

158-
// Each key substring char + separator + key
159-
int length = (cacheFolderDepth * 2) + key.Length;
160171
fixed (char* keyPtr = key)
161172
{
162173
return string.Create(length, (Ptr: (IntPtr)keyPtr, key.Length), (chars, args) =>
@@ -173,7 +184,7 @@ internal static unsafe string ToFilePath(string key, int cacheFolderDepth)
173184
Unsafe.Add(ref charRef, index++) = separator;
174185
}
175186

176-
for (int i = 0; i < keySpan.Length; i++)
187+
for (int i = nameStartIndex; i < keySpan.Length; i++)
177188
{
178189
Unsafe.Add(ref charRef, index++) = Unsafe.Add(ref keyRef, i);
179190
}

tests/ImageSharp.Web.Benchmarks/Caching/StringJoinBenchmarks.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ namespace SixLabors.ImageSharp.Web.Benchmarks.Caching
1212
public class StringJoinBenchmarks
1313
{
1414
private const string Key = "abcdefghijkl";
15-
private const int CachedNameLength = 12;
15+
16+
[Params(0, 8, 12)]
17+
public int CacheFolderDepth { get; set; }
1618

1719
[Benchmark(Baseline = true, Description = "String.Join")]
1820
public string JoinUsingString()
19-
=> $"{string.Join("/", Key.Substring(0, CachedNameLength).ToCharArray())}/{Key}";
21+
=> $"{string.Join("/", Key.Substring(0, this.CacheFolderDepth).ToCharArray())}/{Key}";
2022

2123
[Benchmark(Description = "StringBuilder.Append")]
2224
public string JoinUsingStringBuilder()
@@ -25,8 +27,8 @@ public string JoinUsingStringBuilder()
2527
const char separator = '/';
2628

2729
// Each key substring char + separator + key
28-
var sb = new StringBuilder((CachedNameLength * 2) + Key.Length);
29-
ReadOnlySpan<char> paths = keySpan.Slice(0, CachedNameLength);
30+
var sb = new StringBuilder((this.CacheFolderDepth * 2) + Key.Length);
31+
ReadOnlySpan<char> paths = keySpan.Slice(0, this.CacheFolderDepth);
3032
for (int i = 0; i < paths.Length; i++)
3133
{
3234
sb.Append(paths[i]);
@@ -39,7 +41,7 @@ public string JoinUsingStringBuilder()
3941

4042
[Benchmark(Description = "String.Create")]
4143
public string JoinUsingStringCreate()
42-
=> PhysicalFileSystemCache.ToFilePath(Key, CachedNameLength);
44+
=> PhysicalFileSystemCache.ToFilePath(Key, this.CacheFolderDepth);
4345

4446
/*
4547
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363

tests/ImageSharp.Web.Tests/Caching/PhysicialFileSystemCacheTests.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ namespace SixLabors.ImageSharp.Web.Tests.Caching
88
{
99
public class PhysicialFileSystemCacheTests
1010
{
11-
[Fact]
12-
public void FilePathMatchesReference()
11+
[Theory]
12+
[InlineData("abcdefghijkl", 0, "abcdefghijkl")]
13+
[InlineData("abcdefghijkl", 4, "a/b/c/d/efghijkl")]
14+
[InlineData("abcdefghijkl", 8, "a/b/c/d/e/f/g/h/ijkl")]
15+
[InlineData("abcdefghijkl", 12, "a/b/c/d/e/f/g/h/i/j/k/l/abcdefghijkl")]
16+
[InlineData("abcdefghijkl", 16, "a/b/c/d/e/f/g/h/i/j/k/l/abcdefghijkl")]
17+
public void FilePathMatchesReference(string key, int cacheFolderDepth, string expected)
1318
{
14-
const string Key = "abcdefghijkl";
15-
const int CachedNameLength = 12;
16-
17-
string expected = $"{string.Join("/", Key.Substring(0, CachedNameLength).ToCharArray())}/{Key}";
18-
string actual = PhysicalFileSystemCache.ToFilePath(Key, CachedNameLength);
19+
string actual = PhysicalFileSystemCache.ToFilePath(key, cacheFolderDepth);
1920

2021
Assert.Equal(expected, actual);
2122
}

0 commit comments

Comments
 (0)