yaskkserv

yaskkserv とは?

C++ で書かれた、シンプル、高速で省メモリな独自形式の辞書 (変換にかかる時間は数秒です) を使用する SKK サーバです。 Linux/MacOSX/FreeBSD/OpenBSD/Cygwin で動作します。

バージョン 0.3.6 以降のライセンスは SKK と同じ GPL です。

current : yaskkserv-0.4.0.tar.bz2 (54060 bytes sha1sum:a38dfc1694c10b7040c0aa7351a2866399b81e4f) (2008年4月30日(水) 更新)

何かありましたら mail address へのメイルや 電言板 まで、お気軽にどうぞ。 2ch UNIX 板の「SKK専用スレッド Part7」 も見てます。

コマンドラインオプションについて

オプション 機能 simple normal hairy
--check-update 辞書の更新をチェックし自動で再読み込みします。デフォルトは disable です。 ×
--debug 現在は使用していません。デフォルトは disable です。
--help ヘルプメッセージを表示し、終了します。
--log-level=LEVEL ログレベルを指定します。 0 - 9 の範囲で指定でき、数値が大きいほど詳細なログを出力します。ログは syslog に出力されます。デフォルトは 1 です。
--max-connection=N 最大同時接続数を指定します。デフォルトは 8 です。
--port=PORT ポートを指定します。デフォルトは 1178 です。
--server-completion-midasi-length=LENGTH completion で返す見出しの最大数を指定します。この数を越えると completion は失敗します。デフォルトは 0.3.5_SKK_ML_TEST_20070814_0 より前の版では 1024 、以降は 2048 です。あまり大きな値を指定する意味はない (補完候補は事実上 100 程度を越えた時点意味がなくなるのでは?) ので、デフォルトを小さな値にし失敗時に特定のメッセージを返すか、指定数までは返すような実装にすべきかもしれません。 × ×
--server-completion-midasi-string-size=LENGTH completion で生成される文字列バッファを LENGTH バイト用意します。生成される文字列がこのサイズを越えると completion は失敗します。デフォルトは 0.3.5_SKK_ML_TEST_20070814_0 より前の版では 131072 、 以降は 262144 です。 × ×
--server-completion-test=type SKK ML 「server completion の仕様の欠陥」で提案された 1 - 4 案を指定します。デフォルトは 1 です。 × ×
--version サーバのバージョンを表示し、終了します。

SKK ML 「server completion の仕様の欠陥」で提案された 1 - 4 案について

yaskkserv では以下のような実装になっています。

type サーバの実装
1 変更なし。
2 / を含む見出しを含めない。
3 スペース区切りにする。
4 プロトコル c を追加しスペース区切りにする。プロトコル 4 は / のまま。

News

2008年4月30日(水)
yaskkserv-0.4.0.tar.bz2 (54060 bytes sha1sum:a38dfc1694c10b7040c0aa7351a2866399b81e4f)
  • 不要になった configure の --lang スイッチに関する記述を削除。(レポートありがとうございます!)
  • ポカミス修正ですので 0.3.9 と機能に変わりはありません。
2008年4月26日(土)
yaskkserv-0.3.9.tar.bz2 (54136 bytes sha1sum:472078f93dbfc508e284e519435cfb7c42178c71)
  • configure 内でテンポラリファイル名の生成法に問題があった不具合を修正。(レポートありがとうございます!)
  • gcc-4.3 で gcc のバージョンを取得できない不具合を修正。(レポートありがとうございます!)
  • ビルドテスト用のコードなどを削除。(gcc-4.3 でビルドに失敗するコードも取り除かれました)
2008年1月19日(土)
yaskkserv-0.3.8.tar.bz2 (60700 bytes sha1sum:687671e440cc310b25360d79a20dc15da17b8125)
  • バージョン名から SKK_ML_TEST_20070814_0 を削除しました。(テスト機能自体は含まれています。)
  • mmap やビルド時に発生することがある目立たない不具合をいくつか修正しました。
2008年1月17日(木)
yaskkserv-0.3.7_SKK_ML_TEST_20070814_0.tar.bz2 (60486 bytes sha1sum:730162d61733e8315c616989a2ec2d2100aa0e94)
  • yaskkserv_make_dictionary で空行を含む辞書を変換できない不具合を修正しました。(レポートありがとうございます!)
  • なお、わりと近いうちに mmap などの目立たない不具合を修正した版をリリースします。
2008年1月10日(木)
yaskkserv-0.3.6_SKK_ML_TEST_20070814_0.tar.bz2 (60303 bytes sha1sum:a2490f2aad7801e5713e849285d38bf03650ecae)
  • ライセンスを GPL にしました。
  • テスト実装に大きな問題がないようなので current 扱いにしました。
  • 機能的には 3.3, 3.4 や 3.5 と同じです。

News ログ

注意が必要な点

gcc3.3 系 + メモリが少ない環境でコンパイラのバグを踏む問題について

