Find live name vertices attached to an inode under a view's change filter. A name resolution or rename can remove a name without deleting the inode's content. Callers can inspect these vertices' bytes to match a filename. # Examples ```rust,ignore let options = RetrieveOptions::new().with_change_filter(visible_changes); let names = live_inode_names(&txn, inode_position, &options)?; ```
(
txn: &T,
inode: Position<NodeId>,
options: &RetrieveOptions,
)
| 16 | /// let names = live_inode_names(&txn, inode_position, &options)?; |
| 17 | /// ``` |
| 18 | pub fn live_inode_names<T: GraphTxnT>( |
| 19 | txn: &T, |
| 20 | inode: Position<NodeId>, |
| 21 | options: &RetrieveOptions, |
| 22 | ) -> Result<Vec<GraphNode<NodeId>>, PristineError> { |
| 23 | let mut names = Vec::new(); |
| 24 | for edge in txn.get_edges(inode.inode_node())? { |
| 25 | let flags = edge.flag(); |
| 26 | if !flags.contains(EdgeFlags::FOLDER | EdgeFlags::PARENT) |
| 27 | || flags.intersects(EdgeFlags::DELETED | EdgeFlags::PSEUDO) |
| 28 | || !options.passes_filter(edge.introduced_by()) |
| 29 | { |
| 30 | continue; |
| 31 | } |
| 32 | let end = edge.dest(); |
| 33 | if end.change.is_root() || end.pos.get() == 0 { |
| 34 | continue; |
| 35 | } |
| 36 | // The predecessor name ends at this position. find_block_end would |
| 37 | // prefer the empty inode marker at the same position for a FileAdd. |
| 38 | let name = txn.find_block(Position::new( |
| 39 | end.change, |
| 40 | ChangePosition::new(end.pos.get() - 1), |
| 41 | ))?; |
| 42 | let mut linked = false; |
| 43 | let mut unlinked = false; |
| 44 | // Namespace edges carry BLOCK|FOLDER together. Inspect those flags |
| 45 | // directly; the content-oriented typed parent iterator can omit them. |
| 46 | for parent in txn.get_edges(name)? { |
| 47 | let flags = parent.flag(); |
| 48 | if flags.contains(EdgeFlags::PARENT | EdgeFlags::FOLDER) |
| 49 | && !flags.contains(EdgeFlags::PSEUDO) |
| 50 | && options.passes_filter(parent.introduced_by()) |
| 51 | { |
| 52 | if flags.contains(EdgeFlags::DELETED) { |
| 53 | unlinked = true; |
| 54 | } else { |
| 55 | linked = true; |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | if options.passes_filter(name.change) && linked && !unlinked && !names.contains(&name) { |
| 60 | names.push(name); |
| 61 | } |
| 62 | } |
| 63 | Ok(names) |
| 64 | } |
no test coverage detected