microsoft-visualbasic-runtime/ComponentModel/DataStructures/BitMap/HashHandle.vb

274 lines
8.3 KiB
VB.net
Raw Normal View History

2019-05-22 19:02:42 +08:00
#Region "Microsoft.VisualBasic::c5da2c7c9f66a99c46fb50c58beb6d7a, Microsoft.VisualBasic.Core\ComponentModel\DataStructures\BitMap\HashHandle.vb"
2018-08-02 20:14:48 +08:00
' Author:
'
' asuka (amethyst.asuka@gcmodeller.org)
' xie (genetics@smrucc.org)
' xieguigang (xie.guigang@live.com)
'
' Copyright (c) 2018 GPL3 Licensed
'
'
' GNU GENERAL PUBLIC LICENSE (GPL3)
'
'
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program. If not, see <http://www.gnu.org/licenses/>.
' /********************************************************************************/
' Summaries:
' Class DefaultHashHandle
'
' Constructor: (+2 Overloads) Sub New
' Sub: (+2 Overloads) Add
'
' Operators: (+2 Overloads) +
'
' Class LinkNode
'
' Properties: [Next], node, Previous
'
' Constructor: (+2 Overloads) Sub New
' Function: ToString
'
' Class HashHandle
'
' Constructor: (+2 Overloads) Sub New
'
' Function: (+3 Overloads) [Next], (+2 Overloads) Current, GetEnumerator, HasElement, IEnumerable_GetEnumerator
' IsNull, (+3 Overloads) Previous
'
' Sub: __allocate, (+2 Overloads) Add, (+2 Overloads) Remove
'
'
' /********************************************************************************/
#End Region
Imports Microsoft.VisualBasic.ComponentModel.Collection
Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
Imports Microsoft.VisualBasic.Language
Imports Microsoft.VisualBasic.Serialization.JSON
Namespace ComponentModel
Public Class DefaultHashHandle(Of T As INamedValue) : Inherits HashHandle(Of IHashValue(Of T))
Sub New(Optional capacity As Integer = 2048)
Call MyBase.New(capacity)
End Sub
Sub New(source As IEnumerable(Of T), Optional capacity As Integer = 2048)
Call Me.New(capacity)
Call Me.Add(source)
End Sub
Public Overloads Sub Add(x As T)
Call MyBase.Add(New IHashValue(Of T) With {.obj = x})
End Sub
Public Overloads Sub Add(source As IEnumerable(Of T))
For Each x In source
Call Add(x)
Next
End Sub
Public Shared Operator +(list As DefaultHashHandle(Of T), x As T) As DefaultHashHandle(Of T)
Call list.Add(x)
Return list
End Operator
Public Shared Operator +(list As DefaultHashHandle(Of T), x As IEnumerable(Of T)) As DefaultHashHandle(Of T)
Call list.Add(x)
Return list
End Operator
End Class
Public Class LinkNode(Of T As IHashHandle)
Private list As HashHandle(Of T)
''' <summary>
''' Current node in the chain list
''' </summary>
''' <returns></returns>
Public ReadOnly Property node As T
Friend Sub New(x As String, source As HashHandle(Of T))
list = source
node = source(x)
End Sub
Friend Sub New(x As T, source As HashHandle(Of T))
list = source
node = x
End Sub
''' <summary>
''' The next element in the chain after this element
''' </summary>
''' <returns></returns>
Public ReadOnly Property [Next] As LinkNode(Of T)
Get
2019-07-04 20:16:19 +08:00
Return New LinkNode(Of T)(list.Next(node.Address), list)
2018-08-02 20:14:48 +08:00
End Get
End Property
''' <summary>
''' The previous element in the chain before this element
''' </summary>
''' <returns></returns>
Public ReadOnly Property Previous As LinkNode(Of T)
Get
2019-07-04 20:16:19 +08:00
Return New LinkNode(Of T)(list.Previous(node.Address), list)
2018-08-02 20:14:48 +08:00
End Get
End Property
Public Overrides Function ToString() As String
Return node.GetJson
End Function
End Class
Public Class HashHandle(Of T As IHashHandle) : Implements IEnumerable(Of T)
Protected __innerHash As New Dictionary(Of T)
Protected __innerList As List(Of T)
Dim __emptys As Queue(Of Integer)
Dim delta As Integer
Default Public ReadOnly Property Item(id As String) As T
Get
Return __innerHash(id)
End Get
End Property
Sub New(Optional capacity As Integer = 2048)
__innerList = New List(Of T)(capacity)
__emptys = New Queue(Of Integer)(capacity)
delta = capacity
Call Me.__allocate()
End Sub
Sub New(source As IEnumerable(Of T), Optional capacity As Integer = 2048)
Call Me.New(capacity)
Call Me.Add(source)
End Sub
Public Function HasElement(x As String) As Boolean
Return __innerHash.ContainsKey(x)
End Function
Public Function IsNull(x As Integer) As Boolean
Return __emptys.Contains(x)
End Function
Public Function [Next](x As T) As T
2019-07-04 20:16:19 +08:00
Return [Next](x.Address)
2018-08-02 20:14:48 +08:00
End Function
Public Function [Next](x As String) As T
Dim pos As Integer = __innerHash(x).Address
Dim n As T = __innerList(pos + 1)
Return n
End Function
Public Function [Next](i As Integer) As T
Return __innerList(i + 1)
End Function
Public Function Previous(x As T) As T
2019-07-04 20:16:19 +08:00
Dim pos As Integer = __innerHash(x.Address).Address
2018-08-02 20:14:48 +08:00
Return __innerList(pos - 1)
End Function
Public Function Previous(x As String) As T
Dim pos As Integer = __innerHash(x).Address
Return __innerList(pos - 1)
End Function
Public Function Previous(x As Integer) As T
Return __innerList(x - 1)
End Function
Public Function Current(x As String) As LinkNode(Of T)
Return New LinkNode(Of T)(x, Me)
End Function
Public Function Current(i As Integer) As LinkNode(Of T)
2019-07-04 20:16:19 +08:00
Dim name As String = __innerList(i).Address
2018-08-02 20:14:48 +08:00
Return New LinkNode(Of T)(name, Me)
End Function
Public Sub Remove(x As String)
Dim n As T = Current(x).node
__innerList(n.Address) = Nothing
2019-07-04 20:16:19 +08:00
__innerHash.Remove(n.Address)
2018-08-02 20:14:48 +08:00
__emptys.Enqueue(n.Address)
End Sub
Public Sub Remove(i As Integer)
Dim n As T = __innerList(i)
__innerList(n.Address) = Nothing
2019-07-04 20:16:19 +08:00
__innerHash.Remove(n.Address)
2018-08-02 20:14:48 +08:00
__emptys.Enqueue(n.Address)
End Sub
Public Sub Add(x As T)
If __emptys.Count = 0 Then
Call __allocate()
End If
Dim i As Integer = __emptys.Dequeue
Call x.Assign(address:=i)
__innerList(i) = x
2019-07-04 20:16:19 +08:00
__innerHash(x.Address) = x
2018-08-02 20:14:48 +08:00
End Sub
Public Sub Add(source As IEnumerable(Of T))
For Each x In source
Call Add(x)
Next
End Sub
''' <summary>
''' Allocate memory
''' </summary>
Private Sub __allocate()
Dim top As Integer = __innerList.Count
For i As Integer = 0 To delta - 1
Call __emptys.Enqueue(top + i)
Next
__innerList += New T(__emptys.Count - 1) {}
End Sub
Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
For Each x In __innerList
Yield x
Next
End Function
Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Yield GetEnumerator()
End Function
End Class
End Namespace