           if not self.right
             self.right = right
           delete ordered[page.right]
+
+  splitLeaf: (branch, key, _) ->
+    address = branch.addresses[@io.find(child, @key, 1, _)]
+    @exclusive.push leaf = @io.lock address, true, true, _
+
+    # See that nothing has changed since we last descended.
+    { comparator: c, io, options: { leafSize: length } } = @
+    return if leaves.addresses.length < @options.leafSize
+
+    # We might have let things go for so long, that we're going to have to split
+    # the page into more than two pages.
+    partitions = Math.floor leaf.count / @options.leafSize
+    while (partitions * @options.leafSize) <= leaves.addresses.length
+      # Find a partition.
+      partition = Math.floor leaves.addresses.length / (partitions + 1)
+      key = io.key leaves, partition, _
+      pivot = @io.find(child, key, _) + 1
+
+      addresses = leaf.positions.splice(partition)
+      right = io.allocateLeaves(addresses, leaves.right)
+
+      leaves.right = right.address
+
+      child.addresses.splice(pivot, 0, right.address)
+
+      # Order of rewrites is to first write the pages out. Then delete the old
+      # files. Then copy the new files. The presence of a new file without an
+      # old file means to roll forward. The presence of new files each with and
+      # old file means to roll back.
+      #
+      # TODO Split relink into unlink and rename.
+
+      # Append an operation indciator. This would be a record that describes all
+      # the participants in the rewrite, in the order in which they are supposed
+      # to be rewritten. When found, we look at the last item in the list, then
+      # load that, and ensure that the last record is a complete operation
+      # record. If it is, we know that all of the temporary pages were written.
+      @io.rewriteLeaves(leaves, _)
+      @io.rewriteLeaves(right, _)
+
+      @io.rewriteBranches(child, _)
+
+      @io.relink(right, _)
+      @io.relink(leaves, _)
+      @io.relink(child, _)
+
+      --paritions
           
 # ## Cursors
 # 

class Cassette
  constructor: (@record, @key) ->

# Are we able to jump in, lock exclusive, or do we really need to go hand over
# hand. Here are some properties. There is only one thread of execution that is
# going to mutate branch pages, the same that does merges.
#
# We make a plan, moving from left to right, to merge. or else to split. Merges
# require
#
# We have a deleted page, and that page gets the deleted pages added to it. It
# is rewritten just as any other leaf page is rewritten. We rewrite. If you want
# to have that go very, very fast, then create small branch pages, and huge leaf
# pages.
#
# Leaning toward making a requirement that keys are unique. Duplicate keys can
# be a combination of system time and an offset, descent count. Maybe, maybe
# not.
#
# Degenerate case for all this is that we have someone inserting and deleting
# faster than we can balance, creating live lock. There are constant balance
# operations, not completing, and a back log of unbalanced pages. This may be an
# imagined problem.
#
# We track sizes using json length. A calcualated length, based on the JSON
# respesentation. When we reach a particular size, we purge the cache. We also
# have items that have no length, pages that we've cached for sizes for the sake
# of merge. We don't purge those pages if they are being used to calculate
# balance. We keep a reference count. We also only purge at balance time, so
# that we don't purge cached size data when it is needed.
# 
# When we delete an item, if it is the first record, we leave the item in place,
# to act as a key. We need to fix this during balance. When we delete the first
# item, we mark the item. How? Well, somehow, there is a flag that says that
# this item has been deleted, but still exists. In fact, it is the second item
# to the delete object, a boolean, true for retained false for destroyed. We put
# in a second one to delete it for good.
#
# During balance, 
#
# Our binary search will skip it during search.
#
# When we balance, if 

#              
class Descent
  # The constructor always felt like a dangerous place to be doing anything
  # meaningful in C++ or Java.

    @io         = @strata._io
    @options    = @strata._io.options

    { @extractor, @comparator } = @options

    @key        = @extractor @object if @object? and not @key?

  # TODO: We are always allowed to get a shared lock on any leaf page and read a
  # value, as long as we let go of it immediately. This allows us to read from
  # leaf pages to get branch values.

  cursor: (exclusive, _) ->
    @shared.push page = @io.lock 0, false, false, _
