Context
My app's model is a tree of objects where each object represents a filesystem item (a folder or file) on disk beneath a given starting folder.
Periodically, I recursively walk this tree from top-down in order to "sync" it to the actual state of the filesystem. That is, I visit each object in the model and verify that the file/folder it represents still exists in the same location on disk.
If the file/folder has moved, I use an NSURL bookmark to ascertain the new location of the file/folder so that I can update my model's state. (I create an NSURL bookmark when I first create the model object and then store the bookmark data as a property of the object so that I can resolve it later.)
The Problem
NSURL bookmarks simply aren't performant enough. It's not uncommon for my model graph to have 20,000 nested objects. Each one has a bookmark. Here's what I'm seeing when I profile performance:
The recursivelyValidateExistingChildItemsOfParentItem:... method is what walks my model tree. 90% of the time involved is just resolving bookmarks (and, if they are stale, re-creating them as described in Apple's documentation).
The app takes almost 2 minutes to complete the walk thanks to this. So, I need a faster alternative to NSURL bookmarks.
What I've Considered
Extended File Attributes. I could add a UUID attribute to each file on disk. Instead of walking my model graph, I could walk the actual filesystem underneath the starting folder. When I find a new file, I could see if it has a UUID extended attribute. If so, I could then search my model graph for the object with that UUID to handle moved/relocated files. The trouble here is that many things clobber extended file attributes—they aren't guaranteed to stick around.
BDAliasorNDAlias. I used to useBDAliasbefore I migrated toNSURLbookmarks, but that wasn't exceptionally more performant.
Bottom Line
I need a faster alternative to NSURL's bookmarks. But I still need to be able to track files across launches of my app, so simply keeping file descriptors open or using file id's won't work.
I don't care how low-level I have to get; I just need performance. Thanks!
