SKKSync - オンラインストレージ等によるSKKユーザ辞書ファイルの同期
SKKFEP - Project SKKSync

20XX年、世界はクラウドの闇に包まれた――
ファイルは消え、LANは隔離され、全ての辞書プロセスが暴走したかのように見えた。

だが、SKKは死滅していなかった!

 
 SKKGate/SKKNet/SKKDecompressor(skks.dll)に続く、『第四のユニット』の物語が再始動する……!

ダウンロード

概要

SKKSyncとは――

 辞書ファイルの読み書きを自動認識し、辞書プロセスの再起動(メンテ)なしに自動的に辞書の状態に合わせて内容を同期してくれるツールです。すっごーい!
 辞書プロセスの存在を気にせず、ファイルシステムレベルでユーザー辞書を自由に書き換えできるようになります。ファイルをUSBメモリとPCの間で読み書きしたり、Dropbox/OneDrive/GoogleDrive等のオンラインストレージで同期しておけば、あとはこのツールが自動的にユーザ辞書の読み書きの制御を行なってくれます。

今や時代はメンテナンスフリー!

 オンラインストレージ以外でも、rsyncなどのファイルシステムレベルの同期環境を用意してやれば、簡単に複数の端末間で辞書の同期運用が可能です。
 ほかにも、ユーザ辞書をUSBメモリに保存し、インターネットから隔離された検閲まみれのディストピアPC環境上に極秘ルートで持ち込んでこっそり辞書ファイルを上書きしてやれば、たったの3秒で自動的にユーザ辞書の内容が反映されちゃいます。ファイル同期(物理)最強伝説の誕生です。カミニ ナル カミニ ナル

使用方法

 まずはとにかく最新版のSKKFEPをインストールします。

 エクスプローラでZIPをダブルクリックして開き、圧縮フォルダを開きます。
 SETUP.jsを実行するとインストーラが起動するので、1ENTERと入力すれば設定完了です。

 インストール後は、SKKFEPのセットアップ上では「謎の辞書プロセス(ヒロイン)X代替版(オルタ)」として扱われるようになり、辞書プロセス自体のアップデートが発生するまではセットアップから上書きされることはなくなります。
 (なるべく最新版のSKKFEPのセットアップを使用してください)

 なお拡張ユニット方式は廃止されました。
 以下は拡張ユニット形式だった頃の古い文書です。

 次に、適当なフォルダにskksync.exeを置きます。
 どこに置いてもいいんですが、辞書プロセスの場所(%windir%\IME\SKK0)に置くのがおすすめです。
 ただし、ここに置くには管理者権限が必要なので、操作権限がない場合はユーザ辞書フォルダ(%APPDATA%\SKKFEP)に置くとよいでしょう。

 あとは以下のようにスタートアップに登録して一般ユーザー権限で実行してください。

方法その1
 スタートメニューの「スタートアップ」にショートカットを作る

方法その2
 skkgate.iniの末尾に起動処理を追加する (以下コピペ用)

辞書プロセスの場所に置いた場合の設定
// SKKSyncの起動
S.Run(S.ExpandEnvironmentStrings("%windir%\\IME\\SKK0\\skksync"))

ユーザ辞書フォルダに置いた場合の設定
// SKKSyncの起動
S.Run(app() + "skksync")

 一回実行すると常駐し、辞書プロセスの同期制御を開始します。常駐の有無はタスクマネージャで確認できます。
 動作中に再度実行すると、終了するかどうか確認するためのダイアログが表示されます。
 ダイアログが出たら「いいえ」のボタンを押すと終了します。

 SKKSyncモジュールは、辞書プロセスやSKKGateとは完全に独立したプロセスとして動作します。ひとたび起動してしまえば、あとは動作中にSKKFEPのアップデートや辞書プロセスの再起動などをやっても、そのまま継続して利用できます。

 ちょっとこれだけだと意味不明だと思うので、手動で動作を確認する方法について後述します。「手動での動作テスト」の章まで読み進めてみてください。

