# Salsa patterns and FAQs ## How do I model spans (line/column numbers)? - Anchors! The identity of a tracked span doesn't change, but the values of its fields might. - https://salsa.zulipchat.com/#narrow/stream/333573-Contributing-to-Salsa/topic/salsa.20patterns.20and.20FAQs/near/472909190 ## How do I model a virtual file system? * [Lazy with lazy source text](https://github.com/astral-sh/ruff/blob/main/crates/ruff_db/src/files.rs#L52) ## How do I move an "eager" computation into a "lazy" one (something done on demand?) Imagine you have some ## When should I use `salsa::tracked` vs `salsa::interned`? The semantic difference between the two is based on *identity*: * Interned structs have no identity, so `InternedStruct::new(a, b, c) == InternedStruct::new(x, y, z)` is true if `a == x && b == y && c == z`. * Tracked structs have individual identity, so every `TrackedStruct::new` yields a value struct that is not `==` to any other tracked struct. ## How cheap are interned/tracked structs? Cheap! You should be able to use them freely. If you find that's not true, let's talk about it. ## What's the `Update` trait for? ## How to update data "in-place" ```rust // Salsa will cancel any pending queries and remove its own reference to `open_files` // so that the reference counter to `open_files` now drops to 1. let open_files = self.set_open_fileset(db).to(None); let open_files = if let Some(open_files) = open_files { Arc::try_unwrap(open_files).unwrap() } else { FxHashSet::default() }; // Now mutate the data strucuture open_files.insert(file); // And write it back to the database self.set_open_files(db).to(open_files); ``` [source](https://github.com/astral-sh/ruff/blob/bbb044ebda2890061dba6ec53d3d55e0932041ba/crates/red_knot_workspace/src/workspace.rs#L268-L280)