Object store

The objects store is the place where objects are stored permanently. It is similar to (but also very different from) the file system of other systems.

Gracle does not have files

Gracle does not have files in the traditional meaning of files. It does not make a distinction between primary and secondary storage. The semantics that apply to all Gracle object is that of random-access memory. Files are replaced by strings and other structured objects containing characters. This implies that Gracle has a single-level store.

Other operating systems have had single-level stores. Multics did in the 1970s. For Gracle, we plan to use universal persistence, i.e., every object is automatically persistent and will survive between reboots. The easiest way to implement persistence is to have a battery backup for the memory, and to save the memory to disk before shutting down the system.

The great advantage of not having files in a traditional sense is that applications do not have to convert its objects to sequences of bytes in order for data to persist between invocations. Structured objects in main memory are all persistent.

Objects are not organized in a hierarchy

We would like to eliminate the hierarchy of objects (files) that has become standard since it was introduced in the 1960s. Most often, the order of the directories in the path of an object in such a hierarchy is not meaningful to the user, but imposed by the hierarchy.

Also, we would like to be able to construct collections of object on the fly, and not be limited to the collections that the directories of a hierarchy imposes, for instance ``the collection of all email messages less than a month old and with a PDF attachment''.

While we could settle with the means of access to objects provided by Common Lisp (special variables), it seems useful to have some kind of ``data base'' of objects that are accessible by queries like the one above. Obviously, we do not want every cons cell to be accessible this way. For that reason, we distinguish between objects that are archived and objects that are not. The concept of archived objects is different from that of persistent objects. In Gracle, all accessible objects are persistent in that they do not disappear at logout our system shutdown. Archiving an object just means giving it certain properties and making it accessible by queries like the one above. Such properties include creation date and perhaps a number of tags that serve the same purpose as directory names in traditional hierarchical systems. Tags and dates are not stored in the objects themselves, but in data structures (such as hash tables) external to the objects. This way, it is possible to archive very small objects such as cons cells without it being necessary to reserve space in each cons cell for archive information.

In a traditional hierarchy, the current directory serves two different purposes. The first is to serve as a current collection of objects that is currently manipulated by the user. This collection is determined by the fact that all objects in the collection share the same prefix in the path name. The second purpose is to give newly created objects this prefix so that such objects become members of the same collection.

For Gracle, We suggest using a set of current properties defining the current collection of objects, and a set of assigned properties that define what properties newly archived objects will inherit. They are not the same, since the current properties might include restrictions on date of creation and any other arbitrary filter, whereas newly archived objects would be assigned some properties automatically (date) and others would come from the assigned properties (such as whether the object is part of some named collection of documents).

The most general form of the current properties would be a predicate that takes the tags of an object and that answers T or NIL. While that system is very general, it might not be fast enough (then again it might). It may be necessary to restrict the form of the current properties so that the object store can use various caching mechanisms and indexing schemes to avoid searching tag sets that are known not to correspond to the current properties.

Like we said, it might be fast enough to check all tag sets each time the current selection changes. First, the current selection doesn't change that often, and when it changes, it is as a result of a user interaction (the equivalent of the Unix cd command). By storing the tags separately from the objects that are tagged, one could hope to avoid paging when the object store is searched. It is not unreasonable to search millions of tag sets this way, by applying a function to each tag set and checking the result.