Title: Persistent deques
1Persistent deques
2Lets 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 !
3Queues 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
4Inject
suffix
prefix
suffix
prefix
5Inject
suffix
prefix
suffix
suffix
prefix
6Inject
suffix
prefix
suffix
suffix
prefix
7Inject
suffix
prefix
suffix
suffix
prefix
8Inject
suffix
prefix
suffix
suffix
suffix
suffix
prefix
suffix
9Inject
suffix
prefix
suffix
suffix
suffix
suffix
suffix
prefix
suffix
10Inject
suffix
prefix
suffix
suffix
suffix
suffix
suffix
prefix
suffix
11Inject
suffix
prefix
suffix
suffix
suffix
suffix
suffix
suffix
prefix
suffix
suffix
suffix
suffix
12Inject
suffix
prefix
suffix
suffix
suffix
suffix
suffix
suffix
suffix
prefix
suffix
suffix
suffix
suffix
13result 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(r
esult) 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(x,r) pop(Q)
suffix
prefix
prefix
suffix
prefix
Formal definition of the algorithm is similar to
inject, do by yourself.
18How do we analyze this ?
We want each call to inject (pop) that triggered
another call to inject (pop) to release one unit
of potential.
gt
suffix
suffix
suffix
gt
prefix
prefix
prefix
19Fully persistent queues -- analysis
Define a suffix with 2 elements as red.
Define a prefix with 0 elements as red.
Otherwise the buffer is green.
gt
suffix
suffix
suffix
gt
prefix
prefix
prefix
20Fully persistent queues -- analysis
Maybe ? (red buffers) ?
Red buffers still exists for other queues after
the change.
gt
suffix
suffix
suffix
gt
prefix
prefix
prefix
21Fully 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
gt
suffix
suffix
suffix
gt
prefix
prefix
prefix
22Fully persistent queues -- analysis
? 3 (rr) (rg)
gt
suffix
suffix
suffix
gt
prefix
prefix
prefix
23Fully 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.
24Worst-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 lt yellow lt red and define the color of
a deque as the maximum of the colors of its
buffers.
25Purely functional deques
Let green 0 red 2 yellow 1 Think of the
stack of queues as a redundant binary counter.
suffix
prefix
suffix
prefix
suffix
prefix
26Redundant binary counters
We shall allow an additional digit. Use 0,1, and
2, but keep the base to be 2 !
012110 020 121 122 223 124 38
The representation now is not unique
Can represent 38 also by 020110 or 100110
We shall exploit the redundancy.
27Exploiting the redundancy
We are not going to use all possible
representations
Define a representation to be regular if it does
not contain the following patterns
211111112...
211111111
When you walk from left to right after you see a
2 you should see a 0 before hitting another 2 or
running out of digits
28Redundant binary counters (cont)
Note every number has a regular representation.
Given a regular representation for x, how do you
get a regular representation for x1.
1) increment the rightmost digit. We get a
representation for x1 which may not be regular
.2101210 gt ..2101211 2) If indeed so,
then replace the rightmost 2 with a 0 and
increment the digit to its left. (Fix)
gt ..2102011
29Purely 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.
suffix
prefix
suffix
prefix
suffix
prefix
30Representation
1
1
2
1
0
1
1
2
We need a purely functional representation of
these counters.
31Stack of stacks representation
1
0
0
2
1
1
1
1
Only a constant number of new nodes per increment.
32Purely functional deques
2
0
1
1
33Adding 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
34Adding catenation (cont)
35Adding catenation (cont)
36Push
37Push
38Push
Inject is similar.
39Catenate
40Pop
41Pop
42Pop
43Pop
catenate
There are two more cases. The analysis is similar
to what we have seen before
44Summary
In the paper The full set of operations. Togethe
r with some generalization of the counters you
can get a purely functional implementation with
worst case performance.
45Alternative approaches
Put the items at the leaves of a tree which is at
least binary.
Catenation is done via linking
left linking
46Alternative approaches (cont.)
Alternative forms of linking
right linking
symmetric linking
47Alternative approaches (cont.)
How to pop ?
v
v
flip
ltgt
u
w
Left path reversal Do right flips bottom-up on
the parent of the leftmost leaf.
48Alternative 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
49Alternative approaches (cont.)
Can do eject symmetrically, do push and inject
via catenation
Can analyze only for steques (when eject is not
allowed). (Okasaki FOCS96)
The performance in general is not known ??
50Alternative 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
ltgt
u
w
z
w
Performance of this is not known ??
51Alternative approaches (cont.)
Can we avoid the extra persistent machanism to
represent children lists ?
w
w
ltgt
v
y
z
u
Here stacks suffice if there is no eject.
52Alternative 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
gt
y
A
B
z
D
C