|
|
|
Click here to copy the following block |
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As _ Any, source As Any, ByVal bytes As Long)
Const DEFAULT_HASHSIZE = 1024 Const DEFAULT_LISTSIZE = 2048 Const DEFAULT_CHUNKSIZE = 1024
Option Explicit
Private Type SlotType Key As String Value As Variant nextItem As Long End Type
Dim hashTbl() As Long
Dim slotTable() As SlotType
Dim FreeNdx As Long
Dim m_HashSize As Long
Dim m_ListSize As Long
Dim m_ChunkSize As Long
Dim m_Count As Long
Private m_IgnoreCase As Boolean
Property Get IgnoreCase() As Boolean IgnoreCase = m_IgnoreCase End Property
Property Let IgnoreCase(ByVal newValue As Boolean) If m_Count Then Err.Raise 1001, , "The Hash Table isn't empty" End If m_IgnoreCase = newValue End Property
Sub SetSize(ByVal HashSize As Long, Optional ByVal ListSize As Long, _ Optional ByVal ChunkSize As Long) If ListSize <= 0 Then ListSize = m_ListSize If ChunkSize <= 0 Then ChunkSize = m_ChunkSize m_HashSize = HashSize m_ListSize = ListSize m_ChunkSize = ChunkSize m_Count = 0 FreeNdx = 0 ReDim hashTbl(0 To HashSize - 1) As Long ReDim slotTable(0) As SlotType ExpandSlotTable m_ListSize End Sub
Function Exists(Key As String) As Boolean Exists = GetSlotIndex(Key) <> 0 End Function
Sub Add(Key As String, Value As Variant) Dim ndx As Long, Create As Boolean Create = True ndx = GetSlotIndex(Key, Create) If Create Then If IsObject(Value) Then Set slotTable(ndx).Value = Value Else slotTable(ndx).Value = Value End If Else Err.Raise 457 End If End Sub
Property Get Item(Key As String) As Variant Dim ndx As Long ndx = GetSlotIndex(Key) If ndx = 0 Then ElseIf IsObject(slotTable(ndx).Value) Then Set Item = slotTable(ndx).Value Else Item = slotTable(ndx).Value End If End Property
Property Let Item(Key As String, Value As Variant) Dim ndx As Long ndx = GetSlotIndex(Key, True) slotTable(ndx).Value = Value End Property
Property Set Item(Key As String, Value As Object) Dim ndx As Long ndx = GetSlotIndex(Key, True) Set slotTable(ndx).Value = Value End Property
Sub Remove(Key As String) Dim ndx As Long, HCode As Long, LastNdx As Long ndx = GetSlotIndex(Key, False, HCode, LastNdx) If ndx = 0 Then Err.Raise 5 If LastNdx Then slotTable(LastNdx).nextItem = slotTable(ndx).nextItem ElseIf slotTable(ndx).nextItem Then hashTbl(HCode) = slotTable(ndx).nextItem Else hashTbl(HCode) = 0 End If slotTable(ndx).nextItem = FreeNdx FreeNdx = ndx m_Count = m_Count - 1 End Sub
Sub RemoveAll() SetSize m_HashSize, m_ListSize, m_ChunkSize End Sub
Property Get Count() As Long Count = m_Count End Property
Property Get Keys() As Variant() Dim i As Long, ndx As Long Dim n As Long ReDim res(0 To m_Count - 1) As Variant For i = 0 To m_HashSize - 1 ndx = hashTbl(i) Do While ndx res(n) = slotTable(ndx).Key n = n + 1 ndx = slotTable(ndx).nextItem Loop Next Keys = res() End Property
Property Get Values() As Variant() Dim i As Long, ndx As Long Dim n As Long ReDim res(0 To m_Count - 1) As Variant For i = 0 To m_HashSize - 1 ndx = hashTbl(i) Do While ndx res(n) = slotTable(ndx).Value n = n + 1 ndx = slotTable(ndx).nextItem Loop Next Values = res() End Property
Private Sub Class_Initialize() SetSize DEFAULT_HASHSIZE, DEFAULT_LISTSIZE, DEFAULT_CHUNKSIZE End Sub
Private Sub ExpandSlotTable(ByVal numEls As Long) Dim newFreeNdx As Long, i As Long newFreeNdx = UBound(slotTable) + 1 ReDim Preserve slotTable(0 To UBound(slotTable) + numEls) As SlotType For i = newFreeNdx To UBound(slotTable) slotTable(i).nextItem = i + 1 Next slotTable(UBound(slotTable)).nextItem = FreeNdx FreeNdx = newFreeNdx End Sub
Private Function HashCode(Key As String) As Long Dim lastEl As Long, i As Long lastEl = (Len(Key) - 1) \ 4 ReDim codes(lastEl) As Long CopyMemory codes(0), ByVal Key, Len(Key) For i = 0 To lastEl HashCode = HashCode Xor codes(i) Next End Function
Private Function GetSlotIndex(ByVal Key As String, Optional Create As Boolean, _ Optional HCode As Long, Optional LastNdx As Long) As Long Dim ndx As Long If Len(Key) = 0 Then Err.Raise 1001, , "Invalid key" If m_IgnoreCase Then Key = UCase$(Key) HCode = HashCode(Key) Mod m_HashSize ndx = hashTbl(HCode) Do While ndx If slotTable(ndx).Key = Key Then Exit Do LastNdx = ndx ndx = slotTable(ndx).nextItem Loop If ndx = 0 And Create Then ndx = GetFreeSlot() PrepareSlot ndx, Key, HCode, LastNdx Else Create = False End If GetSlotIndex = ndx
End Function
Private Function GetFreeSlot() As Long If FreeNdx = 0 Then ExpandSlotTable m_ChunkSize GetFreeSlot = FreeNdx FreeNdx = slotTable(GetFreeSlot).nextItem slotTable(GetFreeSlot).nextItem = 0 m_Count = m_Count + 1 End Function
Private Sub PrepareSlot(ByVal Index As Long, ByVal Key As String, _ ByVal HCode As Long, ByVal LastNdx As Long) If m_IgnoreCase Then Key = UCase$(Key) slotTable(Index).Key = Key If LastNdx Then slotTable(LastNdx).nextItem = Index Else hashTbl(HCode) = Index End If End Sub |
|
|
|
Submitted By :
Nayan Patel
(Member Since : 5/26/2004 12:23:06 PM)
|
|
|
Job Description :
He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting. |
View all (893) submissions by this author
(Birth Date : 7/14/1981 ) |
|
|