Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

標準コンテナとスマート・ポインタ対応 #24

Closed
yossi-tahara opened this issue Jan 27, 2017 · 3 comments
Closed

標準コンテナとスマート・ポインタ対応 #24

yossi-tahara opened this issue Jan 27, 2017 · 3 comments

Comments

@yossi-tahara
Copy link
Owner

対応可能な標準のコンテナとスマート・ポインタへの正規対応を行います。
現在は下記について仮対応しています。

  • std::vector
  • std::list
  • std::unique_ptr
  • std::shared_ptr

現在は、デフォルトがあるテンプレート・パラメータに対応していません。
それらも含めて、できるだけフル・スペックでの対応を目指します。

yossi-tahara added a commit that referenced this issue Jan 31, 2017
  そのために、std::default_delete<>に対応
    シリアライズ処理は不要だが、std::unique_ptr<>をTheolizerヘッダ出力のため、
    型名へ変換している。それに対応ずするため、型名出力に対応した。
  そのために、テンプレート・パラメータの型名出力用指定マクロ
  THEOLIZER_TEMPLATE_PARAMETER_TEMPLATE()を追加。
    この時、ドライバ出力を抑制した(NoGenerate)。
  std::weak_ptr<>対応コードを記述した。未デバッグ。

ver1/main.cppでDISABLE_DESTINATIONS_TESTに対応漏れが有ったので修正した。

----------------- MD5 Hash Values -----------------
TheolizerDriver  : 01634e390f2c18bbbe6942fedef89e68
TheolizerLibrary : 7fa29136f6e160286151179b61c26665
Library's Header : 7d3bfed8da4eb20a73e5950dd05c9794

----------------- MD5 Hash Values -----------------
TheolizerDriver  : 225a51de843816c8b047fe594e2a4dc3
TheolizerLibrary : 7fa29136f6e160286151179b61c26665
Library's Header : 7d3bfed8da4eb20a73e5950dd05c9794
@yossi-tahara
Copy link
Owner Author

std::set, std::map群の実装を開始するのですが、それに当たって1点仕様を変更しようと思います。

現状の仕様

まず、現在の仕様はクラスについてはポインタ経由でシリアライズされたら、自動的にそのクラスのインスタンスをオブジェクト追跡しています。
元々は指定したインスタンスのみ追跡する予定だったのですが、std::vector<>等に登録したインスタンスを必要に応じて追跡することができず(1)、クラスなら自動追跡するのも有り(boostと同様な仕様)との思いから、自動追跡するようにしました。

(1)の問題は先日、std::vector<>等を派生したクラス(theolizer::VectorPointee<>等)で対応できたと思います。(オブジェクト追跡しない時は標準のコンテナをそのまま使い、オブジェクト追跡したい時は派生したコンテナを使う。)

問題点

std::setやstd::map等のキー付きコンテナの場合、コンテナ内に領域を獲得してから、そこへ値を設定できるようなI/Fが用意されていません。従って、一旦別領域へ回復(2)後、コンテナへ登録することになります。
すると、一旦別領域へ回復した時と異なるアドレスのメモリへコピーされる(3)ため、(2)で回復処理する際にオブジェクト追跡してアドレス解決されてしまった後にアドレスが変わり、オブジェクト追跡が異常動作します。

(3)例えstd::move()してもインスタンスそのものがムーブされるわけではなく、インスタンス内のヒープ領域の所有権が移動するだけです。

変更仕様

クラスについてもプリミティブと同様、明示的に指定した時のみ被ポインタとしてオブジェクト追跡するように変更します。

