C++ で書かれた、シンプル、高速で省メモリな独自形式の辞書 (変換にかかる時間は数秒です) を使用する SKK サーバです。 Linux/MacOSX/FreeBSD/OpenBSD/Cygwin で動作します。(最近のバージョンでは MacOSX でビルドに失敗するとの情報があります)
バージョン 0.3.6 以降のライセンスは SKK と同じ GPL です。
0.5.4 : yaskkserv-0.5.4.tar.bz2 (58616 bytes sha1sum:75ed8dd242f19575c367d4bb2f18e6b8ca8b31eb) (2012年8月18日(土) 更新)
0.5.2 : yaskkserv-0.5.2.tar.bz2 (58522 bytes sha1sum:fbaab07b74121961e70844d806d1be9330ce7eea) (2011年10月29日(土) 更新)
何かありましたら twitter @wachikun 、 wac@umiushi.org へのメイルなど、お気軽にどうぞ。
まず yaskkserv_make_dictionary で専用の辞書を作成する必要があります。
$ yaskkserv_make_dictionary SKK-JISYO.L SKK-JISYO.L.yaskkserv
以上の操作で SKK-JISYO.L から SKK-JISYO.L.yaskkserv が作られます。
作成した辞書を指定してサーバを起動します。
$ yaskkserv SKK-JISYO.L.yaskkserv
できるだけ外部ライブラリや言語に依存しないようにしてありますので、ほとんどの環境で ./configure && make && make install 一発です。
と、いいながらも configure は Perl 製ですが、 Perl が無い場合は、大抵の環境で make -f Makefile.noperl でビルドできると思います。
| オプション | 機能 | 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 です。 | × | × | ○ |
| --google-japanese-input=type | type には disable, notfound または dictionary を指定します。デフォルトは disable です。 notfound は SKK 辞書に候補が見付からなかったときのみ google Japanese Input を使用します。 dictionary は google Japanese Input を辞書として使用します。辞書を http://www.google.com と指定すると google Japanese Input になります。このモードでは変換するたびに google にアクセスすることになります。 0.5.0beta3 以降で configure に --enable-google-japanese-input を付けてビルドした場合に有効になります。 | × | × | ○ (0.5.0beta3 以降) |
| --google-japanese-input-timeout | 0.5.0beta2 以降で configure に --enable-google-japanese-input を付けてビルドした場合に有効になります。タイムアウト時間を秒で設定します。デフォルトは 2.5 です。 | × | × | ○ (0.5.0beta2 以降) |
| --version | サーバのバージョンを表示し、終了します。 | ○ | ○ | ○ |
yaskkserv では以下のような実装になっています。
| type | サーバの実装 |
|---|---|
| 1 | 変更なし。 |
| 2 | / を含む見出しを含めない。 |
| 3 | スペース区切りにする。 |
| 4 | プロトコル c を追加しスペース区切りにする。プロトコル 4 は / のまま。 |
0.5.0 から google Japanese Input に対応しました。この機能は configure と yaskkserv の起動時双方にオプションを付けないと有効になりません。
google Japanese Input を使用しません。 --google-japanese-input=type を指定しない場合も disable になります。
$ yaskkserv_hairy --google-japanese-input=disable SKK-JISYO.L.yaskkserv
SKK 辞書に候補が見付からない場合のみ google Japanese Input を呼び出します。 google へアクセスする頻度が減るので、そこそこ軽快に動作します。
$ yaskkserv_hairy --google-japanese-input=notfound SKK-JISYO.L.yaskkserv
SKK-JISYO.L.yaskkserv の次に google Japanese Input を辞書ファイルとしてふるまうよう呼び出します。(辞書を書くべきところに http://www.google.com と記述すると google Japanese Input を指定したことになります。) 毎回 google へアクセスすることになるため、多少もたつきますが、 SKK 的ではない変換も可能になります。
$ yaskkserv_hairy --google-japanese-input=dictionary SKK-JISYO.L.yaskkserv http://www.google.com
SKK-JISYO.L.yaskkserv の前に google Japanese Input を辞書ファイルとしてふるまうよう呼び出します。毎回 google へアクセスすることになります。あまりメリットはないかもしれません。
$ yaskkserv_hairy --google-japanese-input=dictionary http://www.google.com SKK-JISYO.L.yaskkserv
google Japanese Input のみを辞書ファイルとして使用します。毎回 google へアクセスすることになります。辞書を用意するのが面倒なときに便利かもしれません。
$ yaskkserv_hairy --google-japanese-input=dictionary http://www.google.com
「送りあり」のことを考えると、 --google-japanese-input=dictionary で最後に http://www.google.com を指定するか、 --google-japanese-input=notfound がオススメなのかもしれません。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
なお、筆者の環境では 1 年ほどテストしていますが、問題は起きていないようです。辞書の語彙が足りないと感じることがほとんどなくなり、本当に便利です。
次のバージョンあたりからデフォルトで --google-japanese-input を有効にするかもしれません。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
なお、筆者の環境では 1 年ほどテストしていますが、問題は起きていないようです。辞書の語彙が足りないと感じることがほとんどなくなり、本当に便利です。
次のバージョンあたりからデフォルトで --google-japanese-input を有効にするかもしれません。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
なお、筆者の環境では 1 ヶ月ほどテストしていますが、問題は起きていないようです。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
なお、筆者の環境では 3 週間ほどテストしていますが、問題は起きていないようです。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
なお、筆者の環境では 3 週間ほどテストしていますが、問題は起きていないようです。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
configure に --enable-google-japanese-input を付けてビルドした yaskkserv_hairy に、 --google-japanese-input=type (beta3 からオプションに引数が追加されています) を付けて起動した場合に google Japanese Input API を使用します。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
configure に --enable-google-japanese-input を付けてビルドした yaskkserv_hairy に、 --google-japanese-input (beta2 からオプションが変更されています) を付けて起動し、辞書による候補が取得できなかった場合にのみ google Japanese Input API を使用します。
デフォルトでは google Japanese Input は有効になりませんが、--google-japanese-input を使用すると以下のような問題が生じる可能性があります。
configure に --enable-google-japanese-input を付けてビルドした yaskkserv_hairy に、 --enable-google-japanese-input を付けて起動し、辞書による候補が取得できなかった場合にのみ google Japanese Input API を使用します。
デフォルトでは google Japanese Input は有効になりませんが、--enable-google-japanese-input を使用すると以下のような問題が生じる可能性があります。
UTF8/EUC の変換に iconv を使用しているため、ここで問題が生じるとローカル辞書にゴミが入るかもしれません。とはいえ実装としては少しでもあやしい場合は変換に失敗したこととして変換文字列を返さないようにしているので、基本的には問題は生じない作りにしているつもりではあるのですが。
なお、 yaskkserv_hairy で --enable-google-japanese-input を付けて起動しない限りは、 0.4.0 から不正なプロトコルチェックが強化された程度の違いしかありません。
gcc3.3 系 + メモリが少ない環境で、コンパイラのバグを踏むためコンパイルできないという問題が確認されています。作者の環境ではメモリが 256M の機械でバグを踏みます。 512M の機械では問題ありません。この問題はオプティマイズレベルが高いと発生するようです。
yaskkserv-0.3.3 以降では configure でコンパイラバグを踏みそうな環境を検知し、自動的にオプティマイズレベルを下げます。
yaskkserv-0.3.3 より前のバージョンでは
といった対処をする必要があります。
以下のような特徴があります。
使用した辞書は 2005年10月12日(水) あたりの SKK-JISYO.total+zipcode です。(482220 エントリ 15930937 bytes)
「最小サイズ」はインデックスデータとブロックリードバッファを同じ領域に置くことでメモリを節約した場合のサイズです。(この場合は当然、インデックスデータを毎回ストレージから RAM へ読み込む必要があります。)
現在の実装ではインデックスデータとブロックリードバッファを別に確保するので、「合計サイズ」だけメモリを消費します。
「--short-block」は辞書サイズを大きくすることでインデックスデータを小さくする形式です。
| オプション | ブロックリードバッファサイズ | インデックスデータサイズ | 合計サイズ | 最小サイズ |
|---|---|---|---|---|
| --block-size=4096 | 4k | 58k | 62k | 58k |
| --block-size=8192 | 8k | 32k | 36k | 32k |
| --block-size=16384 | 16k | 18k | 36k | 18k |
| --block-size=4096 --alignment --short-block | 4k | 36k | 40k | 36k |
| --block-size=8192 --alignment --short-block | 8k | 20k | 28k | 20k |
| --block-size=16384 --alignment --short-block | 16k | 11k | 27k | 16k |
SKK-JISYO.total+zipcode (482220 エントリ 15930937 bytes) をコンバートした場合のサイズです。
| オプション | サイズ | 比率 |
|---|---|---|
| --block-size=4096 | 14152648 | 88.8% |
| --block-size=8192 | 14125252 | 88.6% |
| --block-size=16384 | 14111500 | 88.5% |
| --block-size=4096 --alignment | 14656456 | 91.9% |
| --block-size=8192 --alignment | 15104196 | 94.8% |
| --block-size=16384 --alignment | 15926028 | 99.9% |
| --block-size=4096 --alignment --short-block | 14635072 | 91.8% |
| --block-size=8192 --alignment --short-block | 15093156 | 94.7% |
| --block-size=16384 --alignment --short-block | 15920200 | 99.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 の個数 (通常エントリ + 特殊エントリ) | 文字列格納領域 (通常エントリ + 特殊エントリ) |
|---|---|---|
| 4k | 3563 + 1 個 | 27644 + 4 bytes |
| 8k | 1839 + 1 個 | 14043 + 4 bytes |
| 16k | 970 + 1 個 | 7241 + 4 bytes |
ブロックサイズが大きいとインデックスデータサイズは小さくなりますが、ブロックの読み込みに時間がかかり、ブロックリードバッファ内での探索時間が少し増えます。
ブロックサイズが小さいとインデックスデータサイズは大きくなりますが、ブロックの読み込み時間とブロックリードバッファ内での探索時間は減ります。しかし同一の struct FixedArray に含まれる struct Block が増え、ここでの探索時間が少し増えます。
yaskkserv は以下の環境で動作確認しています。
| OS | CPU | compiler |
|---|---|---|
| gentoo linux(amd64) | Core i7 CPU L 620 | g++ (Gentoo 4.4.5 p1.3, pie-0.4.5) 4.4.5 |
| gentoo linux(amd64) | Athlon X2 4850e | g++ (Gentoo 4.4.5 p1.2, pie-0.4.5) 4.4.5 |
| gentoo linux(x86) | Atom N455 | g++ (Gentoo 4.4.5 p1.3, pie-0.4.5) 4.4.5 |
わざわざ書きおこしたのは
といった理由からです。
用途によって、いくつかのサーバを用意しています。
コマンド yaskkserv_make_dictionary の実行にかかる時間を time で適当に計測してみました。
使用した辞書は 2005年10月12日(水) あたりの SKK-JISYO.total+zipcode です。(482220 エントリ 15930937 bytes)
| CPU | メモリ | OS | 変換にかかった時間 |
|---|---|---|---|
| P3-600 | 320M | gentoo linux | 4-6 sec. |
| C3 1000 | 256M | gentoo linux | 3-5 sec. |
| C3 1000 | 512M | gentoo linux | 3-5 sec. |
| Athlon64 X2 3800+ | 2G | gentoo linux(amd64) | 1 sec. 程度 |
サーバへコネクションを切断するよう要求します。
「見出し」 eee に対する「変換文字列」を要求します。 " " (スペース)でターミネートされていることに注意が必要です。
サーバから返される「変換文字列」は / で区切られた "1/foo/bar/baz/\n" のような形式です。
サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。
「見出し」が存在しない場合は入力の先頭の "1" を "4" に変換したものをそのまま返します。 (実はプロトコル的には 4 で始まる文字列ならば何でも良いらしいですが、一部のクライアントで問題が出るとのことです。)
サーバへ「バージョンナンバー」を要求します。
サーバから返される「バージョンナンバー」は "A.B " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。
skkserv/skkserv.c に A はメジャーバージョン B はマイナーバージョンのような記述がありますが、 skkserv 自体 "A.B.C " のような形式で返していますし、他のサーバではサーバ文字列を返しているものもあるので、バージョンナンバーというよりバージョン情報と表現すべきなのかもしれません。
サーバへ「サーバのホスト名と IP アドレスのリスト」を要求します。
サーバから返される「サーバのホスト名と IP アドレスのリスト」は "hostname:addr:[addr...:] " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。
yaskkserv では未実装です。(ダミー文字列が返されます。)
「見出し」 eee で始まる見出しを要求します。" " (スペース)でターミネートされていることに注意が必要です。
サーバから返される「見出し」は / で区切られた "1/foo/bar/baz/\n" のような形式です。
サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。
これは新しいプロトコルで、今のところきちんとした定義は無いようです。
あいまいな点としては
といったものが挙げられます。
yaskkserv では
といった実装になっています。
skkserv/skkserv.c ではデバッグモード時にエラーメッセージをコンソールへ出力するだけのようです。
yaskkserv-0.3.0 以降では "0\n" を返します。 yaskkserv-0.3.0 より前は何も返しません。
SKK に関するメモ
| 情報 | ソース |
|---|---|
| 見出しサイズは 510 バイト | skkserv/README |
| プロトコル | skkserv/skkserv.c 、 regex-skkserv の MEMO と SKK専用スレッド Part7 の 74 さん |