///|
/// Maximal valid spans on which every selected key has an assigned value.
/// Empty selection is the whole bounds. This does not compare the values.
pub fn Ledger::joint_assigned_spans(
self : Ledger,
keys : Array[String],
bounds : Span,
known_at : Int64,
max_keys? : Int = 64,
max_segments? : Int = 4096,
) -> Array[Span] raise TemporalError {
if max_segments <= 0 {
raise TooManySegments(maximum=max_segments)
}
let selected = unique_query_keys(keys, max_keys)
let mut result = [bounds]
for key in selected {
if result.is_empty() {
break
}
let available = self.matching_spans(
key,
bounds,
known_at,
Assigned,
max_segments~,
)
let shared : Array[Span] = []
let mut a = 0
let mut b = 0
while a < result.length() && b < available.length() {
match result[a].intersection(available[b]) {
Some(span) => {
if shared.length() >= max_segments {
raise TooManySegments(maximum=max_segments)
}
shared.push(span)
}
None => ()
}
if end_before(result[a].end, available[b].end) {
a += 1
} else if end_before(available[b].end, result[a].end) {
b += 1
} else {
a += 1
b += 1
}
}
result = shared
}
result
}