Imports System.Data
'''
''' Zentraler Cache für häufig abgerufene Datenbank-Queries
''' Reduziert DB-Roundtrips um bis zu 90%
'''
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
'''
''' Daten aus Cache holen oder neu laden
'''
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
'''
''' Bestimmten Cache-Eintrag invalidieren
'''
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
'''
''' Alle Cache-Einträge löschen
'''
Public Shared Sub ClearAll()
SyncLock _lockObject
Dim count = _cache.Count
_cache.Clear()
LOGGER.Info($"Cache CLEARED: {count} entries removed")
End SyncLock
End Sub
'''
''' Abgelaufene Einträge entfernen
'''
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
'''
''' Cache-Statistiken
'''
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