WIN32汇编实现的HashTable

 

HashTableAdd proto pHashStruct:dword,pKey:dword,pValue:dword

.data

 HashSizeTable  dword 11,23,47,97,197,397,797,1597,3203,6421,12853,25717,51437,102877,205759,411527
 
   HashPrimeTable dword 103,101,97,91,89,87,83,79,73,71,67,61,59,57,53,51,47,43,41,39,37,31,29,23,/
         19,17,13,11,7,5,2,1
   
 HashStruct struct
  curSize   dword 0
  curMaxSize   dword 11
  curSizeIndex dword 0
  cSizeTable  dword 16
  pSizeTable  dword offset HashSizeTable  
  pPrimeTable  dword offset HashPrimeTable
  pInteralArray dword 0
 HashStruct ends
  
.code

CreateInteralArray proc pHashStruct:dword  

 ;invoke INFODEBUG,SADD("CreateInteralArray")
 
 ;create addr array with the init size to save addr of keys and addr of values
 mov edx,pHashStruct
 mov ecx,(HashStruct ptr [edx]).curMaxSize
 shl ecx,3 ;mul 8(=4+4)
 push edx
 invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,ecx 
 pop edx
 mov (HashStruct ptr [edx]).pInteralArray,eax  
 ret
CreateInteralArray endp

ResizeInteralArrayAndReHashIt proc pHashStruct:dword

 LOCAL oldSize:dword
 LOCAL oldParray:dword
 LOCAL newParray:dword
 
 ;invoke INFODEBUG,SADD("ResizeInteralArrayAndReHashIt")
 
 mov edx,pHashStruct
 
 mov eax,(HashStruct ptr [edx]).pInteralArray
 mov oldParray,eax
 mov eax,(HashStruct ptr [edx]).curMaxSize
 mov oldSize,eax
 
 ;;;;create new array 
 mov ecx,(HashStruct ptr [edx]).curSizeIndex
 mov ebx,(HashStruct ptr [edx]).pSizeTable
 
 inc ecx 
 mov eax,(HashStruct ptr [edx]).cSizeTable
 .if  ecx >= eax
  jmp overmax         ;数组大小到达了最大值
 .endif
 
 
 
 mov (HashStruct ptr [edx]).curSizeIndex,ecx ;set new sizeindex  

 mov eax,[ebx+ecx*4]       ;ebx+ecx*4 = new size addr
 mov (HashStruct ptr [edx]).curMaxSize,eax ;and set
 
 
 shl eax,3         ;mul 8(=4+4)  
 invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,eax ;new array with new size
 mov newParray,eax
 
 
 mov edx,pHashStruct 
 mov (HashStruct ptr [edx]).pInteralArray,eax;set new array
 xor eax,eax
 mov (HashStruct ptr [edx]).curSize,eax;set new array's item count to 0 
 
 ;;;;rehash old data and copy  to new array 

 mov ecx,oldSize   ;COUNT
 mov edx,oldParray  ;START
 xor ebx,ebx    ;INIT COUNT

 .while ebx < ecx
  mov eax,[edx+ebx*8]
  .if eax == 0   ;for check pkey 
   inc ebx
   .continue
  .endif
   
  pusha  
  mov ebx,[edx+ebx*8+4] ;pval 
  invoke HashTableAdd,pHashStruct,eax,ebx ;call Interap with each Item
  popa
  
  inc ebx 
 .endw
 
 
 ;invoke INFODEBUG,SADD("ResizeInteralArrayAndReHashIt to ")
 mov edx,pHashStruct
 invoke INFODEBUG2,(HashStruct ptr [edx]).curMaxSize

 invoke GlobalFree,oldParray  
 mov eax,newParray ;return the pointer of the resized InteralArray
 ret
overmax:
 ;invoke INFODEBUG,SADD("数组大小到达了最大值")
 mov eax,0
 ret 
ResizeInteralArrayAndReHashIt endp


FreeHashTable proc pHashStruct:dword
 local pArray:dword
 mov edx,pHashStruct
 mov eax,(HashStruct ptr [edx]).pInteralArray
 mov pArray,eax
 
 invoke GlobalFree,pArray
 invoke GlobalFree,pHashStruct 
 xor eax,eax
 ret
FreeHashTable endp

CreateHashTable proc
 local pHashStruct:dword 
 
 ;invoke INFODEBUG,SADD("CreateHashTable")

 invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,sizeof HashStruct
 mov pHashStruct,eax

 mov (HashStruct ptr [eax]).curSize,0
 mov (HashStruct ptr [eax]).curMaxSize,11
 mov (HashStruct ptr [eax]).curSizeIndex,0
 mov (HashStruct ptr [eax]).cSizeTable,16
 mov (HashStruct ptr [eax]).pSizeTable,offset HashSizeTable
 mov (HashStruct ptr [eax]).pPrimeTable,offset HashPrimeTable
 mov (HashStruct ptr [eax]).pInteralArray,0

  
 invoke CreateInteralArray,pHashStruct
  
 mov eax,pHashStruct 
 ret
