1 #Region "Microsoft.VisualBasic::a4ff0e70d96771d2639cf71d3eb7ca13, Microsoft.VisualBasic.Core\ComponentModel\DataStructures\HashList\HashList.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 HashList
35     
36     '         Properties: Count, EmptySlots
37     
38     '         Constructor: (+3 OverloadsSub New
39     
40     '         Function: (+2 Overloads) Contains, GetAvailablePos, GetEnumerator, GetEnumerator1
41     
42     '         Sub: (+2 Overloads) Add, Clear, (+2 Overloads) Remove
43     
44     '         Operators: *, +
45     
46     
47     ' /********************************************************************************/
48
49 #End Region
50
51 Imports System.Runtime.CompilerServices
52 Imports Microsoft.VisualBasic.Language
53 Imports Microsoft.VisualBasic.Language.Default
54 Imports Microsoft.VisualBasic.Linq
55
56 Namespace ComponentModel
57
58     ''' <summary>
59     ''' 指针位置应该是只读的,因为在这个列表之中,元素的读取时直接和位置以及指针值相关的
60     ''' </summary>
61     ''' <typeparam name="T">
62     ''' Class object that can be dispose by the system automatically and the class object that should 
63     ''' have a handle property to specific its position in this list class. 
64     ''' (能够被系统所自动销毁的对象类型,并且该类型的对象必须含有一个Handle属性来指明其在本列表中的位置)
65     ''' </typeparam>
66     ''' <remarks>
67     ''' 创建这个列表类型的初衷是能够将数据对象和其所在的位置绑定在一起:
68     ''' 
69     ''' 当目标对象添加进入这个列表之后,列表会自动寻找空余位置,然后将新的元素添加进入空余位置,之后将位置索引值写入对象
70     ''' 所以在这个列表进行添加方法之后,元素可能不是按照顺序排列的
71     ''' </remarks>
72     Public Class HashList(Of T As IAddressOf) : Implements IEnumerable(Of T)
73
74         ''' <summary>
75         ''' Object instances data physical storage position, element may be null after 
76         ''' remove a specify object handle. 
77         ''' (列表中的元素对象实例的实际存储位置,当对象元素从列表之中被移除了之后,其将会被销毁)
78         ''' </summary>
79         ''' <remarks>
80         ''' 即与只读属性'ListData'相比,这个字段的列表中可能含有空引用的元素对象.
81         ''' </remarks>
82         Dim list As New List(Of T)
83         Dim isNothing As Assert(Of T) = Function(x) x Is Nothing
84
85         ''' <summary>
86         ''' 返回所有不为空的元素的数量,因为本列表的存储特性的关系,为空的位置实际上是没有值的,所以不会返回这些为空的值的统计数量
87         ''' </summary>
88         ''' <returns></returns>
89         Public ReadOnly Property Count As Integer
90             <MethodImpl(MethodImplOptions.AggressiveInlining)>
91             Get
92                 Return list.Where(Function(x) Not isNothing(x)).Count
93             End Get
94         End Property
95
96         Public ReadOnly Property EmptySlots As Integer()
97             Get
98                 Return list _
99                     .SeqIterator _
100                     .Where(Function(x) isNothing(x.value)) _
101                     .Select(Function(x) x.i) _
102                     .ToArray
103             End Get
104         End Property
105
106         Public Function GetAvailablePos() As Integer
107             With list _
108                 .SeqIterator _
109                 .Where(Function(x) isNothing(x.value)) _
110                 .FirstOrDefault
111
112                 If list.Count > 0 And .i = 0 Then
113                     If list(0) Is Nothing Then
114                         Return 0
115                     Else
116                         Return list.Count
117                     End If
118                 Else
119                     Return .i
120                 End If
121             End With
122         End Function
123
124         ''' <summary>
125         ''' 与迭代器<see cref="GetEnumerator()"/>函数所不同的是,迭代器函数返回的都是非空元素,而这个读写属性则是可以直接接触到内部的
126         ''' </summary>
127         ''' <param name="index%"></param>
128         ''' <returns></returns>
129         Default Public Property Item(index%) As T
130             <MethodImpl(MethodImplOptions.AggressiveInlining)>
131             Get
132                 If index > list.Count - 1 Then
133                     Return Nothing
134                 End If
135
136                 If index < 0 Then
137                     index = list.Count + index
138                 End If
139
140                 Return list(index)
141             End Get
142             <MethodImpl(MethodImplOptions.AggressiveInlining)>
143             Set(value As T)
144                 If index < 0 Then
145                     index = list.Count + index
146                 End If
147
148                 list(index) = value
149             End Set
150         End Property
151
152         Sub New(Optional isNothing As Assert(Of T) = Nothing)
153             If Not isNothing Is Nothing Then
154                 Me.isNothing = isNothing
155             End If
156         End Sub
157
158         Sub New(capacity%, Optional isNothing As Assert(Of T) = Nothing)
159             Call Me.New(isNothing)
160
161             For i As Integer = 0 To capacity - 1
162                 Call list.Add(Nothing)
163             Next
164         End Sub
165
166         Sub New(source As IEnumerable(Of T), Optional isNothing As Assert(Of T) = Nothing)
167             Call Me.New(isNothing)
168             Call Add(source)
169         End Sub
170
171         <MethodImpl(MethodImplOptions.AggressiveInlining)>
172         Public Function Contains(x As T) As Boolean
173             Return Not Me(x.Address) Is Nothing
174         End Function
175
176         <MethodImpl(MethodImplOptions.AggressiveInlining)>
177         Public Function Contains(index As IntegerAs Boolean
178             Return Not Me(index) Is Nothing
179         End Function
180
181         <MethodImpl(MethodImplOptions.AggressiveInlining)>
182         Public Sub Clear()
183             Call list.Clear()
184         End Sub
185
186         <MethodImpl(MethodImplOptions.AggressiveInlining)>
187         Public Sub Remove(x As T)
188             list(x.Address) = Nothing
189         End Sub
190
191         <MethodImpl(MethodImplOptions.AggressiveInlining)>
192         Public Sub Remove(index%)
193             list(index) = Nothing
194         End Sub
195
196         Public Sub Add(source As IEnumerable(Of T))
197             For Each x As T In source.SafeQuery
198                 Call Add(x)
199             Next
200         End Sub
201
202         ''' <summary>
203         ''' 将要被添加的元素对象<paramref name="x"/>在这个列表之中的位置应该是提前设置好了的
204         ''' </summary>
205         ''' <param name="x"></param>
206         <MethodImpl(MethodImplOptions.AggressiveInlining)>
207         Public Sub Add(x As T)
208             If list.Count <= x.Address Then
209                 For i As Integer = 0 To x.Address - list.Count
210                     list.Add(Nothing)
211                 Next
212             End If
213
214             list(x.Address) = x
215         End Sub
216
217         <MethodImpl(MethodImplOptions.AggressiveInlining)>
218         Public Shared Narrowing Operator CType(src As HashList(Of T)) As T()
219             Return src.ToArray
220         End Operator
221
222         <MethodImpl(MethodImplOptions.AggressiveInlining)>
223         Public Shared Widening Operator CType(array As T()) As HashList(Of T)
224             Return New HashList(Of T)(array)
225         End Operator
226
227         Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
228             For Each x As T In list.Where(Function(o) Not isNothing(o))
229                 Yield x
230             Next
231         End Function
232
233         Public Iterator Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
234             Yield GetEnumerator()
235         End Function
236
237         Public Shared Operator +(list As HashList(Of T), element As T) As HashList(Of T)
238             Call list.Add(element)
239             Return list
240         End Operator
241
242         Public Shared Operator *(list As HashList(Of T), n%) As HashList(Of T)
243             If n = 0 Then
244                 Call list.Clear()
245             ElseIf n < 0 Then
246                 Throw New NotImplementedException
247             Else
248                 Throw New NotImplementedException
249             End If
250
251             Return list
252         End Operator
253     End Class
254 End Namespace