Live Queries: Searching Haiku's File System Like a Database
A live query doesn't just return files matching a condition once — it keeps the result set current automatically, as files are created, changed, or deleted, for as long as the query stays open.
An ordinary file search answers a question once: “which files currently match this condition?” A live query, built on top of BFS’s indexed attributes, answers a different, more useful question: “which files match this condition, kept continuously up to date, for as long as I’m watching?”
What makes a query “live”
A live query is expressed the same way a one-time query would be — a predicate over one or more indexed attributes, such as MIME:Type == "audio/mpeg" && Audio:Artist == "Miles Davis" — but instead of running once and returning a fixed snapshot, the application keeps the query object open and receives update notifications whenever a file starts matching, stops matching, or a matching file is removed entirely:
BQuery query;
query.SetVolume(&volume);
query.PushAttr("Audio:Artist");
query.PushString("Miles Davis");
query.PushOp(B_EQ);
query.SetTarget(this); // this BHandler receives live update messages
query.Fetch();
From that point on, the application’s designated BHandler receives B_QUERY_UPDATE messages whenever the underlying file set changes — a new song tagged with that artist appearing anywhere on the volume, or a matching file being deleted or retagged — without the application needing to re-run the query itself or poll for changes.
Why this is a direct consequence of indexing, not extra machinery
Live queries don’t require some separate notification subsystem bolted on top of BFS — because indexed attributes are already tracked via B+tree indexes that get updated whenever a file’s indexed attribute changes, the file system already has, as a matter of routine housekeeping, precisely the information needed to know when a change affects an open query’s result set. Making that information available to a listening application is a comparatively small addition once the indexing infrastructure itself already exists.
What this replaces
Without this capability, “show me a continuously updated view of files matching some condition” would need to be implemented at the application layer — either polling the file system repeatedly (wasteful, and never perfectly current between polls) or maintaining a separate, hand-rolled notification mechanism specific to that one application. Live queries move that capability down into the file system itself, available identically to any application, rather than requiring every piece of software that wants this behavior to reinvent it.
A practical example: a virtual, self-maintaining folder
A common use of live queries is a saved search that behaves like a folder — “every image file modified in the last week,” say — except its contents update automatically as files are created, edited, or deleted anywhere covered by the query, without anyone needing to manually refresh it or re-run a search. Haiku’s Tracker (its desktop/file-manager shell) supports exactly this pattern natively, letting a user save a query as something that looks and behaves like a folder in the file browser, but is actually a continuously-live view rather than a fixed set of files someone manually placed together.
Why this remains a distinctive BFS capability
Building a genuinely live, continuously-updating query directly into the file system — rather than as a separate indexing/search service layered on top, which is how most other platforms provide comparable functionality — is only possible because BFS was designed from the start with attribute indexing as a core feature rather than an add-on. It’s a clear, practical example of how a foundational design decision made for BeOS in the 1990s (attributes and indexes as first-class file system concepts) continues to pay off in a genuinely useful, still-uncommon capability today.