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