CreateHashTable endp


HashFunc proc pHashStruct:dword,pKey:dword
 LOCAL ttl:DWORD
 LOCAL prms:DWORD
 LOCAL cnt:DWORD
 
  ;invoke INFODEBUG,SADD("HashFunc")
  
 mov edx,pHashStruct
 mov eax,(HashStruct ptr [edx]).pPrimeTable
 mov prms,eax
 mov eax,(HashStruct ptr [edx]).curMaxSize
 mov cnt,eax 
 
    push ebx
    push esi
    push edi

    mov ttl, 0                  ; total

    mov esi, pKey
    mov edi, prms               ; array of primes address in EDI
    xor ecx, ecx                ; zero character counter
    xor ebx, ebx                ; prevent stall in EBX
  @@:
    movzx eax, BYTE PTR [esi+ecx]
    add ecx, 1                  ; increment the character position counter
    mov ebx, [edi+ecx*4]        ; get value of prime from character position  
    imul bx                     ; mul char ascii value by prime
    add ttl, eax                ; add result to total
   
    cmp eax, 0
    jne @B

  ; -------------------------------
  ; added to deliver larger numbers
  ; -------------------------------
    mov ecx, ttl
    shl ecx, 13
    add ttl, ecx
   
   

  ; ------------------------------------------------------------
  ; divide total by array count and return the remainder in EAX
  ; ------------------------------------------------------------
    xor edx, edx
    mov eax, ttl
    div cnt
      
    mov eax, edx
   

    pop edi
    pop esi
    pop ebx
 
 ret   ;return the hashcode of the key pointerd by pKey
HashFunc endp

HashTableAdd proc pHashStruct:dword,pKey:dword,pValue:dword
 
    LOCAL hkey:DWORD 
    LOCAL pArray:DWORD
    LOCAL cnt:DWORD

 ;invoke INFODEBUG,SADD("HashTableAdd")
 
    ;
    ;.if pHashStruct.curSize > curMaxSize * 72 / 100
    ; invoke ResizeInteralArray,pHashStruct
    ;.endif      
   
    mov edx,pHashStruct  
 mov eax,(HashStruct ptr [edx]).pInteralArray
 mov pArray,eax
 mov eax,(HashStruct ptr [edx]).curMaxSize
 mov cnt,eax 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;check size decide if need to resieze  InteralArray
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 mov ecx,72
 imul ecx  ;eax*ecx = curMaxSize * 72
 mov ecx,eax  ;save to ecx 

 mov edx,pHashStruct
 mov eax,(HashStruct ptr [edx]).curSize
 mov edx,100
 imul edx  ;eax*edx = curSize * 100
     ;save to eax  
 .if eax > ecx  
  jmp toresize  
 .endif

resized:
    invoke HashFunc,pHashStruct,pKey
    mov hkey,eax   
  wttstart:
   mov eax,hkey       
    mov edx, pArray     ;
    xor ecx,ecx
    mov ecx,dword ptr [edx+eax*8]            ; get  key addr which index of eax
 
    .if ecx == 0              ; the index of  hkey is blanck then
     jmp write_string             ; jump to "write string"  
    .endif
   
    invoke lstrcmp,ecx,pKey   ; compare the old key in the same index with the newKey  
    .if eax == 0  
     ;invoke INFODEBUG,SADD("已经存在")
     jmp wtEnd                    ; exit procedure if the same      
    .endif ;//
           
    add hkey, 1                     ; if collision,    
    ;invoke INFODEBUG,SADD("+1")
   
    mov eax,hkey
    .if eax == cnt
    ;invoke INFODEBUG,SADD("最大,跳到0")
    mov hkey,0     
   .endif ;
    jmp wttstart                    ; try next location in hash table

  write_string:
 
   mov eax,hkey
   mov edx,pArray   

    mov ecx,pValue 
    mov [edx+eax*8+4],ecx
    mov ecx,pKey         ; write pkey to location in hash table
    mov [edx+eax*8],ecx
 
   mov edx,pHashStruct
 mov ecx,(HashStruct ptr [edx]).curSize
 inc ecx
 mov (HashStruct ptr [edx]).curSize,ecx
  
