-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathHash.cls
More file actions
342 lines (312 loc) · 8.27 KB
/
Copy pathHash.cls
File metadata and controls
342 lines (312 loc) · 8.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "Hash"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private Type item
Key As String
nDx As Long
KeyType As Integer ' 0 as is , 1, reference/don't delete
originalType As Byte
globalvar As Byte
firsthash As Long
lastpos As Long
Pleft As Long ' a list
End Type
'
Private PriveSpace() As item
Public MaxSpace As Long
Dim hashlen As Long
Dim toplim As Long
Private Declare Sub GetMem2 Lib "msvbvm60" (ByVal Addr As Long, RetVal As Integer)
Public index As Long
Private Hash() As Long
Private entrance As Long
Public Sub BigSize(n As Long)
MaxSpace = n
ReDim PriveSpace(MaxSpace) As item, Hash(MaxSpace * 2 + 3)
hashlen = MaxSpace * 2 + 3
toplim = -1
End Sub
Private Sub Class_Initialize()
MaxSpace = 10
ReDim PriveSpace(MaxSpace) As item, Hash(MaxSpace * 2 + 3)
hashlen = MaxSpace * 2 + 3
toplim = -1
End Sub
Friend Sub ReadVar(where, Name$, num As Long)
Name$ = PriveSpace(where).Key
num = PriveSpace(where).nDx
End Sub
Public Property Get lastNDX() As Long
If index < 0 Then
lastNDX = 0
Else
lastNDX = PriveSpace(index).nDx
End If
End Property
Public Property Get lastkey() As String
If index < 0 Then
lastkey = vbCrLf
Else
lastkey = PriveSpace(index).Key
End If
End Property
Private Sub ExpandHash()
Dim i As Long
hashlen = hashlen * 2 + 3
ReDim Hash(hashlen) As Long
For i = 0 To toplim
place HashFunc2(i), i
Next i
End Sub
Friend Sub ReduceHash(newTop As Long, v())
Dim aa As Variant, ditem As item, ditemcl As item
ditemcl.nDx = -1
Dim i As Long
If toplim < newTop Then Exit Sub
entrance = entrance + 1
For i = toplim To newTop Step -1
ditem = PriveSpace(i)
PriveSpace(i) = ditemcl
With ditem
If .Pleft > 0 Then
Hash(.lastpos) = .Pleft
.Key = vbNullString
.Pleft = 0
Else
Hash(.lastpos) = 0
.Key = vbNullString
End If
If .KeyType = 0 And .nDx >= 0 Then
If IsObject(v(.nDx)) Then
Set aa = v(.nDx)
Set v(.nDx) = Nothing
Set aa = v(.nDx)
End If
v(.nDx) = Empty
End If
.KeyType = 0
.globalvar = CByte(0)
.originalType = CByte(0)
.nDx = -1
End With
Next i
If entrance = 1 Then
If MaxSpace >= 6004 Then
If MaxSpace - newTop + 1 > 2 * newTop + 2 Then
If newTop > 3000 Then
MaxSpace = 2 * (newTop + 1) + 1
Else
MaxSpace = 6003
End If
ReDim Preserve PriveSpace(MaxSpace) As item
ReDim Hash(MaxSpace * 2 + 3)
hashlen = MaxSpace * 2 + 3
' reHash...
toplim = newTop - 1
For i = 0 To toplim
place HashFunc2(i), i
Next i
Else
toplim = newTop - 1
End If
Else
toplim = newTop - 1
End If
End If
entrance = entrance - 1
End Sub
Private Function Malloc() As Long
If toplim + 1 >= MaxSpace Then
'' expand hash
MaxSpace = MaxSpace * 2
ReDim Preserve PriveSpace(MaxSpace) As item
If MaxSpace > hashlen Then ExpandHash
End If
toplim = toplim + 1
Malloc = toplim
End Function
Friend Sub Expand(NewMaxSpace As Long)
MaxSpace = NewMaxSpace
ReDim Preserve PriveSpace(MaxSpace) As item
If MaxSpace > hashlen Then ExpandHash
End Sub
Property Get Count()
Count = toplim + 1
End Property
Friend Function Find2(Key As String, num As Long, Optional checktype As Boolean, Optional isglobal As Boolean) As Boolean
Dim k As Long
num = 0
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
If PriveSpace(k).Key = Key Then
num = PriveSpace(k).nDx: Find2 = True: index = k: checktype = PriveSpace(k).originalType: isglobal = PriveSpace(k).globalvar: Exit Function
End If
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
Friend Function Find3(Key As String, num As Long, isglobal As Boolean) As Boolean
Dim k As Long
num = 0
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
If PriveSpace(k).Key = Key Then
num = PriveSpace(k).nDx: Find3 = True: index = k: isglobal = PriveSpace(k).globalvar: Exit Function
End If
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
Friend Function FindOlder(Key As String, num As Long, olderfromthat As Long) As Boolean
Dim k As Long
num = 0
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
If PriveSpace(k).Key = Key And k <= olderfromthat Then
num = PriveSpace(k).nDx: FindOlder = True: index = k: Exit Function
End If
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
Friend Function Find(Key As String, num As Long) As Boolean
Dim k As Long
num = 0
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
If PriveSpace(k).Key = Key Then
num = PriveSpace(k).nDx: Find = True: index = k: Exit Function
End If
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
Friend Function ExistKey(Key As String) As Boolean
Dim k As Long
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
If PriveSpace(k).Key = Key Then ExistKey = True: Exit Function
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
'Friend Function ReBound(newnum As Long) As Boolean
' dengerous... because one can be rebound a newer one, and that is wrong.
'If index > 0 Then
'With PriveSpace(index)
'If .KeyType = 1 Then
' .nDx = newnum
' ReBound = True
'End If
'End With
'End If
'End Function
Friend Function findRebound(Key As String, newnum As Long, v()) As Boolean
Dim k As Long
If Len(Key) = 0 Then Exit Function
k = Hash(HashFunc(Key)) - 1
If k >= 0 Then
Do
With PriveSpace(k)
If .Key = Key Then
If .KeyType = 0 Then
If IsObject(v(.nDx)) Then Set v(.nDx) = Nothing
If newnum <> .nDx Then v(.nDx) = Empty
.KeyType = 1
End If
.nDx = newnum
findRebound = True: Exit Function
End If
End With
k = PriveSpace(k).Pleft - 1
Loop Until k < 0
End If
End Function
Friend Sub ItemCreator(Key As String, num As Long, Optional isRef As Boolean = False, Optional isglobal As Boolean = False, Optional deftype As Boolean = False)
Dim a As Long
a = Malloc()
On Error GoTo exxx
place HashFunc(Key), a
With PriveSpace(a)
.nDx = num
.KeyType = CByte(Abs(isRef))
'If isRef Then
'.originalType = PriveSpace(CByte(deftype)
'Else
.originalType = CByte(deftype)
'End If
.globalvar = CByte(isglobal)
.firsthash = HD(Key)
SwapStrings .Key, Key
End With
index = a
exxx:
End Sub
Friend Sub ItemCreator2(id As idHash, Key As String, num As Long, Optional isRef As Boolean = False, Optional isglobal As Boolean = False, Optional deftype As Boolean = False)
Dim a As Long
a = Malloc()
On Error GoTo exxx
place id.lastHashFunc0 Mod hashlen, a
With PriveSpace(a)
.nDx = num
.KeyType = CByte(Abs(isRef))
.originalType = CByte(deftype)
.globalvar = CByte(isglobal)
.firsthash = HD(Key)
.Key = Key
End With
index = a
exxx:
End Sub
Property Get Percent()
Percent = Count / hashlen
End Property
Private Sub place(ByVal b, ByVal a)
Dim k As Long
k = Hash(b)
If Not Hash(b) = a + 1 Then
Hash(b) = a + 1
PriveSpace(a).Pleft = k
End If
PriveSpace(a).lastpos = b
End Sub
Private Function HashFunc2(where As Long)
HashFunc2 = PriveSpace(where).firsthash Mod hashlen
End Function
Private Function HashFunc(a$)
HashFunc = HD(a$) Mod hashlen
End Function
Sub flat()
index = -1
End Sub
Friend Property Get vType(where As Long) As Boolean
vType = CBool(PriveSpace(where).originalType)
End Property
Friend Property Let vType(where As Long, RHS As Boolean)
If RHS Then
PriveSpace(where).originalType = 255
Else
PriveSpace(where).originalType = 0
End If
End Property