Skip to content

Commit 28a8766

Browse files
authored
[dynamic Instrumentation] DEBUG-2336 Add Concurrent Adaptive Cache (#6093)
## Summary of changes This PR introduces a thread-safe, adaptive caching system that automatically adjusts to system resources and usage patterns. The cache implements both LRU (Least Recently Used) and LFU (Least Frequently Used) eviction policies and features dynamic cleanup intervals based on expiration patterns. ### Key Features - Sliding Expiration: Items expire after a configurable period of inactivity - Adaptive Cleanup: Cleanup interval adjusts between 5-60 minutes based on expiration patterns - Resource Awareness: Automatically reduces capacity in low-resource environments - Thread Safety: All operations are protected by reader-writer locks for concurrent access ## Implementation #### Main cache implementation with: - Automatic capacity adjustment (2048 default, 512 for low-resource environments) - Dynamic cleanup interval (300s-3600s) that adjusts based on expiration patterns - Thread-safe operations using reader-writer locks - Hit rate tracking and monitoring #### Eviction Policies: - LRU: Uses LinkedList + Dictionary for O(1) access and eviction - LFU: Implements frequency tracking with SortedDictionary for efficient eviction #### Environment Detection: - Serverless environment detection (AWS Lambda, Azure Functions) - Memory availability checking (Windows and Unix systems) - Automatic capacity adjustment based on system resources ## Testing - Basic operations (Add, TryGet, GetOrAdd) - Eviction policy behavior (LRU and LFU) - Thread safety with parallel operations - Sliding expiration functionality - Cleanup interval adaptation - Resource-based capacity adjustment - Hit rate calculation - Proper disposal of resources
1 parent 57b76ff commit 28a8766

16 files changed

+1896
-0
lines changed

tracer/src/Datadog.Trace.Trimming/build/Datadog.Trace.Trimming.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@
589589
<type fullname="System.Func`6" />
590590
<type fullname="System.Func`7" />
591591
<type fullname="System.GC" />
592+
<type fullname="System.GCMemoryInfo" />
592593
<type fullname="System.Globalization.CultureInfo" />
593594
<type fullname="System.Globalization.DateTimeStyles" />
594595
<type fullname="System.Globalization.NumberFormatInfo" />
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// <copyright file="CacheItem.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
#nullable enable
7+
8+
using System;
9+
using System.Threading;
10+
11+
namespace Datadog.Trace.Debugger.Caching;
12+
13+
internal class CacheItem<TValue>
14+
{
15+
private readonly DateTime _created;
16+
private long _lastAccessed;
17+
private long _accessCount;
18+
19+
public CacheItem(TValue? value, TimeSpan? slidingExpiration)
20+
{
21+
if (slidingExpiration.HasValue && slidingExpiration.Value <= TimeSpan.Zero)
22+
{
23+
throw new ArgumentException("Sliding expiration must be positive", nameof(slidingExpiration));
24+
}
25+
26+
Value = value;
27+
_created = DateTime.UtcNow;
28+
LastAccessed = _created;
29+
SlidingExpiration = slidingExpiration;
30+
}
31+
32+
public DateTimeOffset Created => _created;
33+
34+
public TimeSpan? SlidingExpiration { get; set; }
35+
36+
public TValue? Value { get; set; }
37+
38+
internal DateTimeOffset LastAccessed
39+
{
40+
get => DateTime.FromBinary(Interlocked.Read(ref _lastAccessed));
41+
set => Interlocked.Exchange(ref _lastAccessed, value.UtcDateTime.ToBinary());
42+
}
43+
44+
internal long AccessCount => Interlocked.Read(ref _accessCount);
45+
46+
internal void UpdateAccess(DateTime now)
47+
{
48+
LastAccessed = now;
49+
Interlocked.Increment(ref _accessCount);
50+
}
51+
}

0 commit comments

Comments
 (0)