$PBExportHeader$n_cst_hash.sru forward global type n_cst_hash from nonvisualobject end type end forward global type n_cst_hash from nonvisualobject end type global n_cst_hash n_cst_hash type variables PRIVATE n_cst_hash_entry invo_fields[] PRIVATE LONG il_field_max_value = 7 PRIVATE LONG il_field_count PRIVATE LONG il_max_capacity = -1 end variables forward prototypes public function boolean of_key_exists (readonly string as_key) public function long of_get_capacity () public function long of_get_keys (ref string as_keys[]) public function integer of_delete_key (readonly string as_key) public function n_cst_hash_entry of_find_hash_entry (readonly string as_key) public function n_cst_hash_entry of_get_hash_entry (readonly string as_key) public function ulong of_hash (readonly string as_key) protected function integer of_set_capacity (long al_new_capacity) protected function integer of_set_max_capacity (long al_new_max_capacity) protected function n_cst_hash_entry of_create_entry () protected function integer of_extend_hash (long al_power) end prototypes public function boolean of_key_exists (readonly string as_key);ulong ll_h ulong ll_i n_cst_hash_entry lnvo_entry ll_h = of_hash(as_key) ll_i = mod(ll_h, il_field_max_value) + 1 lnvo_entry = invo_fields[ll_i] //do until not isnull(lnvo_entry) do while not isnull(lnvo_entry) if lnvo_entry.il_hash = ll_h then if lnvo_entry.is_key = as_key then return true end if end if lnvo_entry = lnvo_entry.invo_next loop return false end function public function long of_get_capacity ();return il_field_max_value + 1 end function public function long of_get_keys (ref string as_keys[]);string ls_ret[] long ll_cnt long ll_i n_cst_hash_entry lnvo_cur_entry ll_cnt = 0 for ll_i = 1 to il_field_max_value + 1 lnvo_cur_entry = invo_fields[ll_i] do while not isnull(lnvo_cur_entry) ll_cnt ++ ls_ret[ll_cnt] = lnvo_cur_entry.is_key lnvo_cur_entry = lnvo_cur_entry.invo_next loop next as_keys = ls_ret return ll_cnt end function public function integer of_delete_key (readonly string as_key);n_cst_hash_entry lnvo_cur_entry n_cst_hash_entry lnvo_prev_entry n_cst_hash_entry lnvo_next_entry ulong ll_h ulong ll_i ll_h = of_hash(as_key) ll_i = mod(ll_h, il_field_max_value) + 1 lnvo_cur_entry = invo_fields[ll_i] setnull(lnvo_prev_entry) do while not isnull(lnvo_cur_entry) if lnvo_cur_entry.il_hash = ll_h then if lnvo_cur_entry.is_key = as_key then if lnvo_cur_entry = invo_fields[ll_i] then invo_fields[ll_i] = lnvo_cur_entry.invo_next lnvo_next_entry = lnvo_cur_entry.invo_next else lnvo_prev_entry.invo_next = lnvo_cur_entry.invo_next lnvo_next_entry = lnvo_cur_entry.invo_next end if il_field_count -- destroy(lnvo_cur_entry) else lnvo_prev_entry = lnvo_cur_entry lnvo_next_entry = lnvo_cur_entry.invo_next end if else lnvo_prev_entry = lnvo_cur_entry lnvo_next_entry = lnvo_cur_entry.invo_next end if lnvo_cur_entry = lnvo_next_entry loop return 1 end function public function n_cst_hash_entry of_find_hash_entry (readonly string as_key);ulong ll_h ulong ll_i n_cst_hash_entry lnvo_cur_entry n_cst_hash_entry ret setnull(ret) ll_h = of_hash(as_key) ll_i = mod(ll_h, il_field_max_value) + 1 lnvo_cur_entry = invo_fields[ll_i] do while not isnull(lnvo_cur_entry) if lnvo_cur_entry.il_hash = ll_h then if lnvo_cur_entry.is_key = as_key then ret = lnvo_cur_entry exit end if end if lnvo_cur_entry = lnvo_cur_entry.invo_next loop return ret end function public function n_cst_hash_entry of_get_hash_entry (readonly string as_key);ulong ll_h ulong ll_i n_cst_hash_entry lnvo_cur_entry n_cst_hash_entry ret setnull(ret) if il_field_count > il_field_max_value then of_extend_hash(1) end if ll_h = of_hash(as_key) ll_i = mod(ll_h, il_field_max_value) + 1 lnvo_cur_entry = invo_fields[ll_i] do while not isnull(lnvo_cur_entry) if lnvo_cur_entry.il_hash = ll_h then if lnvo_cur_entry.is_key = as_key then ret = lnvo_cur_entry exit end if end if lnvo_cur_entry = lnvo_cur_entry.invo_next loop if isnull(ret) then ret = of_create_entry() il_field_count ++ ret.invo_next = invo_fields[ll_i] ret.il_hash = ll_h ret.is_key = as_key invo_fields[ll_i] = ret end if return ret end function public function ulong of_hash (readonly string as_key);ulong ll_i ulong ll_len ulong ll_ret ll_len = len(as_key) for ll_i = 1 to ll_len ll_ret = 33 * ll_ret + asc(mid(as_key, ll_i, 1)) next ll_ret = ll_ret + ll_ret / 32 return ll_ret end function protected function integer of_set_capacity (long al_new_capacity);long ll_power long ll_capacity ll_capacity = of_get_capacity() if al_new_capacity > ll_capacity then ll_power = 1 + truncate(log(al_new_capacity - 1) / log(2) - log(ll_capacity) / log(2) + 0.00001, 0) if ll_power > 0 then return of_extend_hash(ll_power) end if end if return 1 end function protected function integer of_set_max_capacity (long al_new_max_capacity);long ll_capacity if al_new_max_capacity < 0 then il_max_capacity = -1 else ll_capacity = of_get_capacity() if al_new_max_capacity < ll_capacity then il_max_capacity = ll_capacity else il_max_capacity = al_new_max_capacity end if end if return 1 end function protected function n_cst_hash_entry of_create_entry ();n_cst_hash_entry ret setnull(ret) return ret end function protected function integer of_extend_hash (long al_power);ulong ll_i ulong ll_old_size ulong ll_new_size ulong ll_new_pos n_cst_hash_entry lnvo_cur_entry n_cst_hash_entry lnvo_prev_entry n_cst_hash_entry lnvo_next_entry ll_old_size = il_field_max_value + 1 ll_new_size = ll_old_size * 2 ^ al_power if ll_new_size > il_max_capacity and il_max_capacity <> -1 then return -1 end if il_field_max_value = ll_new_size - 1 for ll_i = ll_old_size + 1 to ll_new_size setnull(invo_fields[ll_i]) next for ll_i = 1 to ll_old_size lnvo_cur_entry = invo_fields[ll_i] setnull(lnvo_prev_entry) do while not isnull(lnvo_cur_entry) ll_new_pos = mod(lnvo_cur_entry.il_hash, il_field_max_value) + 1 if ll_new_pos <> ll_i then if lnvo_cur_entry = invo_fields[ll_i] then invo_fields[ll_i] = lnvo_cur_entry.invo_next lnvo_next_entry = lnvo_cur_entry.invo_next else lnvo_prev_entry.invo_next = lnvo_cur_entry.invo_next lnvo_next_entry = lnvo_cur_entry.invo_next end if lnvo_cur_entry.invo_next = invo_fields[ll_new_pos] invo_fields[ll_new_pos] = lnvo_cur_entry else lnvo_prev_entry = lnvo_cur_entry lnvo_next_entry = lnvo_cur_entry.invo_next end if lnvo_cur_entry = lnvo_next_entry loop next return 1 end function on n_cst_hash.create call super::create TriggerEvent( this, "constructor" ) end on on n_cst_hash.destroy TriggerEvent( this, "destructor" ) call super::destroy end on event constructor;LONG ll_i FOR ll_i = 1 TO il_field_max_value + 1 SETNULL(invo_fields[ll_i]) NEXT end event event destructor;LONG ll_i n_cst_hash_entry lnvo_cur_entry FOR ll_i = 1 TO il_field_max_value + 1 // DO UNTIL NOT ISNULL(invo_fields[ll_i]) DO while NOT ISNULL(invo_fields[ll_i]) lnvo_cur_entry = invo_fields[ll_i] invo_fields[ll_i] = lnvo_cur_entry.invo_next DESTROY(lnvo_cur_entry) LOOP NEXT RETURN 1 end event