固定長ハッシュ試作

速度とかを勘案して、キーと値が固定長の擬似ハッシュを作ってみた。
ある文字列をハッシュとして取り扱うルーチンだ。

命令

初期化:以降はこの文字列変数に通常のアクセスはしない方がいい。
fhash_init $ハッシュにしたい文字列変数,%キーの長さ,%値の長さ
書き込み
f_mov $ハッシュにした文字列変数,$キー,$値
読み出し
f_read $値を受け取る文字列変数,$ハッシュにした文字列変数,$キー
高速書き込み:そのキーがないことが確実な時に使ってください。
f_mov2 $ハッシュにした文字列変数,$キー,$値
キー削除
f_delete
f_mov2 $ハッシュにした文字列変数,$キー

スクリプト

ちなみにこのスクリプトはそのままでは実行できない。

numalias fhash_fhash
numalias fhash_key
numalias fhash_value
numalias fhash_key_length
numalias fhash_value_length
numalias fhash_key_temp
numalias fhash_value_temp
numalias fhash_cursor
numalias fhash_hit
------
------
;==============================
; 初期化ルーチン
;==============================
*fhash_init
getparam s%fhash_fhash,%fhash_key_length,%fhash_key_value
if %fhash_key_length>9 mov %fhash_key_length,9
if %fhash_key_length<1 mov %fhash_key_length,1
if %fhash_value_length>9 mov %fhash_value_length,9
if %fhash_value_length<1 mov %fhash_value_length,1
itoa $%fhash_fhash,%fhash_key_length
itoa $fhash_value_length,%fhash_value_length
add $%fhash_fhash,$fhash_value_length
return
;==============================
; 読み出しルーチン
;==============================
*fhash_read
*f_read
getparam s%fhash_value,s%fhash_fhash,$fhash_key
; キーを整える。
fhash_get_length
fhash_adjust
fhash_exist
if %fhash_hit=0 mov $%fhash_value,"":return
mov $%fhash_value,$fhash_value_temp
return
;==============================
; 書き込みルーチン
;==============================
*fhash_write
*f_mov
getparam s%fhash_fhash,$fhash_key,$fhash_value
; キーを整える。
fhash_get_length
fhash_adjust
mov $fhash_key_temp,$fhash_key
mov $fhash_value_temp,$fhash_value
fhash_rewrite
return
;==============================
; 書き込みルーチン
; キーが存在しないことがわかっている前提
;==============================
*fhash_write2
*f_mov2
getparam s%fhash_fhash,$fhash_key,$fhash_value
; キーを整える。
fhash_get_length
fhash_adjust
add $%fhash_fhash,$fhash_key
add $%fhash_fhash,$fhash_value
return
;==============================
; キーを一つ削除する
;==============================
*fhash_delete
*f_delete
getparam s%fhash_fhash,$fhash_key,$fhash_value
; キーを整える。
fhash_get_length
fhash_adjust
mov $fhash_key_temp,""
mov $fhash_value_temp,""
fhash_rewrite
return
;==============================
; 汎用ルーチン。キーの長さと値の長さを調整する。
;==============================
*fhash_adjust
adjust_length $fhash_key,%fhash_key_length
adjust_length $fhash_value,%fhash_value_length
return
;==============================
; 汎用ルーチン。キーの長さと値の長さを取得する。
;==============================
*fhash_get_length
mid $fhash_key_length,$%fhash_fhash,0,1:atoi %fhash_key_length,$fhash_key_length
mid $fhash_value_length,$%fhash_fhash,0,1:atoi %fhash_value_length,$fhash_value_length
return
;==============================
; 汎用ルーチン。そのキーがあるかどうか。あった場合はキーと値を設定する。
;==============================
*fhash_exist
fhash_get_length
mov %fhash_cursor,2
mov %fhash_hit,0
mov $fhash_value_temp,""
 *fhash_exist_loop
mov $fhash_key_temp,""
mid $fhash_key_temp,$%fhash_fhash,%fhash_cursor,%fhash_key_length
if $fhash="" return
if $fhash_key=$fhash_key_temp mid $fhash_value_temp,$%fhash_fhash,%fhash_cursor+%fhash_key_length,%fhash_value_length:mov %fhash_hit,1:return
add %fhash_cursor,%fhash_key_length+%fhash_value_length
goto *fhash_exist_loop
;==============================
; 汎用ルーチン。そのキーがあるかどうか。あった場合はキーと値を書き換える。
;==============================
*fhash_rewrite
fhash_get_length
mid $fhash_fhash,$%fhash_fhash,0,2
add $fhash_fhash,$fhash_key_temp
add $fhash_fhash,$fhash_value_temp
mov %fhash_cursor,2
mov $fhash_value_temp,""
 *fhash_rewrite_loop
mov $fhash_key_temp,""
mid $fhash_key_temp,$%fhash_fhash,%fhash_cursor,%fhash_key_length
if $fhash="" mov $%fhash_fhash,$fhash_fhash:return
notif $fhash_key=$fhash_key_temp mid $fhash_value_temp,$%fhash_fhash,%fhash_cursor+%fhash_key_length,%fhash_value_length:add $fhash_fhash,$fhash_key_temp:add $fhash_fhash,$fhash_value_temp
add %fhash_cursor,%fhash_key_length+%fhash_value_length
goto *fhash_rewrite_loop

;==============================
; 長さにあわせてスペースをつけるか、削るかする。
;==============================
*adjust_length
getparam s%math_result,%math_param1
len %math_temp1,$%math_result
if %math_temp1>%math_param1 mid $%math_result,$%math_result,0,%math_param1:return
 *adjust_length_loop
len %math_temp1,$%math_result
if %math_temp1=%math_param1 return
add $%math_result," "
goto *adjust_length_loop