トレードオフ

  • 現在の仕様のメリットとデメリット
    クラス・インスタンスを自動追跡するので明示的な指定を省略できて便利。
    キー付きコンテナでオブジェクト追跡しても役に立たないものまでオブジェクト追跡してしまう。
    それを見落としてキー付きコンテナの要素へのポインタをシリアライズした場合、デバッグにかなり苦労する。

  • 変更仕様のメリットとデメリット
    プリミティブとクラスの動作が同じになり仕様を単純化できる。
    キー付きコンテナの問題を回避できる。
    キー付きコンテナでオブジェクト追跡したい場合はstd::unique_ptr<>などを使えば可能である。
    なお、プリミティブだけでなくクラスもPointee指定を忘れるとアドレス未解決(Some pointed data does not save.)エラーが出る。

結論

メリット・デメリットを比較し、クラスの自動追跡をしない方が使い勝手は良さそうなので自動追跡を止めます。なお、THEOLIZER_INTERNAL_DISABLE_AUTO_POINTEEシンボルを解除することで自動追跡が有効になるようロジックを残しておきます。

yossi-tahara added a commit that referenced this issue Feb 6, 2017
  ポイントされているクラスのインスタンスを自動追跡するようにしていたが、それを止めた。
  THEOLIZER_INTERNAL_DISABLE_AUTO_POINTEEをコメントアウトすると回復できる。

----------------- MD5 Hash Values -----------------
TheolizerDriver  : 1bc5151679c06c22329818ad7ff6291e
TheolizerLibrary : 021dbbc29a9fd4456c63bdfc988f62ba
Library's Header : 8abfc2488332f8f67ed3e3a7965f9887
@yossi-tahara
Copy link
Owner Author

yossi-tahara commented Feb 8, 2017

更に1点修正です。

Theolizerは保存先指定により、1つのクラス内のデータを複数のファイルに分割して保存し、それらを回復時に合成することで元のデータを回復できる機能を持っています。
コンテナについてもできるだけこの機能に対応しました。キー無しコンテナについては全て対応できました。キー付きコンテナについては、std::mapとstd::unordered_mapは対応できました。
これらは、キーとデータが分離しており、かつ、キーの重複を許さないため、回復時に「シリアライズ・データ中に記録されているインスタンス・データ」が対応する「メモリ上のインスタンス」をキーを使って特定できます。これにより、対応するインスタンス同士を合成できます。

その際に、キー回復後、コンテナ内に該当データが無い場合でもそのキーで領域を一旦確保することが可能です。従って、前回の仕様変更で断念したキー付きコンテナの内、std::mapとstd::unordered_mapについては被ポインタとしての回復にも対応しました。

現在の対応仕様

標準コンテナ シリアライズ 被ポインタ対応 合成回復
array YES YES YES
vector YES YES YES
vector<bool> YES NO NA
deque YES YES YES
forward_list YES YES YES
list YES YES YES
set YES NO NO
multiset YES NO NO
map YES YES YES
multimap YES NO NO
unordered_set YES NO NO
unordered_multiset YES NO NO
unordered_map YES YES YES
unordered_multimap YES NO NO

なお、multimapとunordered_multimapについては同様の手法により「被ポインタ」に対応することが可能ですが、下記理由により現時点では対応していません。必要性が高いことが分かったら対応します。

  • 必要性はあまり高くないと考えています。
  • 現仕様なら合成回復と同じコンテナに対応することになるので混乱しにくい。

yossi-tahara added a commit that referenced this issue Feb 12, 2017
  バージョン名の"-Prerelease."を解除。
  2017/01/31の警告レベルアップ時の対処漏れ追加。
    msvcのデバッグ・ビルドでclangのDecl.h(C4389)とHashing.h(C4310)にて警告がでていたので修正。
    fast_serializer.hでC4251ディセーブル漏れ追加。

----------------- MD5 Hash Values -----------------
TheolizerDriver  : 237e5af395c8b8bd4162c97c923c4903
TheolizerLibrary : 1f50826361e1a8fda9cfe6a4d998e3d3
Library's Header : 5af7578870c837e4a82f3f60fcb61f6b
@yossi-tahara
Copy link
Owner Author

v0.4.3としてリリースしました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant