1 #Region "Microsoft.VisualBasic::2e46ec2d70d12084ebd04781a6155f13, Microsoft.VisualBasic.Core\Language\Value\Uid.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 Uid
35     
36     '         Properties: Key
37     
38     '         Constructor: (+4 OverloadsSub New
39     
40     '         Function: __plus, Plus, ToString
41     
42     '         Sub: __error
43     
44     '         Operators: (+2 Overloads) +
45     
46     
47     ' /********************************************************************************/
48
49 #End Region
50
51 Imports System.Runtime.CompilerServices
52 Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
53 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.Repository
54 Imports Microsoft.VisualBasic.Linq
55 Imports Microsoft.VisualBasic.Serialization.JSON
56
57 Namespace Language
58
59     ''' <summary>
60     ''' The unique id generator.
61     ''' </summary>
62     Public Class Uid : Implements INamedValue
63
64         ''' <summary>
65         ''' index collection of array <see cref="__chars"/>.(<see cref="__chars"/>数组的下标集合)
66         ''' </summary>
67         Dim chars As List(Of Integer)
68         ''' <summary>
69         ''' tick n
70         ''' </summary>
71         Dim value As Integer = 0
72
73         ReadOnly __chars As Char() = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
74         ReadOnly __upbound As Integer = __chars.Length - 1
75
76         ''' <summary>
77         ''' 可以通过这个属性来重设uid的字符串的值
78         ''' </summary>
79         ''' <returns></returns>
80         Public Property Key As String Implements IKeyedEntity(Of String).Key
81             <MethodImpl(MethodImplOptions.AggressiveInlining)>
82             Get
83                 Return ToString()
84             End Get
85             Set(value As String)
86                 Call chars.Clear()
87
88                 For Each c As Char In value
89                     Dim index% = Array.IndexOf(__chars, c)
90
91                     If index = -1 Then
92                         Call __error(c)
93                     Else
94                         Call chars.Add(index)
95                     End If
96                 Next
97             End Set
98         End Property
99
100         ''' <summary>
101         ''' Throw error helper
102         ''' </summary>
103         ''' <param name="c"></param>
104         Private Sub __error(c As Char)
105             Dim msg$ = $"Char '{c}' is not a valid ASCII char, valids list: " & __chars.GetJson
106             Throw New NotSupportedException(msg)
107         End Sub
108
109         ''' <summary>
110         ''' 使用自定义顺序的字符序列
111         ''' </summary>
112         ''' <param name="n"></param>
113         ''' <param name="_chars"></param>
114         Sub New(n As Integer, _chars As IEnumerable(Of Char))
115             chars += -1
116             __chars = _chars.ToArray
117             __upbound = __chars.Length - 1
118
119             For i As Integer = 0 To n - 1
120                 Call __plus(chars.Count - 1)
121             Next
122         End Sub
123
124         ''' <summary>
125         ''' 
126         ''' </summary>
127         ''' <param name="n"></param>
128         ''' <param name="caseSensitive">
129         ''' 假若是使用这个uid对象来生成临时文件名的话,由于Windows的文件系统是不区分大小写的,所以Aa的情况会出现同名的情况,
130         ''' 所以在这里就需要设置为False了,大小写重名的情况在Linux或者Mac上面没有影响
131         ''' </param>
132         Sub New(n As IntegerOptional caseSensitive As Boolean = True)
133             chars += -1
134
135             If Not caseSensitive Then
136                 __upbound -= 26    ' 则只有小写字母
137             End If
138
139             For i As Integer = 0 To n - 1
140                 Call __plus(chars.Count - 1)
141             Next
142         End Sub
143
144         Sub New(i As Uid, Optional caseSensitive As Boolean = True)
145             chars = New List(Of Integer)(i.chars)
146
147             If Not caseSensitive Then
148                 __upbound -= 26    ' 则只有小写字母
149             End If
150         End Sub
151
152         ''' <summary>
153         ''' ZERO
154         ''' </summary>
155         ''' <param name="caseSensitive">
156         ''' 大小写敏感?假若是需要应用于文件名称,在Windows操作系统之上建议设置为False不敏感,否则会出现相同字母但是不同大小写的文件会被覆盖的情况出现
157         ''' </param>
158         Sub New(Optional caseSensitive As Boolean = True)
159             Call Me.New(Scan0, caseSensitive)
160         End Sub
161
162         Private Function __plus(l As IntegerAs Integer
163             Dim n As Integer = chars(l) + 1
164             Dim move As Integer = 0
165
166             If n > __upbound Then
167                 n = 0
168                 Dim pl = l - 1
169
170                 If pl < 0 Then
171                     Call chars.Insert(0, 1)
172                     l += 1
173                     move = 1
174                 Else
175                     l += __plus(pl)
176                 End If
177             End If
178
179             chars(l) = n
180             Me.value += 1
181
182             Return move
183         End Function
184
185         ''' <summary>
186         ''' current id value +1
187         ''' </summary>
188         ''' <returns></returns>
189         Public Function Plus() As String
190             Call __plus(chars.Count - 1)
191             Return ToString()
192         End Function
193
194         ''' <summary>
195         ''' Thread unsafe operator for current id value plus <paramref name="n"/>.
196         ''' (请注意,这个操作是线程不安全的,所以请确保在执行这个命令之前使用``SyncLock``加锁)
197         ''' </summary>
198         ''' <param name="i"></param>
199         ''' <param name="n"></param>
200         ''' <returns></returns>
201         Public Shared Operator +(i As Uid, n As IntegerAs Uid
202             For o As Integer = 0 To n - 1
203                 Call i.__plus(i.chars.Count - 1)
204             Next
205
206             Return i
207         End Operator
208
209         ''' <summary>
210         ''' Thread unsafe operator for current id value +1.
211         ''' (请注意,这个操作是线程不安全的,所以请确保在执行这个命令之前使用``SyncLock``加锁)
212         ''' </summary>
213         ''' <param name="i"></param>
214         ''' <returns></returns>
215         ''' 
216         <MethodImpl(MethodImplOptions.AggressiveInlining)>
217         Public Shared Operator +(i As Uid) As SeqValue(Of String)
218             Call i.__plus(i.chars.Count - 1)
219             Return New SeqValue(Of String)(i.value, i.ToString)
220         End Operator
221
222         ''' <summary>
223         ''' Convert the internal id value as the uid string value.(直接字符串序列,不会产生步进前移)
224         ''' </summary>
225         ''' <returns></returns>
226         ''' 
227         <MethodImpl(MethodImplOptions.AggressiveInlining)>
228         Public Overrides Function ToString() As String
229             Return chars.Select(Function(x) __chars(x)).CharString
230         End Function
231
232         ''' <summary>
233         ''' String contract of current id value string with a specific <paramref name="s"/> value.
234         ''' </summary>
235         ''' <param name="i"></param>
236         ''' <param name="s$"></param>
237         ''' <returns></returns>
238         <MethodImpl(MethodImplOptions.AggressiveInlining)>
239         Public Shared Operator &(i As Uid, s$) As String
240             Return i.ToString & s
241         End Operator
242
243         ''' <summary>
244         ''' Alias for <see cref="ToString()"/>
245         ''' </summary>
246         ''' <param name="i"></param>
247         ''' <returns></returns>
248         <MethodImpl(MethodImplOptions.AggressiveInlining)>
249         Public Shared Narrowing Operator CType(i As Uid) As String
250             Return i.ToString
251         End Operator
252     End Class
253 End Namespace