///|
/// Combine process, device+inode and waiter filters. Unknown owners never match a PID.
pub fn Snapshot::matching(
self : Snapshot,
pid? : Int32,
file? : FileKey,
waiting_only~ : Bool = false,
) -> Array[Entry] raise LockError {
if pid is Some(n) && n <= 0 {
invalid(0, "PID must be positive")
}
self.records.filter(e => {
(pid is None || (pid is Some(n) && e.owner == Process(n))) &&
(file is None || e.file == file) &&
(!waiting_only || e.depth > 0)
})
}
///|
/// Selected lines plus all their actual blockers, deduplicated in snapshot order.
pub fn Snapshot::with_blockers(
self : Snapshot,
lines : ArrayView[Int32],
) -> Array[Entry] raise LockError {
let wanted : Map[Int32, Bool] = Map([])
for line in lines {
wanted[line] = true
}
let keep = Array::make(self.records.length(), false)
for i, e in self.records {
if wanted.contains(e.line) {
keep[i] = true
wanted.remove(e.line)
}
}
for line, _ in wanted {
invalid(line, "no lock record at this source line")
}
for i = self.records.length() - 1; i >= 0; i = i - 1 {
if keep[i] && self.parents[i] is Some(parent) {
keep[parent] = true
}
}
let result : Array[Entry] = []
for i, e in self.records {
if keep[i] {
result.push(e)
}
}
result
}