動作原理

 インストールすると辞書プロセスがSKKSync対応版と置き換わり、挙動が以下のように変化します。

その1: 自分以外がユーザー辞書ファイルを更新したら、3秒間更新がなくなるまで待ってからユーザ辞書をリロードする。
 ファイルの書き換え途中に誤って読み込んでしまわないように、3秒の待機時間を設けてあります。

その2: 自分のPC上で日本語入力が行われ、辞書の更新が発生した場合の辞書更新までの待機時間が短縮されます。従来の3分のオートセーブ待ち時間が短縮され、3秒で速攻保存となります。
 要するに「3分間待っ『バルス!』」って感じです。辞書の状態をオンラインストレージにすばやく反映させることで利便性を上げるのが狙いです。目が目があぁぁ

従来手法との比較

 従来のSKKFEPでは、ユーザ辞書の運用に以下のような手順を想定していました。

手順1. セットアップを起動する
手順2. 「メンテ」ボタンを押して辞書プロセスを停止させる (またはタスクマネージャから辞書プロセスを選んで直接停止させる)
手順3. テキストエディタやファイルコピーを使ってユーザ辞書ファイルを操作する
手順4. 「辞書の読み込み」ボタンを押して辞書プロセスを再起動する (または辞書プロセスを手動で実行する)

 この方法でも、時々編集したりファイルを変更する程度であれば何も問題はありませんでした。
 しかしファイルシステムの同期などの高レイヤの機能を使うようになるとファイルの更新回数が「桁違いに」上昇してしまいます。
 こうなると以下のような問題が見えてきます。

問題1. セットアップだのプロセスだの横文字うざい。操作めんどい。またメンテか。詫び石はよ
問題2. 辞書プロセスを再起動すると、ユーザ辞書とは無関係なメイン辞書側の全文検索のインデックス作成処理も毎回行わなければならない。標準のL辞書だけなら大したことはないが、巨大な辞書をいくつも持っている環境だとこの処理に時間がかかってしまい、変換できない空白時間ができてしまう。そして何よりもォ――!消費電力的にこんな運用はありえない。コノママジャダメ コノママジャダメ

 よろしい、ならばSKKSyncだ!
 このユニットの登場により、利用者は一切辞書プロセスの動作を意識する必要がなくなります。

手順1. テキストエディタやファイルコピーを使ってユーザ辞書ファイルを操作する

 これだけ!
 そして、ユーザ辞書の再構築だけが実行されるようになり、動作停止はほぼゼロ秒、消費電力も理論上最小に抑えることが可能となります。ヒャッハー!ファイル更新だァー!

手動での動作テスト

 なるほど、わからん。
 とりあえず、何やら便利そうだという事は伝わった。でもどういう動きなのか実際に見てみないと何だかよくわからんぞ。
 御託はいいからとにかく動きを見てみたい!そんな時のための操作例を以下に記します。
 まずはこれを参考に、いろいろ試してみるのがお勧めです。

実行前の準備

1. 書庫ファイルをダウンロードするか、もしくは、IE(ブラウザ)からZIPファイルを直接開き、圧縮フォルダを開いてください。

動作試験開始

2. 圧縮フォルダ内のインストーラを実行してインストールを選択します。
3. 以降、ユーザ辞書の保存間隔が3分から3秒に切り替わります。

ユーザ辞書ファイルを操作してみる

4. L辞書に入ってない単語、たとえば「初音ミク」とかを入力し、ユーザ学習に覚えさせておきます。
5. セットアップで「ユーザ辞書のバックアップ」ボタンを押して、バックアップを作成しておきます。
6. セットアップで「ユーザ辞書」ボタンを押してユーザ辞書フォルダを表示します。
7. ここで「バルス!」と叫びながらおもむろにユーザ辞書ファイル "skkuser.txt" を削除します。アッー
8. 削除したら3秒ほど待って、メモ帳などで「はつねみく」と入力してみると、変換できなくなっています。(なお、拡張スクリプトを使用している場合は、SKKGateの超短期キャッシュの影響を無効化するため5秒ほど待つのがおすすめです)
要するに辞書ファイルの状態の変化が自動的に検出されて、辞書プロセスの動作が変化した、というわけです。
9. さきほどバックアップを取った "skkuser_20XXXXXX.txt" を "skkuser.txt" にリネームします。
ちなみに、8のあとに日本語の入力を行なった場合は、中身がほぼ空の "skkuser.txt" が『何度でも蘇えるさ!』と言わんばかりに新たに生成されます。
その場合は再度 "skkuser.txt" をバルスしてからリネームしましょう。
(リネーム以外でも、テキストエディタで "skkuser.txt" を直接編集してしまっても構いません。ユーザ辞書に対するあらゆる外部からのファイル操作が可能です。)
10. リネームしたら3秒ほど待ち、再度メモ帳で入力してみると、正しく変換できる(ちゃんと元に戻っている)ことがわかります。

動作試験完了

11. 圧縮フォルダ内のインストーラを実行してアンインストールを選択します。その後、SKKFEPのインストーラを実行しアップデートを選択します。これでユーザ辞書の保存間隔が3分に戻ります。
12. おわり

応用例

 オンラインストレージの運用については、CorvusSKKの作者さまによる詳細な記事があります。こちらの情報も参考にしてみてください。

 共有フォルダ(OneDriveなら%USERPROFILE%\OneDrive、Dropboxなら%USERPROFILE%\Dropbox)にユーザ辞書フォルダ(%APPDATA%\SKKFEP)の実体を置き、元のユーザ辞書フォルダ側はジャンクションを使用するのが一番簡単な運用方法です。

 ここではOneDriveやDropboxで運用を開始するまでの手順と、元に戻す時の手順について簡単に記します。
 コマンドプロンプトを開いて、以下のコマンドを順に実行すればOKです。
 (ここでは、OneDrive用のコマンド例を書いてあります。Dropboxの場合は"OneDrive"と書かれている箇所を"Dropbox"に置き換えて実行してください)

運用を開始するための手順

1. 原本となる共有フォルダを用意する (最初の一回目だけ)

mkdir "%USERPROFILE%\OneDrive\SKKFEP"

2. 必要なファイルをコピーする (最初の一回目だけ)

copy "%APPDATA%\SKKFEP\skkuser.txt" "%USERPROFILE%\OneDrive\SKKFEP"
(辞書以外にも必要なものがあれば最小限コピーすべし)

3. SKKFEP用のフォルダを名前を変えて退避してから、オンラインストレージ側にジャンクションを張る

ren "%APPDATA%\SKKFEP" SKKFEP_backup
mklink /j "%APPDATA%\SKKFEP" "%USERPROFILE%\OneDrive\SKKFEP"

注意1: リネームがうまくいかない場合は、最新版の拡張スクリプトに更新してください。
注意2: ジャンクションの生成後、一回適当に漢字を入力して辞書のリロードを手動で行なってください。(ブラウザやメモ帳などで「うまみちょうみりょう」を変換→確定するなど)

 二台目以降は、上記の3だけ実行すればOKです。

運用をやめて元に戻すための手順

1. 念のためジャンクションがあるかどうか確認する

dir "%APPDATA%"

2. ジャンクションを取り消す

rmdir "%APPDATA%\SKKFEP"

3. 退避しておいたSKKFEP用のフォルダを元に戻す

ren "%APPDATA%\SKKFEP_backup" SKKFEP

魅惑の3秒間

 なぜ同期の待ち時間は3秒なのか。

 この待ち時間が短すぎると、2つの問題が発生してしまいます。
1. ファイルへの反映が素早すぎると、SKKNet経由での超高速な単語更新などのDoS攻撃によって端末の消費電力が急激に増加してしまう恐れがある。どんな状況であっても電力バランスを保つためには、極力長い時間にしたい
2. 現在のWindowsの仕様では「ファイルの更新が完了した瞬間」を取得することができない。ファイルが書き変わったことは検出できるが、それがファイルを書き換え途中の書き込みによるものなのか、それともファイル作成完了によるものなのか判定できないので、あまり短い時間にしてしまうと、ファイル書き換え途中のデータを何度も読み直す間抜けな動作になってしまう。さまざまなアプリからの書き換えを想定すると、なるべく長い時間安定するまで待っておきたい

 てなわけで、当初は安全側に寄せようってことで待ち時間を30秒とかで試していたんだけど、Webブラウズのページ表示速度に対するユーザ反応の理論と同じで、更新されるまで何十秒もじっと待つとか正直耐えられない無理無理かたつ無理。
 魅惑の肌色画像を求めて激重の鯖に挑んでいるような最重要顧客案件ならともかく、単なるファイル更新の反映を待つなら3秒が限界だッ!
 などと試行錯誤しまくった結果、この時間に落ち着いたのでした。

 で、説明では3秒って書いたけど、実は正確には3.072秒だったりします。
 この小数点以下の「O72」ってのは一体何者なのか?肌色画像との負けられない戦いと何か関係するのか?
 ……なんてことはなくて、実はこの数字にはもっと別の理由があります。

 プログラムの内部では、待ち時間はミリ秒単位で表現されていて、これを数値にすると3072ミリ秒となります。16進数にすると0xC00です。この値は下位8ビットが0になるので、ZIPなどでバイナリの圧縮率が僅かに上がるという……(他にも例えば、32ビット中1が連続2ビットだけで他は全て0なので組み込み系のプロセッサだと短い命令で表現できたりとか、0が多い部分に狙って配置できればスライド辞書方式の圧縮率が一気に上がるとか)。そんな理由です。
 こういう地味な積み重ねで小さいサイズを実現しているってわけなのです。我々はかしこいので。

時代背景

 ここでは誰も信じてはならぬ――

 世はまさに大クラウド時代。
 ファイルシステムレベルでの同期はコンピュータ史初期の頃から多くの実装があり、シンプルで利用しやすいメリットがある。
 その仕組みがクラウド上にそのまま実現されたオンラインストレージは、ネットワークの利便性を手軽に享受できるので入門者にも最適だ。実はこれは最強のメリットかもしれない。理解が困難というネットワーク関連機能のもつ問題を根本的に解決できれば利用者と開発者を爆発的に増やせる可能性を秘めているわけで、この部分は本当に大事なポイントなのだ。そのために多少複雑な処理が必要になったところで、現代の計算機の処理能力なら何の足枷にもならない。
 しかし本当にこれだけでよいのだろうか?

 SKKユーザ辞書の同期をファイルシステムレベルで行うというのは、実はかなりオーバーヘッドの大きい処理だ。
 例えばSKKを1年間ほど使うとユーザ辞書ファイルのサイズは数百KB程度になる。
 このサイズのデータが、1単語(数十バイト程度の情報量)が書き変わる毎に中央サーバと全てのノード間で処理されることになるのだ。
 もちろん現代のオンラインストレージはデータの差分通信や圧縮通信を駆使しているから、通信量自体はオーバーヘッドが少なくなるように工夫されてはいる(はず)なんだけど、差分や圧縮の抽出や書き戻しを行なうために本来必要最小限の処理には必要ない大量の処理が裏で発生しているのだ。4桁レベルの情報量差は普通はそう簡単には埋められないのだ。
 だから本当に処理効率を追求したい時はSKKNetとSKKSyncは使いわけるべき……と書きたかったんだけど今のところファイル同期のメリットを上回るユースケースを何一つ実現できてないのが歯痒いところ。

 そして最後にもうひと味。(謎の塩ポーズ)
 いっつも言ってることだから今さら繰り返すのも野暮な話かもしれないけど、ユーザ辞書というのは利用者の「思考」の断片だということ。個人情報なんて甘っちょろいレベルじゃない。
 そんな大事な情報を丸ごとMSやGoogleなどの検閲大好きな「邪悪」になり得る可能性をもつ営利企業に託すというのは最悪の結果を生む危険を伴う行為である……かもしれないということ。

「市民、あなたは幸福ですか」

「もちろんです、Google(検閲削除)。幸福でいることは市民の義務です」

 崩壊なんてその気になれば一瞬だし、実はもう手遅れだったりするのかもしれないし。それでもなお代替手段を考え続けることは決して無駄にはならないはずだし。

 現在のコンピュータの持つ膨大な処理帯域があれば、こんな瑣末な部分を気にするのは無意味なのかもしれない。でも文明が崩壊しちゃったり異世界に転生して無双したくなっちゃった時にこんなポストアポカリプス日本語入力技術が再評価される日が来るかもしれない。ううん、知らないけどきっとそう。

更新履歴

2017.03.21

 いきなりクライマックス!
 現実逃避でスモーキーな四月馬鹿向け一発ネタで終わるつもりだったが、使ってみたら控え目に言って最高すぎたため急遽俺得ツールとして公開。俺得最高!

2017.03.23

 ユーザ辞書フォルダをリネームしたり、ジャンクションを生成した際、現在のWin32 APIでは書き換えを検出できないため、セーブ直前にもタイムスタンプを比較してフォルダ消滅や未検出の書き換えを発見した場合はリロードを優先するよう改良した。それとZIP圧縮率を改善。

 要するに、初版のSKKSyncではオンラインストレージ接続のための初期設定を行なった後、辞書プロセスを再起動せずに動かし続けた場合、辞書データをうっかり上書きしてしまう危険性があったが、再起動しなくてもこの問題を完全に防げるようになった、ということだ。これで真のメンテナンスフリー運用が実現できる。

 なおSKKSyncではユーザ辞書フォルダが消滅した状態、すなわちWin32 APIでファイル変化を検出できない状況に陥った場合であっても、ポーリングなどの電力を無駄にする効率の悪い監視行為は一切行わない。これは仕様である。
 フォルダのリネームや削除を行なった結果、SKKSyncのAPIによるファイル更新検出が途切れた場合、その後初回の漢字変換の確定(例えばメモ帳で「だいにうちゅうそくど」を変換→確定する)を契機にリロード動作が行なわれ、新たなユーザ辞書フォルダを対象としたAPIによる更新イベント検出動作が復旧する。
 つまり一回目の学習結果は捨てられるわけだが、そもそも辞書フォルダをジャンクション化するなんて高度な操作を行うのは初回設定時くらいのレアケースだし、これは仕様ってことにする。

2017.04.04

 10KBの辞書プロセスと4KBの拡張ユニットを統合したら10KBになっちゃった!THCompは実在した!
 というエイプリールフール遅刻ネタなのであった。
 ちなみに統合版は小型化のために4K Introの悪魔に魂を売りまくるレベルで大改造が施されているので、内部動作は3秒カウントではなく2秒または4秒カウントになってるけどまーだいたい平均3秒って思っておけば大丈夫。

2017.04.10

さらば拡張ユニット、安らかに眠れ――

 拡張ユニット方式は廃止。
 辞書プロセスを上書きするインストーラを作成。これなら1プロセスで済むので効率が良いし、インストールも手軽にできる。ひとまずこっちを正式版にすることにした。

ちくわ大明神

 実はこの機能、もともとはSKK Universe計画の一環としてテキトーに仕込んだ辞書制御用おまけAPIって感じだったんだけど……
 使ってみて思ったのは、

マジやばくね?

 ってこと。
 とにかく辞書プロセスの存在をまったく気にしなくてよくなるので、利用者はただユーザ辞書のファイルをコピーすることだけを考えておけばいい。とにかく運用が超お手軽になる。

これ複数種類・プラットフォーム間のSKK運用には必須機能じゃね?マジやばくね?

 って感じ。このお手軽さを知ってしまうと戻れない。

 ……つーかなんでこういう機能が元の(Emacsやviの)SKKには存在しないの?ってのが正直なところ。
 どうか誰か作りやがれくださいおながいします。
 てなわけで将来的にこのモジュールはSKKFEP側に統合する予定。統合はする……するが……今回、まだその時と場所の指定まではしていない、そのことをどうか諸君らも思い出していただきたい(吐血)

co (Twitter)

inserted by FC2 system