Skip to content

Commit 75b9c2f

Browse files
committed
Caching improvements
1 parent 364d6fe commit 75b9c2f

8 files changed

Lines changed: 488 additions & 28 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using FluentAssertions;
3+
using LiteDbX.Engine;
4+
using Xunit;
5+
6+
namespace LiteDbX.Internals;
7+
8+
public class CacheTrim_Tests
9+
{
10+
[Fact]
11+
public void Discarded_Page_Tracks_TimestampFree_And_Clears_It_On_Reuse()
12+
{
13+
var cache = CreateTrimEnabledCache();
14+
var page = cache.NewPage();
15+
16+
page.TimestampFree.Should().BeNull();
17+
18+
cache.DiscardPage(page);
19+
20+
page.TimestampFree.Should().NotBeNull();
21+
22+
var reused = cache.NewPage();
23+
24+
reused.TimestampFree.Should().BeNull();
25+
26+
cache.DiscardPage(reused);
27+
}
28+
29+
[Fact]
30+
public void Cache_Trim_Retires_A_Fully_Free_Idle_Segment()
31+
{
32+
var cache = CreateTrimEnabledCache();
33+
var first = cache.NewPage();
34+
var second = cache.NewPage();
35+
36+
cache.DiscardPage(first);
37+
cache.DiscardPage(second);
38+
39+
cache.ActiveSegments.Should().Be(1);
40+
cache.RetiredSegments.Should().Be(0);
41+
cache.FreePages.Should().Be(2);
42+
43+
var reused = cache.NewPage();
44+
45+
cache.RetiredSegments.Should().Be(1);
46+
cache.ActiveSegments.Should().Be(1);
47+
cache.FreePages.Should().Be(1);
48+
reused.SegmentId.Should().NotBe(0);
49+
50+
cache.DiscardPage(reused);
51+
}
52+
53+
[Fact]
54+
public void Cache_Trim_Does_Not_Retire_Segment_When_A_Writable_Sibling_Is_Still_In_Use()
55+
{
56+
var cache = CreateTrimEnabledCache();
57+
var first = cache.NewPage();
58+
var second = cache.NewPage();
59+
60+
cache.DiscardPage(first);
61+
62+
var reused = cache.NewPage();
63+
64+
cache.RetiredSegments.Should().Be(0);
65+
cache.ActiveSegments.Should().Be(1);
66+
reused.UniqueID.Should().Be(first.UniqueID);
67+
68+
cache.DiscardPage(reused);
69+
cache.DiscardPage(second);
70+
}
71+
72+
[Fact]
73+
public void Cache_Trim_Does_Not_Retire_Segment_When_A_Readable_Sibling_Is_Still_Cached()
74+
{
75+
var cache = CreateTrimEnabledCache();
76+
var readableSource = cache.NewPage();
77+
var writableSibling = cache.NewPage();
78+
79+
readableSource.Origin = FileOrigin.Log;
80+
readableSource.Position = 0;
81+
cache.TryMoveToReadable(readableSource).Should().BeTrue();
82+
83+
cache.DiscardPage(writableSibling);
84+
85+
var reused = cache.NewPage();
86+
87+
cache.RetiredSegments.Should().Be(0);
88+
cache.ActiveSegments.Should().Be(1);
89+
reused.UniqueID.Should().Be(writableSibling.UniqueID);
90+
91+
var readable = cache.GetReadablePage(0, FileOrigin.Log, (_, _) => { });
92+
readable.UniqueID.Should().Be(readableSource.UniqueID);
93+
readable.Release();
94+
95+
cache.DiscardPage(reused);
96+
}
97+
98+
private static MemoryCache CreateTrimEnabledCache(int segmentSize = 2)
99+
{
100+
return new MemoryCache(
101+
new[] { segmentSize },
102+
new MemoryCacheConfig
103+
{
104+
Enabled = true,
105+
MaxFreePages = 0,
106+
MaxIdleTime = TimeSpan.Zero,
107+
CleanupInterval = TimeSpan.Zero,
108+
BatchSize = 10
109+
});
110+
}
111+
}
112+

LiteDBX/Engine/Disk/DiskService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public DiskService(
5050
EngineState state,
5151
int[] memorySegmentSizes)
5252
{
53-
Cache = new MemoryCache(memorySegmentSizes);
53+
Cache = new MemoryCache(memorySegmentSizes, settings.MemoryCacheConfig);
5454
_state = state;
5555

5656
_dataFactory = settings.CreateDataFactory();

0 commit comments

Comments
 (0)