1 / 49

Persistent deques

Persistent deques. Lets revisit queues first. Only pop & inject. It will be possible to generalize our solution in various ways so we can get a purely functional solution with O(1) time per push, pop, inject, eject, and catenate !. suffix. prefix. Queues revisited.

lmilton
Download Presentation

Persistent deques

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Persistent deques

  2. Lets revisit queues first. Only pop & inject It will be possible to generalize our solution in various ways so we can get a purely functional solution with O(1) time per push, pop, inject, eject, and catenate !

  3. suffix prefix Queues revisited Represent a queue over A by a triple (prefix, queue over AA, suffix) Prefix and suffix contain at most 2 elements of the queue. suffix prefix

  4. Inject suffix prefix suffix prefix

  5. Inject suffix prefix suffix suffix prefix

  6. suffix suffix Inject suffix prefix suffix suffix prefix

  7. suffix suffix suffix Inject suffix prefix suffix suffix prefix

  8. Inject suffix prefix suffix suffix suffix suffix prefix suffix

  9. Inject suffix prefix suffix suffix suffix suffix suffix prefix suffix

  10. suffix suffix suffix suffix Inject suffix prefix suffix suffix suffix suffix suffix prefix suffix

  11. Inject suffix prefix suffix suffix suffix suffix suffix suffix prefix suffix suffix suffix suffix

  12. Inject suffix prefix suffix suffix suffix suffix suffix suffix suffix prefix suffix suffix suffix suffix

  13. result = inject(x,d) If (suffix(d) = (a,b) ) then d’ := inject(child(d),(a,b)) child(d) := d’ suffix(d) := empty endif allocate(result) prefix(result) := prefix(d) child(result) := child(d) suffix(result) := allocate(suffix(d) + x)

  14. (x,r)= pop(Q) suffix prefix suffix prefix

  15. (x,r)= pop(Q) suffix prefix prefix suffix prefix

  16. (x,r)= pop(Q) suffix prefix prefix suffix prefix

  17. prefix prefix (x,r)= pop(Q) suffix prefix prefix suffix prefix Formal definition of the algorithm is similar to inject, do by yourself.

  18. How do we analyze this ? We want each call to inject (pop) that triggered another call to inject (pop) to release one unit of potential. ==> suffix suffix suffix ==> prefix prefix prefix

  19. Fully persistent queues -- analysis Define a suffix with 2 elements as red. Define a prefix with 0 elements as red. Otherwise the buffer is green. ==> suffix suffix suffix ==> prefix prefix prefix

  20. Fully persistent queues -- analysis Maybe  = # (red buffers) ? Red buffers still exists for other queues after the change. ==> suffix suffix suffix ==> prefix prefix prefix

  21. Fully persistent queues -- analysis Define a queue/subqueue as either rr, rg, gg Either an rr queue dies and we get two rg queues or an rg queue dies and we get two gg queues ==> suffix suffix suffix ==> prefix prefix prefix

  22. Fully persistent queues -- analysis  = 3# (rr) + #(rg) ==> suffix suffix suffix ==> prefix prefix prefix

  23. Fully persistent deques How do we generalize this to allow insertions/deletions from both sides ? Increase the size of the buffers to 0-3. Everything else is the same, when a buffer is full we may have to do a recursive push/inject, when a buffer is empty we may have to do a recursive eject/pop. Analysis: Define prefix/suffix to be red if it contains either 0 or 3 elements.

  24. Worst-case bounds/purely functional implementation Increase the size of the buffers to 0-5. Define a buffer as red if it contains 0 or 5 elements yellow if it contains 1 or 4 elements green if it contains 2 or 3 elements Let green < yellow < red and define the color of a deque as the maximum of the colors of its buffers.

  25. 1 0 2 Purely functional deques Let green = 0 red = 2 yellow = 1 Think of the stack of queues as a redundant binary counter. prefix suffix suffix prefix suffix prefix

  26. 1 0 2 Purely functional deques Push/pop/inject/eject may increase the least significant digit. Then you need to do a fix. Fix: fill an empty buffer by popping from the corresponding buffer of the subqueue. Similarly empty a full buffer. prefix suffix suffix prefix suffix prefix

  27. Representation 2 1 1 0 1 2 1 1 We need a purely functional representation of these counters.

  28. 2 0 0 1 1 Stack of stacks representation 2 0 0 1 1 1 1 1 Only a constant number of new nodes per increment.

  29. Purely functional deques 2 0 1 1

  30. Adding catenation We will do only steques (no eject) prefix, steque of pairs, suffix pair = (prefix, steque of pairs) prefix contains 2-6 elements suffix contains 1-3 elements

  31. Adding catenation (cont)

  32. Adding catenation (cont)

  33. Push

  34. Push

  35. Push Inject is similar.

  36. Catenate

  37. Pop

  38. Pop

  39. Pop

  40. Pop catenate There are two more cases. The analysis is similar to what we have seen before

  41. Summary In the paper: The full set of operations. Together with some generalization of the counters you can get a purely functional implementation with worst case performance.

  42. Alternative approaches Put the items at the leaves of a tree which is at least binary. Catenation is done via linking: left linking

  43. Alternative approaches (cont.) Alternative forms of linking right linking symmetric linking

  44. Alternative approaches (cont.) How to pop ? v flip v <==> u w Left path reversal: Do right flips bottom-up on the parent of the leftmost leaf.

  45. Alternative approaches (cont.) After the left path reversal: r` r Create a new root for the queue after the pop. Represent children lists as deques (or steques) so each flip takes constant time, and duplicating the root takes constant time

  46. Alternative approaches (cont.) Can do eject symmetrically, do push and inject via catenation Can analyze only for steques (when eject is not allowed). (Okasaki FOCS’96) The performance in general is not known ??

  47. Alternative approaches (cont.) To avoid pushing down stuff on the right side of the tree when doing a left path reversal replace the flips with the following v v <==> u w z w Performance of this is not known ??

  48. Alternative approaches (cont.) Can we avoid the extra persistent machanism to represent children lists ? w w <==> v z y u Here stacks suffice if there is no eject.

  49. z y D C x A B Alternative approaches (cont.) Use binary trees. Link by symmetric linking. To pop do a splay on the parent of the leftmost leaf and then delete it and its parent. x ==> A y B z C D

More Related