gcc3.3 系 + メモリが少ない環境で、コンパイラのバグを踏むためコンパイルできないという問題が確認されています。作者の環境ではメモリが 256M の機械でバグを踏みます。 512M の機械では問題ありません。この問題はオプティマイズレベルが高いと発生するようです。

yaskkserv-0.3.3 以降では configure でコンパイラバグを踏みそうな環境を検知し、自動的にオプティマイズレベルを下げます。

yaskkserv-0.3.3 より前のバージョンでは

といった対処をする必要があります。

ビルドについて

その他

なぜいまさら SKK サーバを書くの?

わざわざ書きおこしたのは

といった理由からです。

特徴

サーバについて

用途によって、いくつかのサーバを用意しています。

yaskkserv_simple
もっともシンプルなサーバ (skkserv から辞書再読み込み機能を除いたもの相当)
yaskkserv_normal
一般的なサーバ (skkserv + 複数辞書 + 辞書の自動再読み込み相当)
yaskkserv_hairy
なんでもありサーバになる予定 (yaskkserv_normal + server completion)

独自形式の辞書について

以下のような特徴があります。

探索コアで必要なメモリサイズ

使用した辞書は 2005年10月12日(水) あたりの SKK-JISYO.total+zipcode です。(482220 エントリ 15930937 bytes)

「最小サイズ」はインデックスデータとブロックリードバッファを同じ領域に置くことでメモリを節約した場合のサイズです。(この場合は当然、インデックスデータを毎回ストレージから RAM へ読み込む必要があります。)

現在の実装ではインデックスデータとブロックリードバッファを別に確保するので、「合計サイズ」だけメモリを消費します。

「--short-block」は辞書サイズを大きくすることでインデックスデータを小さくする形式です。

オプションブロックリードバッファサイズインデックスデータサイズ合計サイズ最小サイズ
--block-size=40964k58k62k58k
--block-size=81928k32k36k32k
--block-size=1638416k18k36k18k
--block-size=4096 --alignment --short-block4k36k40k36k
--block-size=8192 --alignment --short-block8k20k28k20k
--block-size=16384 --alignment --short-block16k11k27k16k

辞書サイズ

SKK-JISYO.total+zipcode (482220 エントリ 15930937 bytes) をコンバートした場合のサイズです。

オプションサイズ比率
--block-size=40961415264888.8%
--block-size=81921412525288.6%
--block-size=163841411150088.5%
--block-size=4096 --alignment1465645691.9%
--block-size=8192 --alignment1510419694.8%
--block-size=16384 --alignment1592602899.9%
--block-size=4096 --alignment --short-block1463507291.8%
--block-size=8192 --alignment --short-block1509315694.7%
--block-size=16384 --alignment --short-block1592020099.9%

「ひらがなエンコード」について

文字列がひらがなまたは ASCII だけで構成されていれば下位バイトのみ使用し、それ以外の文字が存在する場合は先頭に \x1 を追加するエンコード形式です。

ex.)
ああああ → \xa2\xa2\xa2\xa2 (下位バイトのみ)
ひらがな漢字 → \x1ひらがな漢字 (先頭に \x1)
LIFEFORCE → LIFEFORCE (ASCII のみ)
ぐらでぃうす2 → \xb0\xe9\xc7\xa3\xa6\xb9\x32 (下位バイト + ASCII)
沙羅曼蛇 → \x1沙羅曼蛇 (先頭に \x1)

見出しやインデックスデータ中の文字列でこのエンコード形式を採用しています。

「インデックスデータ」について

インデックスデータは一般に RAM 上へ置かれます。ここでストレージ上にある辞書の読み込むべきブロックが確定するため、ストレージへのアクセスは 1 度の探索あたり必ず 1 回以下 (運が良ければキャッシングされ 0 回) になります。

インデックスデータをストレージに置いておき、ブロックリードバッファと同じ領域に読み込んでから使うこともできます。この場合メモリは節約できますが、ストレージへのアクセスが 1 度の探索あたり必ず 2 回 (インデックスデータの読み込み + 辞書のブロック読み込み) になります。

インデックスデータは以下の要素から構成されます。 (詳しくはソースコード skk_jisyo.hpp のコメントをごらんください。)

struct FixedArray は「通常エントリ」の探索に使用します。「ひらがなエンコード」された先頭 1 バイトが添字となります。「特殊エントリ」は struct FixedArray を参照せず、直接ブロックを探索します。

struct FixedArray には struct Block の開始インデックス、長さとブロック終端文字列へのオフセットが含まれています。ここで指定されたどこかのブロックに探索文字列は存在することになります。どのブロックに含まれるかは、ブロック終端文字列と探索文字列を比較することで判定します。

                                            文字列を比較して
                        +---------+         「探索文字列」が「終端文字列」以下ならば
                        |Block N-1|         そのブロックに存在
