///|
/// Build an OrderTree from an array of elements in O(n) time.
/// Filters zero-span items, pre-merges adjacent mergeable elements,
/// then builds bottom-up.
pub fn[T : @rle.Spanning + @rle.Mergeable] OrderTree::from_array(
items : Array[T],
min_degree? : Int,
) -> OrderTree[T] {
let t = match min_degree {
Some(d) => if d < 2 { 2 } else { d }
None => 10
}
if items.is_empty() {
return OrderTree::new(min_degree=t)
}
// Filter zero-span and pre-merge adjacent elements
let merged : Array[T] = []
for item in items {
if @rle.Spanning::span(item) <= 0 {
continue
}
match merged.last() {
Some(last) =>
if @rle.Mergeable::can_merge(last, item) {
merged[merged.length() - 1] = @rle.Mergeable::merge(last, item)
} else {
merged.push(item)
}
None => merged.push(item)
}
}
if merged.is_empty() {
return OrderTree::new(min_degree=t)
}
let pairs = merged.map(elem => (elem, @rle.Spanning::span(elem)))
{ tree: @btree.BTree::from_sorted(pairs, min_degree=t) }
}