$PBExportHeader$n_cst_hash_blob.sru forward global type n_cst_hash_blob from nonvisualobject end type end forward global type n_cst_hash_blob from nonvisualobject event type n_cst_hash_blob_entry ue_get_hash_entry ( readonly blob ab_key ) event type n_cst_hash_blob_entry ue_create_entry ( ) end type global n_cst_hash_blob n_cst_hash_blob type variables PRIVATE n_cst_hash_blob_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 long of_get_capacity () public function boolean of_key_exists (readonly blob ab_key) public function unsignedlong of_hash (readonly blob ab_key) protected function integer of_extend_hash (long al_power) public function integer of_delete_key (readonly blob ab_key) public function n_cst_hash_blob_entry of_find_hash_entry (readonly blob ab_key) public function long of_get_keys (ref blob ab_keys[]) protected function integer of_set_capacity (long al_new_capacity) protected function integer of_set_max_capacity (long al_new_max_capacity) end prototypes event type n_cst_hash_blob_entry ue_get_hash_entry(readonly blob ab_key);ulong ll_h ulong ll_i n_cst_hash_blob_entry lnvo_cur_entry n_cst_hash_blob_entry ret setnull(ret) if il_field_count > il_field_max_value then of_extend_hash(1) end if ll_h = of_hash(ab_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.ib_key = ab_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 = event ue_create_entry() il_field_count ++ ret.invo_next = invo_fields[ll_i] ret.il_hash = ll_h ret.ib_key = ab_key invo_fields[ll_i] = ret end if return ret end event event type n_cst_hash_blob_entry ue_create_entry();n_cst_hash_blob_entry ret setnull(ret) return ret end event public function long of_get_capacity ();return il_field_max_value + 1 end function public function boolean of_key_exists (readonly blob ab_key);ulong ll_h ulong ll_i n_cst_hash_blob_entry lnvo_entry ll_h = of_hash(ab_key) ll_i = mod(ll_h, il_field_max_value) + 1 lnvo_entry = invo_fields[ll_i] do while not isnull(lnvo_entry) if lnvo_entry.il_hash = ll_h then if lnvo_entry.ib_key = ab_key then return true end if end if lnvo_entry = lnvo_entry.invo_next loop return false end function public function unsignedlong of_hash (readonly blob ab_key);ulong ll_i ulong ll_len ulong ll_ret ll_len = len(ab_key) for ll_i = 1 to ll_len ll_ret = 33 * ll_ret + asc(char(blobmid(ab_key, ll_i, 1))) next ll_ret = ll_ret + ll_ret / 32 return ll_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_blob_entry lnvo_cur_entry n_cst_hash_blob_entry lnvo_prev_entry n_cst_hash_blob_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 public function integer of_delete_key (readonly blob ab_key);n_cst_hash_blob_entry lnvo_cur_entry n_cst_hash_blob_entry lnvo_prev_entry n_cst_hash_blob_entry lnvo_next_entry ULONG ll_h ULONG ll_i ll_h = of_hash(ab_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.ib_key = ab_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_blob_entry of_find_hash_entry (readonly blob ab_key);ulong ll_h ulong ll_i n_cst_hash_blob_entry lnvo_cur_entry n_cst_hash_blob_entry ret setnull(ret) ll_h = of_hash(ab_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.ib_key = ab_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 long of_get_keys (ref blob ab_keys[]);blob lb_ret[] long ll_cnt long ll_i n_cst_hash_blob_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 ++ lb_ret[ll_cnt] = lnvo_cur_entry.ib_key lnvo_cur_entry = lnvo_cur_entry.invo_next loop next ab_keys = lb_ret return ll_cnt 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 on n_cst_hash_blob.create call super::create TriggerEvent( this, "constructor" ) end on on n_cst_hash_blob.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_blob_entry lnvo_cur_entry for ll_i = 1 to il_field_max_value + 1 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