112 lines
3.6 KiB
VB.net
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
|