Update CLAUDE.md, CRC32B.pbi, _ChainedHashMap.pbi, and 1 more file

This commit is contained in:
2026-09-30 22:03:10 +02:00
parent 0fde87a616
commit 605c4d1739
4 changed files with 226 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
EnableExplicit
#HashMap_InitialPower = 9
#HashMap_InsertIterations = 100000
;{
Structure ChainedHashMapBucket
*BucketData
*Next.ChainedHashMapBucket
Hash.q
EndStructure
Structure ChainedHashMap
EntryCount.i
Capacity.i
SizePower.a
*Buckets.ChainedHashMapBucket[0]
EndStructure
Prototype CbFree(*Data)
Procedure.l MakeBitMask(BitCount.b)
EnableASM
MOV eax, $00000001
MOV cl, BitCount
SHL eax, cl
DEC eax
ProcedureReturn
DisableASM
EndProcedure
Procedure.i CHM_Create(SizePower.b)
Protected *CHM.ChainedHashMap = AllocateMemory(SizeOf(ChainedHashMap) + (SizeOf(Integer) * (MakeBitMask(SizePower) + 1)))
If *CHM <> #Null
*CHM\EntryCount = 0
*CHM\SizePower = SizePower
Protected iBucket
For iBucket = 0 To MakeBitMask(SizePower)
*CHM\Buckets[iBucket] = #Null
Next
EndIf
ProcedureReturn *CHM
EndProcedure
Procedure.i CHM_GetByHash(*CHM.ChainedHashMap, Hash.q)
If *CHM <> #Null
Protected *CurrentBucket.ChainedHashMapBucket = *CHM\Buckets[(Hash & MakeBitMask(*CHM\SizePower))]
While *CurrentBucket <> #Null
If *CurrentBucket\Hash = Hash
ProcedureReturn *CurrentBucket\BucketData
EndIf
*CurrentBucket = *CurrentBucket\Next
Wend
EndIf
ProcedureReturn #Null
EndProcedure
Procedure.b CHM_OverwriteByHash(*CHM.ChainedHashMap, *Data, Hash.q, *FreeingCallback.CbFree = #Null)
If *CHM <> #Null
Protected *PreviousBucket.ChainedHashMapBucket = #Null
Protected *CurrentBucket.ChainedHashMapBucket = *CHM\Buckets[(Hash & MakeBitMask(*CHM\SizePower))]
; We iterate over the bucket chain until we find a collision or an in-between.
While *CurrentBucket <> #Null
If *CurrentBucket\Hash >= Hash
Break
EndIf
*PreviousBucket = *CurrentBucket
*CurrentBucket = *CurrentBucket\Next
Wend
If *CurrentBucket = #Null Or *CurrentBucket\Hash <> Hash
; We either reached the end of the list, or no buckets was in the current slot.
; Or, we have an in-between, or we are at the start of the list.
Protected *NewBucket.ChainedHashMapBucket = AllocateMemory(SizeOf(ChainedHashMapBucket))
If *NewBucket <> #Null
*NewBucket\Next = *CurrentBucket
*NewBucket\BucketData = *Data
*NewBucket\Hash = Hash
If *PreviousBucket <> #Null
; In-between, or we are at the start of the List.
*PreviousBucket\Next = *NewBucket
Else
; Start of the list.
*CHM\Buckets[(Hash & MakeBitMask(*CHM\SizePower))] = *NewBucket
EndIf
*CHM\EntryCount = *CHM\EntryCount + 1
ProcedureReturn #True
EndIf
ElseIf *FreeingCallback <> #Null
; Handling collision.
CallFunctionFast(*FreeingCallback, *CurrentBucket\BucketData)
*CurrentBucket\BucketData = *Data
ProcedureReturn #True
EndIf
; Implied else: Handling collision while forbidden to overwrite => doing nothing.
EndIf
ProcedureReturn #False
EndProcedure
Procedure CHM_DeleteByHash(*CHM.ChainedHashMap, Hash.q)
EndProcedure
Procedure CHM_Free(*CHM.ChainedHashMap)
EndProcedure
Procedure NoopFree(*Data) : EndProcedure