;  PUSHA
;   invoke INFODEBUG21,ecx
;   invoke INFODEBUG11,SADD(":")
;   invoke INFODEBUG21,hkey
;   invoke INFODEBUG11,SADD(";")
;   invoke INFODEBUG11,pKey
;   invoke INFODEBUG11,SADD(":")
;   invoke INFODEBUG,pValue
;  popa
 
 xor eax,eax ;ok
 ret


toresize:

 invoke ResizeInteralArrayAndReHashIt,pHashStruct 
 .if eax == 0
  invoke FreeHashTable,pHashStruct
  jmp wtEnd 
 .endif ;//
 
 mov edx,pHashStruct  
 mov eax,(HashStruct ptr [edx]).pInteralArray
 mov pArray,eax
 mov eax,(HashStruct ptr [edx]).curMaxSize
 mov cnt,eax 
 
 
 jmp resized
  
  wtEnd:   
 mov eax,1 ;exists 
 ret
 

HashTableAdd endp


HashGethkeyForRead proc pHashStruct:dword,pKey:dword
 LOCAL item:DWORD
    LOCAL hkey:DWORD 
    LOCAL pArray:DWORD
    LOCAL cnt:DWORD
   
     ;invoke INFODEBUG,SADD("HashGethkeyForRead")
     
 mov edx,pHashStruct 
 mov eax,(HashStruct ptr [edx]).curMaxSize
 mov cnt,eax 
 mov eax,(HashStruct ptr [edx]).pInteralArray
 mov pArray,eax
 
    invoke HashFunc,pHashStruct,pKey
    mov hkey,eax
  
wttstart:
 mov eax,hkey
   .if eax == cnt
    mov hkey,0
    mov eax,hkey      
   .endif ;//  
    
    mov edx, pArray     ;
    mov ecx, [edx+eax*8]            ; get  key addr which index of eax
     
    cmp ecx, 0              ; the index of  hkey is blanck then
    je no_exists                    ; jump to "no_exists"
 
 invoke lstrcmp,ecx,pKey
    .if eax != 0     ; compare the old key in the same index with the newKey
     jmp refind                      ; refind if not same
    .else
     mov eax,hkey  
     ret
    .endif 
   
 refind:
  
  add hkey, 1                     ;
  mov eax,hkey
  inc eax
  .if eax < cnt     ;
     jmp wttstart                     ;
  .endif        ; no find
 no_exists:  
 mov eax,0      ;
 ret
HashGethkeyForRead endp

HashTableGet proc pHashStruct:dword,pKey:dword

;invoke INFODEBUG,SADD("HashTableGet")

 invoke HashGethkeyForRead,pHashStruct,pKey 
 .if eax == 0  
  ret 
 .endif
 mov ecx,eax
 
 mov edx,pHashStruct 
 mov ebx,(HashStruct ptr [edx]).pInteralArray
 
 mov eax,[ebx+ecx*8+4] ;pInteralArray + phkey*8 + 4 = addr of pval
   
 ret 
 

 
HashTableGet endp

 

HashTableExists proc pHashStruct:dword,pKey:dword 
 invoke HashGethkeyForRead,pHashStruct,pKey
 
 ret
HashTableExists endp

HashTableDel proc pHashStruct:dword,pKey:dword
 invoke HashGethkeyForRead,pHashStruct,pKey
 cmp eax,0
 je nofind
 
 mov edx,pHashStruct 
 mov ebx,(HashStruct ptr [edx]).pInteralArray
  
 mov dword ptr [ebx+eax*8],0  ;pInteralArray + phkey*8  = addr of pkey    
 mov dword ptr [ebx+eax*8+4],0 ;pInteralArray + phkey*8 + 4 = addr of pval
 
 mov ecx,(HashStruct ptr [edx]).curSize
 dec ecx
 mov (HashStruct ptr [edx]).curSize,ecx
 
 xor eax,eax  ;deled
 ret
nofind: 
 mov eax,1
 ret
HashTableDel endp

HashTableEach proc pHashStruct:dword,pInterap:dword
    mov edx,pHashStruct    

 mov ecx,(HashStruct ptr [edx]).curMaxSize  ;COUNT 
 mov eax,(HashStruct ptr [edx]).pInteralArray ;POINTER
 mov edx,eax
 
 xor ebx,ebx          ;INIT COUNT 
 .while ebx < ecx
  mov eax,[edx+ebx*8]
  .if eax == 0   ;for check if exists
   inc ebx
   .continue
  .endif
    
  push ecx
  push edx
  push ebx
  
  ;;edx+ebx*8
  mov eax,ebx
  shl eax,3
  add eax,edx
  
  add eax,4
  push eax
  sub eax,4
  push eax  ;call Interap with each  addr of the addr of pkey
  
  call pInterap 
  
  
  pop ebx
  pop edx
  pop ecx
  
  inc ebx
 .endw
 
 ret
HashTableEach endp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值