GListModel as a file format interface

One of the things I’ve done this cycle leading up to GNOME 45 is some rework on how we process *.syscap files. In particular, I wanted to really push the GListModel interface in GTK 4.

That is a tall order at first sight because Sysprof capture files easily have hundreds of thousands of data frames. To create an object for each would be an enormous amount of overhead.

However, GListModel allows you to create objects on demand, which means you only need to create them as necessary.

But that becomes a bit more difficult once you need to segment those data frames like a database.

For example, one data frame type is samples (e.g. a stacktrace). Those need to be processed very differently than counter values. Since these documents are read-only, we can do a bunch of fun performance hacks!

Sysprof, in what will land very soon, uses a mmap() file for the underlying document. That document may be in a non-native endian format, so it has a bunch of helpers to deal with that so you can keep the memory map read-only. The document then exports a GListModel of data frames.

But lets say you want to have a SysprofDocument:samples property that is also a GListModel? You probably don’t want to filter a few hundred thousand objects (each needing to be inflated) just to create that index.

Sysprof gets around this by doing a single “full-table-scan” at startup and indexing the memory offsets of all the data frames. From there, we create roaring bitmaps of all the sorts of indexes we need at runtime. Then you can take that document (a GListModel) plus a roaring bitmap to create a new indexed GListModel. Position 0 in that new model will map to position N in the document, based on the roaring bitmap index. Very handy.

So now you can have all sorts of properties on that document like samples, memory allocations, counters, logs, marks, files, metadata, and more. This makes data binding to GtkBuilder templates very easy and natural.

To take it to the next level though, you have essentially a table with indexes. And where those become powerful is through the use of index intersection.

So now Sysprof will even index which symbols show up in which stack traces. That means you very quickly find stack traces which have a prefix/suffix or even just contain any number of specific functions by intersecting the indexes which itself yields a new index.

Anyway, GListModel all the way down seems to be working out a whole lot better than I anticipated, and this will probably change how I write applications going forward.