       cache: {}
       right: right
       io: new LeafIO @filename address
+
+  # Going forward, every will story keys, so that when we encounter a record, we
+  # don't have to run the extractor, plus we get some caching.
+  #
+  # Or maybe just three arrays, key, object and address? I'm talking about using
+  # each key as an object cache, by adding an object member to the key. But,
+  # they cache container is a hash table, which is a compactish representation,
+  # so why not make it yet anohter hash table? The logic gets a lot easier.
+  object: (tier, index, _) ->
+    address = tier.addresses[index]
+    if not object = tier.cache[address]
+      object = tier.cache[address] = tier.io.readObject address, _
+    object
+
+  key: (tierOrAddress, index, _) ->
+    if typeof tierOrAddress is "number"
+      leaf  = @lock false, tierOrAddress, true, _
+      key = @extractor @object leaf, index, _
+      @release leaf
+      key
+    else if tierOrAddress.leaf
+      @extractor @object tierOrAddress, index, _
+    else
+      address = tierOrAddress.addresses[index]
+      if not key = tierOrAddress.cache[address]
+        # Here's something to consdier. The only time we lock the leaf is during
+        # descent, to read in the key.
+        #
+        # If this leaf tier is locked exclusively, we are not the ones holding the
+        # lock, because that would mean that we are locking the inner tier, we
+        # would already have traversed the inner tier, the key would be in the
+        # cache.
+        #
+        # If this leaf tier has an exclusive lock pending, it is not a lock that
+        # we are waiting for, so we can append a shared lock and wait for multiple
+        # exclusive and shared locks to clear.
+        key = tierOrAddress.cache[address] = @key address, 0, _
+      key
+
+  # Write the branches to a file as a JSON string. We tuck the tier properties
+  # into an object before we serialize it, so that it is easy deserialize.
+  writeBranches: (tier, suffix, _) ->
+    filename = @filename tier.address, suffix
+    record = [ tier.penultimate, tier.next?.address, tier.addresses ]
+    json = JSON.stringify(record) + "\n"
+    fs.writeFile filename, json, "utf8", _
+
+  # Read branches from a brach tier file and assign the tier properties to the
+  # given tier object.
+  #
+  # TODO: Move link to head always, to maintain MRU.
+  readBranches: (tier, _) ->
+    filename = @filename tier.address
+    json = fs.readFile filename, "utf8", _
+    [ penultimate, next, addresses ] = JSON.parse json
+    extend tier, { penultimate, next, addresses }
+
+  # TODO Consider: can't I always just rewrite and link?
+  rewriteBranches: (tier, _) ->
+    @writeBranches(tier, ".new", _)
+
+  # TODO Ensure that you close the current tier I/O. Also, you must also be very
+  # much locked before you use this, but I'm sure you know that.
+  
+  # Compact a leaf tier file by writing it to a temporary file that will become
+  # the permanent file. All of records referenced by the current address array a
+  # appended to a new leaf tier file using insert objects. An address array
+  # object is appended to the end of new leaf tier file. The new file will load
+  # quickly, because the address array object will be found immediately.
+  rewriteLeaves: (tier, _) ->
+    io = new LeafIO @filename(tier.address, ".new")
+    addresses = []
+    cache = {}
+    for i in [0...tier.addresses.length]
+      object = @object tier, i, _
+      address = io.writeInsert(object, i, _)
+      addresses.push address
+      cache[address] = object
+    io.writeAddresses(tier.right, addresses, _)
+    io.close(_)
+    extend tier, { addresses, cache }
 
   readLeaves: (tier, _) ->
     filename = @filename tier.address

      true
    false

# ### Leaf Tier Files
#
# A leaf tier maintains an array of file positions called an address array. A

    catch e
      throw e unless e.code is "ENOENT"
    fs.rename replacement, permanent, _

  # TODO Move down, bring read and write up.
  lock: (exclusive, address, leaf, callback) ->
    if not tier = @cache[address]
      @cache[address] = tier =
        @link({ leaf, address, cache: {}, addresses: [], locks: [[]] })
    locks = tier.locks
    if tier.loaded
      lock = callback
    else
      lock = (error, tier) =>
        if error
          callback error
        else if tier.loaded
          callback null, tier
        else if leaf
          @readLeaves tier, callback
        else
          @readBranches tier, callback
    if exclusive
      throw new Error "already locked" unless locks.length % 2
      locks.push [ lock ]
      locks.push []
      if locks[0].length is 0
        locks.shift()
        lock(null, tier)
    else
      locks[locks.length - 1].push lock
      if locks.length is 1
        lock(null, tier)

  resume: (tier, continuations) ->
    process.nextTick =>
      for callback in continuations
        callback(null, tier)

  # Remove the lock callback from the callback list..
  release: (tier) ->
    locks = tier.locks
    running = locks[0]
    running.shift()
    say { locks }
    if running.length is 0 and locks.length isnt 1
      locks.shift()
      @resume tier, locks[0] if locks[0].length
      
  upgrade: (tier, _) ->
    @release tier
    @lock true, tier.address, false, _

class exports.Strata
  # Construct the Strata from the options.
