121 lines
3.9 KiB
VB.net
121 lines
3.9 KiB
VB.net
Imports DigitalData.Modules.EDMI.API.Client
|
|
|
|
Namespace DocumentResultList
|
|
|
|
Public Class Cache
|
|
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()
|
|
Me.New(_DefaultCapacity)
|
|
End Sub
|
|
|
|
Public Sub New(capacity As Long)
|
|
If capacity < 0 Then
|
|
Throw New InvalidOperationException("DocumentResultCache capacity must be positive.")
|
|
End If
|
|
|
|
Me.Capacity = capacity
|
|
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
|
|
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 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
|
|
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
|
|
|