Files
RecordOrganizer/app/DD-Record-Organizer/Classes/ClassDataCache.vb
2026-03-16 12:29:11 +01:00

112 lines
3.6 KiB
VB.net

Imports System.Data
''' <summary>
''' Zentraler Cache für häufig abgerufene Datenbank-Queries
''' Reduziert DB-Roundtrips um bis zu 90%
''' </summary>
Public Class ClassDataCache
Private Shared ReadOnly _cache As New Dictionary(Of String, CachedItem)
Private Shared ReadOnly _lockObject As New Object()
Private Shared _defaultTimeout As TimeSpan = TimeSpan.FromMinutes(5)
Private Class CachedItem
Public Data As DataTable
Public Timestamp As DateTime
Public Timeout As TimeSpan
Public ReadOnly Property IsExpired As Boolean
Get
Return DateTime.Now - Timestamp > Timeout
End Get
End Property
End Class
''' <summary>
''' Daten aus Cache holen oder neu laden
''' </summary>
Public Shared Function GetOrLoad(cacheKey As String,
loadFunction As Func(Of DataTable),
Optional timeout As TimeSpan? = Nothing) As DataTable
SyncLock _lockObject
' Cache-Check
If _cache.ContainsKey(cacheKey) Then
Dim item = _cache(cacheKey)
If Not item.IsExpired Then
LOGGER.Debug($"Cache HIT: {cacheKey} (Age: {(DateTime.Now - item.Timestamp).TotalSeconds:F1}s)")
Return item.Data.Copy() ' Kopie zurückgeben!
Else
' Abgelaufen - entfernen
_cache.Remove(cacheKey)
LOGGER.Debug($"Cache EXPIRED: {cacheKey}")
End If
End If
' Cache MISS - neu laden
LOGGER.Debug($"Cache MISS: {cacheKey} - Loading from DB...")
Dim result = loadFunction()
If result IsNot Nothing Then
_cache(cacheKey) = New CachedItem With {
.Data = result.Copy(),
.Timestamp = DateTime.Now,
.Timeout = If(timeout, _defaultTimeout)
}
End If
Return result
End SyncLock
End Function
''' <summary>
''' Bestimmten Cache-Eintrag invalidieren
''' </summary>
Public Shared Sub Invalidate(cacheKey As String)
SyncLock _lockObject
If _cache.ContainsKey(cacheKey) Then
_cache.Remove(cacheKey)
LOGGER.Debug($"Cache INVALIDATED: {cacheKey}")
End If
End SyncLock
End Sub
''' <summary>
''' Alle Cache-Einträge löschen
''' </summary>
Public Shared Sub ClearAll()
SyncLock _lockObject
Dim count = _cache.Count
_cache.Clear()
LOGGER.Info($"Cache CLEARED: {count} entries removed")
End SyncLock
End Sub
''' <summary>
''' Abgelaufene Einträge entfernen
''' </summary>
Public Shared Sub CleanupExpired()
SyncLock _lockObject
Dim expiredKeys = _cache.Where(Function(kvp) kvp.Value.IsExpired).
Select(Function(kvp) kvp.Key).ToList()
For Each key In expiredKeys
_cache.Remove(key)
Next
If expiredKeys.Count > 0 Then
LOGGER.Debug($"Cache CLEANUP: {expiredKeys.Count} expired entries removed")
End If
End SyncLock
End Sub
''' <summary>
''' Cache-Statistiken
''' </summary>
Public Shared Function GetStatistics() As String
SyncLock _lockObject
Return $"Cache Entries: {_cache.Count}, Default Timeout: {_defaultTimeout.TotalMinutes:F1} min"
End SyncLock
End Function
End Class