n_cst_hash_blob.sru 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. $PBExportHeader$n_cst_hash_blob.sru
  2. forward
  3. global type n_cst_hash_blob from nonvisualobject
  4. end type
  5. end forward
  6. global type n_cst_hash_blob from nonvisualobject
  7. event type n_cst_hash_blob_entry ue_get_hash_entry ( readonly blob ab_key )
  8. event type n_cst_hash_blob_entry ue_create_entry ( )
  9. end type
  10. global n_cst_hash_blob n_cst_hash_blob
  11. type variables
  12. PRIVATE n_cst_hash_blob_entry invo_fields[]
  13. PRIVATE LONG il_field_max_value = 7
  14. PRIVATE LONG il_field_count
  15. PRIVATE LONG il_max_capacity = -1
  16. end variables
  17. forward prototypes
  18. public function long of_get_capacity ()
  19. public function boolean of_key_exists (readonly blob ab_key)
  20. public function unsignedlong of_hash (readonly blob ab_key)
  21. protected function integer of_extend_hash (long al_power)
  22. public function integer of_delete_key (readonly blob ab_key)
  23. public function n_cst_hash_blob_entry of_find_hash_entry (readonly blob ab_key)
  24. public function long of_get_keys (ref blob ab_keys[])
  25. protected function integer of_set_capacity (long al_new_capacity)
  26. protected function integer of_set_max_capacity (long al_new_max_capacity)
  27. end prototypes
  28. event type n_cst_hash_blob_entry ue_get_hash_entry(readonly blob ab_key);ulong ll_h
  29. ulong ll_i
  30. n_cst_hash_blob_entry lnvo_cur_entry
  31. n_cst_hash_blob_entry ret
  32. setnull(ret)
  33. if il_field_count > il_field_max_value then
  34. of_extend_hash(1)
  35. end if
  36. ll_h = of_hash(ab_key)
  37. ll_i = mod(ll_h, il_field_max_value) + 1
  38. lnvo_cur_entry = invo_fields[ll_i]
  39. do while not isnull(lnvo_cur_entry)
  40. if lnvo_cur_entry.il_hash = ll_h then
  41. if lnvo_cur_entry.ib_key = ab_key then
  42. ret = lnvo_cur_entry
  43. exit
  44. end if
  45. end if
  46. lnvo_cur_entry = lnvo_cur_entry.invo_next
  47. loop
  48. if isnull(ret) then
  49. ret = event ue_create_entry()
  50. il_field_count ++
  51. ret.invo_next = invo_fields[ll_i]
  52. ret.il_hash = ll_h
  53. ret.ib_key = ab_key
  54. invo_fields[ll_i] = ret
  55. end if
  56. return ret
  57. end event
  58. event type n_cst_hash_blob_entry ue_create_entry();n_cst_hash_blob_entry ret
  59. setnull(ret)
  60. return ret
  61. end event
  62. public function long of_get_capacity ();return il_field_max_value + 1
  63. end function
  64. public function boolean of_key_exists (readonly blob ab_key);ulong ll_h
  65. ulong ll_i
  66. n_cst_hash_blob_entry lnvo_entry
  67. ll_h = of_hash(ab_key)
  68. ll_i = mod(ll_h, il_field_max_value) + 1
  69. lnvo_entry = invo_fields[ll_i]
  70. do while not isnull(lnvo_entry)
  71. if lnvo_entry.il_hash = ll_h then
  72. if lnvo_entry.ib_key = ab_key then
  73. return true
  74. end if
  75. end if
  76. lnvo_entry = lnvo_entry.invo_next
  77. loop
  78. return false
  79. end function
  80. public function unsignedlong of_hash (readonly blob ab_key);ulong ll_i
  81. ulong ll_len
  82. ulong ll_ret
  83. ll_len = len(ab_key)
  84. for ll_i = 1 to ll_len
  85. ll_ret = 33 * ll_ret + asc(char(blobmid(ab_key, ll_i, 1)))
  86. next
  87. ll_ret = ll_ret + ll_ret / 32
  88. return ll_ret
  89. end function
  90. protected function integer of_extend_hash (long al_power);ulong ll_i
  91. ulong ll_old_size
  92. ulong ll_new_size
  93. ulong ll_new_pos
  94. n_cst_hash_blob_entry lnvo_cur_entry
  95. n_cst_hash_blob_entry lnvo_prev_entry
  96. n_cst_hash_blob_entry lnvo_next_entry
  97. ll_old_size = il_field_max_value + 1
  98. ll_new_size = ll_old_size * 2 ^ al_power
  99. if ll_new_size > il_max_capacity and il_max_capacity <> -1 then
  100. return -1
  101. end if
  102. il_field_max_value = ll_new_size - 1
  103. for ll_i = ll_old_size + 1 to ll_new_size
  104. setnull(invo_fields[ll_i])
  105. next
  106. for ll_i = 1 to ll_old_size
  107. lnvo_cur_entry = invo_fields[ll_i]
  108. setnull(lnvo_prev_entry)
  109. do while not isnull(lnvo_cur_entry)
  110. ll_new_pos = mod(lnvo_cur_entry.il_hash, il_field_max_value) + 1
  111. if ll_new_pos <> ll_i then
  112. if lnvo_cur_entry = invo_fields[ll_i] then
  113. invo_fields[ll_i] = lnvo_cur_entry.invo_next
  114. lnvo_next_entry = lnvo_cur_entry.invo_next
  115. else
  116. lnvo_prev_entry.invo_next = lnvo_cur_entry.invo_next
  117. lnvo_next_entry = lnvo_cur_entry.invo_next
  118. end if
  119. lnvo_cur_entry.invo_next = invo_fields[ll_new_pos]
  120. invo_fields[ll_new_pos] = lnvo_cur_entry
  121. else
  122. lnvo_prev_entry = lnvo_cur_entry
  123. lnvo_next_entry = lnvo_cur_entry.invo_next
  124. end if
  125. lnvo_cur_entry = lnvo_next_entry
  126. loop
  127. next
  128. return 1
  129. end function
  130. public function integer of_delete_key (readonly blob ab_key);n_cst_hash_blob_entry lnvo_cur_entry
  131. n_cst_hash_blob_entry lnvo_prev_entry
  132. n_cst_hash_blob_entry lnvo_next_entry
  133. ULONG ll_h
  134. ULONG ll_i
  135. ll_h = of_hash(ab_key)
  136. ll_i = MOD(ll_h, il_field_max_value) + 1
  137. lnvo_cur_entry = invo_fields[ll_i]
  138. SETNULL(lnvo_prev_entry)
  139. DO while NOT ISNULL(lnvo_cur_entry)
  140. IF lnvo_cur_entry.il_hash = ll_h THEN
  141. IF lnvo_cur_entry.ib_key = ab_key THEN
  142. IF lnvo_cur_entry = invo_fields[ll_i] THEN
  143. invo_fields[ll_i] = lnvo_cur_entry.invo_next
  144. lnvo_next_entry = lnvo_cur_entry.invo_next
  145. ELSE
  146. lnvo_prev_entry.invo_next = lnvo_cur_entry.invo_next
  147. lnvo_next_entry = lnvo_cur_entry.invo_next
  148. END IF
  149. il_field_count --
  150. DESTROY(lnvo_cur_entry)
  151. ELSE
  152. lnvo_prev_entry = lnvo_cur_entry
  153. lnvo_next_entry = lnvo_cur_entry.invo_next
  154. END IF
  155. ELSE
  156. lnvo_prev_entry = lnvo_cur_entry
  157. lnvo_next_entry = lnvo_cur_entry.invo_next
  158. END IF
  159. lnvo_cur_entry = lnvo_next_entry
  160. LOOP
  161. RETURN 1
  162. end function
  163. public function n_cst_hash_blob_entry of_find_hash_entry (readonly blob ab_key);ulong ll_h
  164. ulong ll_i
  165. n_cst_hash_blob_entry lnvo_cur_entry
  166. n_cst_hash_blob_entry ret
  167. setnull(ret)
  168. ll_h = of_hash(ab_key)
  169. ll_i = mod(ll_h, il_field_max_value) + 1
  170. lnvo_cur_entry = invo_fields[ll_i]
  171. do while not isnull(lnvo_cur_entry)
  172. if lnvo_cur_entry.il_hash = ll_h then
  173. if lnvo_cur_entry.ib_key = ab_key then
  174. ret = lnvo_cur_entry
  175. exit
  176. end if
  177. end if
  178. lnvo_cur_entry = lnvo_cur_entry.invo_next
  179. loop
  180. return ret
  181. end function
  182. public function long of_get_keys (ref blob ab_keys[]);blob lb_ret[]
  183. long ll_cnt
  184. long ll_i
  185. n_cst_hash_blob_entry lnvo_cur_entry
  186. ll_cnt = 0
  187. for ll_i = 1 to il_field_max_value + 1
  188. lnvo_cur_entry = invo_fields[ll_i]
  189. do while not isnull(lnvo_cur_entry)
  190. ll_cnt ++
  191. lb_ret[ll_cnt] = lnvo_cur_entry.ib_key
  192. lnvo_cur_entry = lnvo_cur_entry.invo_next
  193. loop
  194. next
  195. ab_keys = lb_ret
  196. return ll_cnt
  197. end function
  198. protected function integer of_set_capacity (long al_new_capacity);long ll_power
  199. long ll_capacity
  200. ll_capacity = of_get_capacity()
  201. if al_new_capacity > ll_capacity then
  202. ll_power = 1 + truncate(log(al_new_capacity - 1) / log(2) - log(ll_capacity) / log(2) + 0.00001, 0)
  203. if ll_power > 0 then
  204. return of_extend_hash(ll_power)
  205. end if
  206. end if
  207. return 1
  208. end function
  209. protected function integer of_set_max_capacity (long al_new_max_capacity);long ll_capacity
  210. if al_new_max_capacity < 0 then
  211. il_max_capacity = -1
  212. else
  213. ll_capacity = of_get_capacity()
  214. if al_new_max_capacity < ll_capacity then
  215. il_max_capacity = ll_capacity
  216. else
  217. il_max_capacity = al_new_max_capacity
  218. end if
  219. end if
  220. return 1
  221. end function
  222. on n_cst_hash_blob.create
  223. call super::create
  224. TriggerEvent( this, "constructor" )
  225. end on
  226. on n_cst_hash_blob.destroy
  227. TriggerEvent( this, "destructor" )
  228. call super::destroy
  229. end on
  230. event constructor;LONG ll_i
  231. FOR ll_i = 1 TO il_field_max_value + 1
  232. SETNULL(invo_fields[ll_i])
  233. NEXT
  234. end event
  235. event destructor;long ll_i
  236. n_cst_hash_blob_entry lnvo_cur_entry
  237. for ll_i = 1 to il_field_max_value + 1
  238. do While not isnull(invo_fields[ll_i])
  239. lnvo_cur_entry = invo_fields[ll_i]
  240. invo_fields[ll_i] = lnvo_cur_entry.invo_next
  241. destroy(lnvo_cur_entry)
  242. loop
  243. next
  244. return 1
  245. end event