2022-02-23 14:29:14 +01:00

136 lines
4.4 KiB
VB.net

Imports DigitalData.Modules.Base
Imports DigitalData.Modules.EDMI.API.Client
Imports DigitalData.Modules.Logging
Namespace DocumentResultList
Public Class Cache
Inherits BaseClass
Implements ICollection(Of Document)
Private Const _DefaultCapacity As Long = 1000
Public Shared ReadOnly Property DefaultCapacity As Long
Get
Return _DefaultCapacity
End Get
End Property
Friend ReadOnly List As New LinkedList(Of Document)
Private ReadOnly Index As New Dictionary(Of String, LinkedListNode(Of Document))
Private ReadOnly Lock As New Object
Public Sub New(pLogConfig As LogConfig)
Me.New(pLogConfig, _DefaultCapacity)
End Sub
Public Sub New(pLogConfig As LogConfig, pCapacity As Long)
MyBase.New(pLogConfig)
If pCapacity < 0 Then
Throw New InvalidOperationException("DocumentResultCache capacity must be positive.")
End If
Logger.Debug("Initializing DocumentResultCache with capacity of [{0}] bytes.", pCapacity)
Me.Capacity = pCapacity
End Sub
Public Event DiscardingOldestItem As EventHandler
Public Property Capacity As Long
Public Property Count As Integer Implements ICollection(Of Document).Count
Public ReadOnly Property Oldest As Document
Get
Return List.First.Value
End Get
End Property
Public Sub Add(pItem As Document) Implements ICollection(Of Document).Add
Logger.Debug("Adding document [{0}].", pItem.Id)
SyncLock Lock
If Index.ContainsKey(pItem.Id) Then
List.Remove(Index(pItem.Id))
Index(pItem.Id) = List.AddLast(pItem)
Return
End If
If Count >= Capacity AndAlso Capacity <> 0 Then
RaiseEvent DiscardingOldestItem(Me, New EventArgs())
Remove(Oldest)
End If
Index.Add(pItem.Id, List.AddLast(pItem))
If pItem.Contents IsNot Nothing Then
Count += pItem.Contents?.Length
End If
End SyncLock
End Sub
Public Function Contains(pItem As Document) As Boolean Implements ICollection(Of Document).Contains
Return Index.ContainsKey(pItem.Id)
End Function
Public Function Contains(pDocumentId As Long) As Boolean
Return Index.ContainsKey(pDocumentId)
End Function
Public Sub CopyTo(pArray As Document(), pIndex As Integer) Implements ICollection(Of Document).CopyTo
SyncLock Lock
For Each item As Document In Me
pArray(Math.Min(System.Threading.Interlocked.Increment(pIndex), pIndex - 1)) = item
Next
End SyncLock
End Sub
Public Sub Clear() Implements ICollection(Of Document).Clear
SyncLock Lock
List.Clear()
Index.Clear()
End SyncLock
End Sub
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Document).IsReadOnly
Get
Return False
End Get
End Property
Public Function Remove(pItem As Document) As Boolean Implements ICollection(Of Document).Remove
Logger.Debug("Removing document [{0}].", pItem.Id)
SyncLock Lock
If Index.ContainsKey(pItem.Id) Then
List.Remove(Index(pItem.Id))
Index.Remove(pItem.Id)
If pItem.Contents IsNot Nothing Then
Count -= pItem.Contents.Length
End If
Return True
End If
Return False
End SyncLock
End Function
Private Iterator Function GetEnumerator() As IEnumerator(Of Document) Implements ICollection(Of Document).GetEnumerator
Dim node As LinkedListNode(Of Document) = List.First
While node IsNot Nothing
Yield node.Value
node = node.[Next]
End While
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return DirectCast(List, IEnumerable).GetEnumerator()
End Function
End Class
End Namespace