n_cst_hash.sru 7.6 KB

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