When I last blogged about it, I discussed the need for an object-map. The object-map maps logical object ids to the physical location that the durable store placed the object. We'll be putting a couple more kinds of things in the durable store, so at this point it is a good idea to add a record abstraction on top of the durable store. It is easier to show this than to describe it. Here are the actual contents of a test durable store:
;;; A persistent store. Do not edit. (object 1 929 <string> 1 "zip") (leaf 1 38) (object 1 269 <string> 1 "zero?") (leaf 1 82) (branch 1 116 0 38) (object 1 387 <string> 1 "yield-current-thread") (leaf 1 148) (branch 1 0 197 82) (leaf 1 38) (leaf 1 82) (branch 1 242 230 148) (object 1 535 <string> 1 "xsubstring-move!") (leaf 1 277) (branch 1 322 0 38) (branch 1 242 335 148) (object 1 295 <string> 1 "xsubstring-find-previous-char-in-set")A ‘record’ is simply a list. The first element is one of
branch. The second element is the version number of the record layout in case I decide to change how the record is represented. The remaining elements are the contents of the record. For a leaf, it is simply the address of the object that this leaf represents. For a branch, it is the addresses of the left and right child and the address of the object the branch represents. (This is using a functional binary tree as detailed in the code.) An object record has four additional components. First is the object-id. Second is the data tag of the object. Third is a version number of the serialization method for the object and finally the serialized representation of the object itself.
This is clearly not the most parsimonious representation, and it could be made much more robust by including record length information, checksums or CRCs, and by ensuring that user data (such as those strings) cannot spoof a record boundary, but this is demonstration code, not production code.
In the next installment, we add another record type.