+----------+   index=N  +---------+         探索文字列が "あい" ならば Block N+1 に存在
|FixedArray|--+-------->|Block N  |
+----------+  |    ^    +---------+---"ああああ" Block N の 終端文字列
              |    |    |Block N+1|
              |  len=4  +---------+---"あいいいいい" Block N+1 の 終端文字列
              |    |    |Block N+2|
              |    v    +---------+---"あかかかか" Block N+2 の 終端文字列
              +-------> |Block N+3|
                        +---------+---"あさささ" Block N+3 の 終端文字列
                        |Block N+4|
特殊エントリ開始        +---------+
ブロック -------------> |Block N+5|
index = N+5             +---------+
                        |Block N+6|
                        +---------+

struct Block の個数と文字列格納領域は 2005年10月12日(水) あたりの SKK-JISYO.total+zipcode の値です。

ブロックサイズstruct Block の個数 (通常エントリ + 特殊エントリ)文字列格納領域 (通常エントリ + 特殊エントリ)
4k3563 + 1 個27644 + 4 bytes
8k1839 + 1 個14043 + 4 bytes
16k970 + 1 個7241 + 4 bytes

「ブロック」について

ブロックサイズが大きいとインデックスデータサイズは小さくなりますが、ブロックの読み込みに時間がかかり、ブロックリードバッファ内での探索時間が少し増えます。

ブロックサイズが小さいとインデックスデータサイズは大きくなりますが、ブロックの読み込み時間とブロックリードバッファ内での探索時間は減ります。しかし同一の struct FixedArray に含まれる struct Block が増え、ここでの探索時間が少し増えます。

作者の環境

yaskkserv は以下の環境で動作確認しています。

OSCPUcompiler
MacOSX(x86)Core Duoi686-apple-darwin8-g++-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5363)
gentoo linux(amd64)Athlon64 X2 3800+g++ (GCC) 4.1.1 (Gentoo 4.1.1-r3)
gentoo linux(amd64)Athlon64 3200+g++ (GCC) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)
gentoo linux(x86)C3g++ (GCC) 4.1.1 (Gentoo 4.1.1-r3)
FreeBSD(VMware freebsd-6.2-i386.zip)-g++ (GCC) 3.4.6 [FreeBSD] 20060305
OpenBSD(VMware OAMP.zip)-g++ (GCC) 3.3.5 (propolice)
CygwinPentium4g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

いろいろ

基本戦略

めも

辞書変換時間

コマンド yaskkserv_make_dictionary の実行にかかる時間を time で適当に計測してみました。

使用した辞書は 2005年10月12日(水) あたりの SKK-JISYO.total+zipcode です。(482220 エントリ 15930937 bytes)

CPUメモリOS変換にかかった時間
P3-600320Mgentoo linux4-6 sec.
C3 1000256Mgentoo linux3-5 sec.
C3 1000512Mgentoo linux3-5 sec.
Athlon64 X2 3800+2Ggentoo linux(amd64)1 sec. 程度

SKK protocol メモ

"0"

サーバへコネクションを切断するよう要求します。

"1eee "

「見出し」 eee に対する「変換文字列」を要求します。 " " (スペース)でターミネートされていることに注意が必要です。

サーバから返される「変換文字列」は / で区切られた "1/foo/bar/baz/\n" のような形式です。

サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。

「見出し」が存在しない場合は入力の先頭の "1" を "4" に変換したものをそのまま返します。 (実はプロトコル的には 4 で始まる文字列ならば何でも良いらしいですが、一部のクライアントで問題が出るとのことです。)

"2"

サーバへ「バージョンナンバー」を要求します。

サーバから返される「バージョンナンバー」は "A.B " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。

skkserv/skkserv.c に A はメジャーバージョン B はマイナーバージョンのような記述がありますが、 skkserv 自体 "A.B.C " のような形式で返していますし、他のサーバではサーバ文字列を返しているものもあるので、バージョンナンバーというよりバージョン情報と表現すべきなのかもしれません。

"3"

サーバへ「サーバのホスト名と IP アドレスのリスト」を要求します。

サーバから返される「サーバのホスト名と IP アドレスのリスト」は "hostname:addr:[addr...:] " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。

yaskkserv では未実装です。(ダミー文字列が返されます。)

"4eee "

「見出し」 eee で始まる見出しを要求します。" " (スペース)でターミネートされていることに注意が必要です。

サーバから返される「見出し」は / で区切られた "1/foo/bar/baz/\n" のような形式です。

サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。

これは新しいプロトコルで、今のところきちんとした定義は無いようです。

あいまいな点としては

といったものが挙げられます。

yaskkserv では

といった実装になっています。

上記以外の不正な入力について

skkserv/skkserv.c ではデバッグモード時にエラーメッセージをコンソールへ出力するだけのようです。

yaskkserv-0.3.0 以降では "0\n" を返します。 yaskkserv-0.3.0 より前は何も返しません。

SKK メモ

SKK に関するメモ

情報ソース
見出しサイズは 510 バイトskkserv/README
プロトコルskkserv/skkserv.c 、 regex-skkserv の MEMOSKK専用スレッド Part7 の 74 さん

戻る