     tier.cache = cache
     tier
 
+  # Move a new branch tier file into place. Unlink the existing branch tier
+  # file, then rename the new branch tier file to the permanent name of the
+  # branch tier file.
   relink: (tier, _) ->
     replacement = @filename(tier.address, ".new")
     stat = fs.stat replacement, _

      true
    false

class LeafIO
  constructor: (@filename) ->

  _drain: (callback) -> @out.once "drain", -> callback()

  _writeJSON: (object, _) ->
    @out or= fs.createWriteStream @filename,
      flags: "a"
      encoding: "utf8"
      mode: 0666
    @position or= fs.stat(@filename, _).size

    json            = JSON.stringify object
    position        = @position
    @position      += Buffer.byteLength(json, "utf8") + 1

    buffered = @out.write(json)
    buffered = @out.write("\n") && buffered

    position

  writeInsert: (object, index, _) ->
    @_writeJSON [ index + 1, object ], _

  writeDelete: (index, _) ->
    @_writeJSON [ -(index + 1) ], _

  writeAddresses: (right, addresses, _) ->
    @_writeJSON [ 0, right, addresses ], _

  _readJSON: (buffer, read) ->
    for offset in [0...read]
      if buffer[offset] is 0x0A
        return JSON.parse buffer.toString("utf8", 0, offset + 1)

  readObject: (address, _) ->
    @in or= fs.open @filename, "r", _
    @position or= fs.stat(@filename, _).size
    length = 1024
    loop
      buffer = new Buffer(length)
      read = fs.read @in, buffer, 0, buffer.length, address, _
      if json = @_readJSON(buffer, read)
        break
      if length > @position - address
        throw new Error "cannot find end of record."
      length *= 2
    json.pop()

  _closeOut: (callback) ->
    @out.once "close", -> callback()
    @out.destroySoon()

  close: (_) ->
    @close(@in, _) if @in
    @_closeOut(_) if @out
    @position = @in = @out = null

class IO
  constructor: (@directory, @extractor) ->
    @cache          = {}
    @head           = { address: -1 }

        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, 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", _)

