1 #Region "Microsoft.VisualBasic::c5da2c7c9f66a99c46fb50c58beb6d7a, Microsoft.VisualBasic.Core\ComponentModel\DataStructures\HashList\HashHandle.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class DefaultHashHandle
35     
36     '         Constructor: (+2 OverloadsSub New
37     '         Sub: (+2 Overloads) Add
38     
39     '         Operators: (+2 Overloads) +
40     
41     '     Class LinkNode
42     
43     '         Properties: [Next], node, Previous
44     
45     '         Constructor: (+2 OverloadsSub New
46     '         FunctionToString
47     
48     '     Class HashHandle
49     
50     '         Constructor: (+2 OverloadsSub New
51     
52     '         Function: (+3 Overloads) [Next], (+2 Overloads) Current, GetEnumerator, HasElement, IEnumerable_GetEnumerator
53     '                   IsNull, (+3 Overloads) Previous
54     
55     '         Sub: __allocate, (+2 Overloads) Add, (+2 Overloads) Remove
56     
57     
58     ' /********************************************************************************/
59
60 #End Region
61
62 Imports Microsoft.VisualBasic.ComponentModel.Collection
63 Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
64 Imports Microsoft.VisualBasic.Language
65 Imports Microsoft.VisualBasic.Serialization.JSON
66
67 Namespace ComponentModel
68
69     Public Class DefaultHashHandle(Of T As INamedValue) : Inherits HashHandle(Of IHashValue(Of T))
70
71         Sub New(Optional capacity As Integer = 2048)
72             Call MyBase.New(capacity)
73         End Sub
74
75         Sub New(source As IEnumerable(Of T), Optional capacity As Integer = 2048)
76             Call Me.New(capacity)
77             Call Me.Add(source)
78         End Sub
79
80         Public Overloads Sub Add(x As T)
81             Call MyBase.Add(New IHashValue(Of T) With {.obj = x})
82         End Sub
83
84         Public Overloads Sub Add(source As IEnumerable(Of T))
85             For Each x In source
86                 Call Add(x)
87             Next
88         End Sub
89
90         Public Shared Operator +(list As DefaultHashHandle(Of T), x As T) As DefaultHashHandle(Of T)
91             Call list.Add(x)
92             Return list
93         End Operator
94
95         Public Shared Operator +(list As DefaultHashHandle(Of T), x As IEnumerable(Of T)) As DefaultHashHandle(Of T)
96             Call list.Add(x)
97             Return list
98         End Operator
99     End Class
100
101     Public Class LinkNode(Of T As IHashHandle)
102
103         Private list As HashHandle(Of T)
104
105         ''' <summary>
106         ''' Current node in the chain list
107         ''' </summary>
108         ''' <returns></returns>
109         Public ReadOnly Property node As T
110
111         Friend Sub New(x As String, source As HashHandle(Of T))
112             list = source
113             node = source(x)
114         End Sub
115
116         Friend Sub New(x As T, source As HashHandle(Of T))
117             list = source
118             node = x
119         End Sub
120
121         ''' <summary>
122         ''' The next element in the chain after this element
123         ''' </summary>
124         ''' <returns></returns>
125         Public ReadOnly Property [Next] As LinkNode(Of T)
126             Get
127                 Return New LinkNode(Of T)(list.Next(node.Key), list)
128             End Get
129         End Property
130
131         ''' <summary>
132         ''' The previous element in the chain before this element
133         ''' </summary>
134         ''' <returns></returns>
135         Public ReadOnly Property Previous As LinkNode(Of T)
136             Get
137                 Return New LinkNode(Of T)(list.Previous(node.Key), list)
138             End Get
139         End Property
140
141         Public Overrides Function ToString() As String
142             Return node.GetJson
143         End Function
144     End Class
145
146     Public Class HashHandle(Of T As IHashHandle) : Implements IEnumerable(Of T)
147
148         Protected __innerHash As New Dictionary(Of T)
149         Protected __innerList As List(Of T)
150         Dim __emptys As Queue(Of Integer)
151         Dim delta As Integer
152
153         Default Public ReadOnly Property Item(id As StringAs T
154             Get
155                 Return __innerHash(id)
156             End Get
157         End Property
158
159         Sub New(Optional capacity As Integer = 2048)
160             __innerList = New List(Of T)(capacity)
161             __emptys = New Queue(Of Integer)(capacity)
162             delta = capacity
163
164             Call Me.__allocate()
165         End Sub
166
167         Sub New(source As IEnumerable(Of T), Optional capacity As Integer = 2048)
168             Call Me.New(capacity)
169             Call Me.Add(source)
170         End Sub
171
172         Public Function HasElement(x As StringAs Boolean
173             Return __innerHash.ContainsKey(x)
174         End Function
175
176         Public Function IsNull(x As IntegerAs Boolean
177             Return __emptys.Contains(x)
178         End Function
179
180         Public Function [Next](x As T) As T
181             Return [Next](x.Key)
182         End Function
183
184         Public Function [Next](x As StringAs T
185             Dim pos As Integer = __innerHash(x).Address
186             Dim n As T = __innerList(pos + 1)
187             Return n
188         End Function
189
190         Public Function [Next](i As IntegerAs T
191             Return __innerList(i + 1)
192         End Function
193
194         Public Function Previous(x As T) As T
195             Dim pos As Integer = __innerHash(x.Key).Address
196             Return __innerList(pos - 1)
197         End Function
198
199         Public Function Previous(x As StringAs T
200             Dim pos As Integer = __innerHash(x).Address
201             Return __innerList(pos - 1)
202         End Function
203
204         Public Function Previous(x As IntegerAs T
205             Return __innerList(x - 1)
206         End Function
207
208         Public Function Current(x As StringAs LinkNode(Of T)
209             Return New LinkNode(Of T)(x, Me)
210         End Function
211
212         Public Function Current(i As IntegerAs LinkNode(Of T)
213             Dim name As String = __innerList(i).Key
214             Return New LinkNode(Of T)(name, Me)
215         End Function
216
217         Public Sub Remove(x As String)
218             Dim n As T = Current(x).node
219             __innerList(n.Address) = Nothing
220             __innerHash.Remove(n.Key)
221             __emptys.Enqueue(n.Address)
222         End Sub
223
224         Public Sub Remove(i As Integer)
225             Dim n As T = __innerList(i)
226             __innerList(n.Address) = Nothing
227             __innerHash.Remove(n.Key)
228             __emptys.Enqueue(n.Address)
229         End Sub
230
231         Public Sub Add(x As T)
232             If __emptys.Count = 0 Then
233                 Call __allocate()
234             End If
235
236             Dim i As Integer = __emptys.Dequeue
237
238             Call x.Assign(address:=i)
239
240             __innerList(i) = x
241             __innerHash(x.Key) = x
242         End Sub
243
244         Public Sub Add(source As IEnumerable(Of T))
245             For Each x In source
246                 Call Add(x)
247             Next
248         End Sub
249
250         ''' <summary>
251         ''' Allocate memory
252         ''' </summary>
253         Private Sub __allocate()
254             Dim top As Integer = __innerList.Count
255
256             For i As Integer = 0 To delta - 1
257                 Call __emptys.Enqueue(top + i)
258             Next
259
260             __innerList += New T(__emptys.Count - 1) {}
261         End Sub
262
263         Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
264             For Each x In __innerList
265                 Yield x
266             Next
267         End Function
268
269         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
270             Yield GetEnumerator()
271         End Function
272     End Class
273 End Namespace