Posted by & filed under 開発.


 前回 は Stream オブジェクトをリモートアクターに転送するにはどうすればいいか?という話でした。

 せっかく Straem を使うわけですから。List に変換したり、転送時に Stream を foreach で走査して、再構築するなんて事はしないで。値の評価の遅延だけでなく、プロセス間のデータ転送まで遅延したいところです。

 という事で。Stream のデータ転送を遅延する、抽象化機構を作ってみました。
 この Stream を抽象化するデータ構造を AStream とここでは名づけます [*1]。

 まず。リモートアクターに Stream 転送する際、直接 Stream を送らないで別のデータ構造に変換してからリモートに転送するようにします。
 そこで、入力に Stream オブジェクトを取る set メソッドを作り、出力に入力した Stream に可換な別のデータ構造を吐き出すようにします。具体的に、送信側では以下のようにします。

 [送信側の実装の抜粋]

 AStream.set は以下のケースクラスのインスタンスをリモートに送ります。

 リモートでデータを受け取り、Stream を取り出す実装は以下のようにします。

 [受信側の実装の抜粋]

 リモートの受信側では、SendStream の各メンバを引数に AStream オブジェクトの get メソッドを呼び出し、Stream を抽出します。
 以下が get メソッドの実装です。ここまでの話は、かなり手続的な内容でしたが。ここでようやく Stream の本領発揮です。

 [AStream のコード抜粋]

 ここでの処理は、送信側に Stream の中身を問い合わせて、先頭要素だけを送ってもらうという事をしています(もちろん送信側では、この処理の後に先頭要素を次要素にスライドさせます)。ただし、Stream.empty は、空リスト (Nil) に変換して送ってもらい、リモート側で Stream.empty に戻します。
 ミソは 10 行目の再起が Stream によって遅延評価される事です。この時点では 10 行目の get メソッドは評価されず、「次に評価するのは僕ですよ」という事だけ教えて Stream を返します。なのでここでの処理は一瞬で終わります。
 
 実際に先頭以降の要素を送信側から取ってくるのは、値が参照されたとき ([受信側の実装] の tail が実行されたとき) になります。このときに始めて AStream.get メソッドで返された Stream の次の要素 (get メソッド) の評価が行われ、送信側から次の要素が入った Stream が返されます。

 こうすることで、データ転送を遅延する Stream の転送が実現できました。
 こんな事しなくても、別の (もっと簡単な) 方法を知ってるぜ。という方は、是非コメントください。

[*1] AStream のコード : AStream.scala


関連文書:

  • 関連文書は見つからんがな

Comments are closed.