12. スケジュールの導入
ローテーション実行中にrotateDrop関数と rotateRev関数が作成したサスペンションを、
次回のローテーション開始までに全て実行しなければなりません。
このためにスケジュールを導入します。
type ‘a queue = int * ‘a Stream * ‘a Stream (* front *)
* int * ‘a Stream * ‘a Stream (* rear *)
データサイズ データ スケジュール
ローテーションで新しいフロントとリアができるので、そのままスケジュールとします。
let j = (lenf + lenr) / 2; let i = lenf + lenr –j;
let r' = S.take (j, r); let f' = rotateDrop (f, j, r)
in (i, f', f', j, r', r')
Streamを順に開いていくことでサスペンションを実行します。
fun exec1 ($CONS (x, s)) = s
| exec1 s = s
18. おまけ: Global Rebuildingとの違い
だいたいこんな感じだと思います。
• Global Rebuildingには必要だったローテーション用のコピーが、Lazy Rebuildingで
は不要。
• Global Rebuildingを使用したHood MelvilleQueueでは、ローテーションに必要な処
理が比較的均等に分散していたが、Lazy Rebuildingを使用したRealTimeDequeで
は、短い方のStreamを再作成する$CONSだけを使ってdropやreverse遅延させて
いるので、サスペンションの実行コストに偏りがある。
19. 参考文献
• Chris Okasaki, “8.4.3 Real-Time Deque”, Purely Functional Data Structures,
Cambridge University Press (1999)
• Chris Okasaki, “Simple and efficient purely functional queues and deques”, Journal
of Functional Programming, 5(4):583-592, October 1995