Open treeowl opened 4 years ago
Aha! We can actually do something simpler. We should only need a one-fingered tree. Moreover, we don't need to be able to pop off the entry by the finger particularly quickly, so we can reduce the number of digits without deepening the trees (1 digits can be considered "safe"). So using most of the definitions above, I think we can write
data Tree k a
= Single !a
| One {-# UNPACK #-} !(MinMax k) !a (Tree k (Node a))
| Two {-# UNPACK #-} !(MinMax k) !a !a (Tree k (Node a))
| Three {-# UNPACK #-} !(MinMax k) !a !a !a (Tree k (Node a))
This needs a whole custom meld, but that's just tedious, not hard.
For performance reasons, this should probably copy ideas and some (modified) code from the
fingertree
package, but not use its actualFingerTree
type. Here's the general idea:The code for
meld
can be copied from the code for><
infingertree
, but using<>
instead ofmappend
and being stricter in the spine than what that package currently does (it will probably be fixed soon). The code forminView
andmaxView
should be similar to the code forData.Sequence.deleteAt
, but using the search procedure infingertree
.This implementation should offer:
insert
: persistently amortized O(1); worst-case O(log n).minView
,maxView
: O(log n)meld
: O(log n)