基本的に単一スレッドからの編集しか許さなくて Rc<RefCell<NodeImpl>> したいんだけど、同時に、完全に複製したうえでツリーを Send にする (別スレッドへ転送可能にする) といったようなことも可能であってほしくて困っている
とりあえず Arc<Mutex<NodeImpl>> すれば可能にはなるんだけど、ひとつのツリーのインスタンスはひとつのスレッドからしか編集 (あるいは読み出し) されないという状況を作れるとして (方法はある)、 Mutex 使うのはオーバーヘッドクソデカそうで嫌。 Arc のアトミック操作までは許せるんだけど。
たとえば考えられるのは、同一スレッドでツリーを完全に複製したうえで所有権を破棄 (leak) して、生ポインタだけ別スレッドに転送してそっちで所有権を再度発生させるという手。
ただ、これだとコンパイラ側が変な最適化とかをかけてしまわないかという懸念が拭えないので困っている
たとえばスレッド1でオブジェクトaを複製して共有部分の一切ないオブジェクトbを作ったとして、bをリークさせて生ポインタをスレッド2に持っていきオブジェクトcを作ったとき、本当にスレッド2から見たcがスレッド1から見た (かつての) bと一致しているのだろうかと。
かなり不安がある
rust - Is it safe to `Send` struct containing `Rc` if strong_count is 1 and weak_count is 0? - Stack Overflow
https://stackoverflow.com/a/58998150
やっぱり駄目よね……
てことは、やっぱり無難にやるには「スレッドローカルな操作専用の一連の型」と「スレッドを跨いだ操作の可能な一連の型」の2つのセットを用意して相互変換を実装する感じになるか、あるいは「スレッド間で転送するための (内部的な) 直列化形式」みたいなのを用意してやる必要があるか。
まあ後者だよなぁ……