状態: Accepted
常駐デーモンを持たない(ADR-0002)ため、プロセス内のメモ表は 実行の終わりに失われる。プロセスを跨いだ再利用は永続化ストア (20-architecture.md 5節)が担う。
ストアの機構は実装済みである。追記専用の値ログ、原子的に差し替えるインデックス、
単一書き手の制限、形式版ごとのディレクトリ、入力の stat 走査による変更検出。
現在これを使っているのは入力の記録だけであり、値ログは空のままである。
格納の候補は2つある(99-open-questions.md Q9)。
| 対象 | 省けるもの |
|---|---|
Evaluated(ファイル単位) |
字句解析・構文解析・評価 |
Interface / CompileEnv(ターゲット単位) |
併合 |
Evaluated のみを格納する。ターゲット単位の派生はプロセス内のメモに留める。
格納の対象は、診断を1件も出さずに評価できたファイルに限る。
復元の判定は本文の指紋の一致による。復元した文書の FileId が問い合わせた
ファイルと異なる場合は使わない。
ターゲット単位の派生を格納しても評価を省けない。 interface と compile_env は
Declared と Deps を入力に取る。Declared はターゲットの宣言を評価した結果から
作られるため、これを組み立てるには評価が要る。したがって派生だけを格納しても
併合を省けるだけであり、その前段の字句解析・構文解析・評価は毎回走る。
両方を格納する案は、評価を省く目的においては Evaluated の格納と等価であり、
併合の分だけ格納する対象が増える。
診断を持つ値を格納しないのは、診断の識別子が &'static str であるためである。
復元には識別子を静的な文字列へ戻す必要があり、既知の識別子の一覧を実行時に
持つことになる。この一覧は診断を足すたびに更新が要り、更新漏れを防ぐために
別の検査を要する。網羅の追跡(51-testing.md)と同じ対象に
2つ目の台帳を持つことになる。
診断を持つファイルを毎回評価し直す代償は、ADR-0011 が 診断を指紋に含めた判断と同じ性質を持つ。誤りや警告が残っている間、利用者は編集を 繰り返している最中であり、その間の再利用の利得は小さい。
復元後に FileId を照合するのは、鍵の衝突を値の側で検出するためである。
ストアの鍵はハッシュであり、衝突しないことを形式が保証していない。文書は自身の
FileId を持つため、照合の費用は比較1回である。
両方を格納する。 上記のとおり、評価を省く効果は Evaluated の格納で尽きる。
併合の費用はターゲット数に比例し、評価の費用はマニフェストのバイト数に比例する。
後者が支配的である間、前者を格納する利得は測れない。将来 interface が
ツールチェーンのプローブ結果を入力に取るようになれば再検討の対象になる。
診断も直列化する。 識別子の一覧を実行時に持つことになる。上記のとおり、 台帳が増える。
識別子を Box::leak で復元する。 一覧を持たずに済むが、ストアの内容が
壊れている場合に任意のバイト列が識別子になる。診断の識別子は利用者が
--deny 等で指定しうる安定識別子であり、由来を実行ファイル内に限る。
値ログにファイル単位ではなくクエリ単位で書く。 現在の Evaluated は
ファイル単位のクエリであるため、両者は一致する。区別が生じるのは
ターゲット単位の派生を格納する場合であり、それを却下した以上は選択肢にならない。
query::evaluated は復元元を引数に取る。Session はストアを開いて渡し、
実行の終わりに新しく計算した分を書く。
復元が起きた場合、Parsed のメモは作られない。構文木を要する経路
(言語サーバのホバー)は同一プロセス内で解析するため、影響を受けない。
鍵と指紋の算出は DefaultHasher による。この実装は Rust の版を跨いで
同一であることを保証していない。変わった場合に起きるのは鍵の不一致と
指紋の不一致であり、いずれも再計算に落ちる。失うのは再利用の利得だけであり、
結果は変わらない。古い記録は Store::gc の
対象ではないため、形式版を上げるまで残る。
検査は an_unchanged_manifest_is_restored_from_the_store と
editing_a_manifest_makes_the_store_recompute_it(scenario.rs)が対で行う。
前者だけでは、そもそも評価を問い合わせていない状態でも通る。
格納が起きる実行は、インデックスの差し替えに伴う sync_data 2回の分だけ遅くなる。
計測は 91-implementation-status.md「計測」にある。
費用はマニフェストを変更した実行にのみ生じる。書くものが無い実行では
差し替えを行わない。
同期を省けばこの費用は消える。復元できない値は無いものとして扱われるため
(codec 冒頭)、同期を省いても誤った結果にはならない。ただし
20-architecture.md 5.3 が述べる担保の一角を外すことになるため、
本 ADR では採らない。判断には、短縮の側が規模に比例することを示す計測が要る。