anchor.diff:              blk:PageBlock
           }
   
  -    type private Location =
  +    // TODO gratuitously different names of the items in these
  +    // two unions
  +
  +    type private KeyLocation =
           | Inline
  -        | Overflow of len:int*page:int
  +        | Overflow of page:int
  +
  +    type private ValueLocation =
  +        | Tombstone
  +        | Buffer of vbuf:byte[]
  +        | Overflowed of len:int*page:int
   
       type private LeafPair =
           {
  -            pair:kvp
  -            keyLoc:Location
  -            valueLoc:Location
  +            key:byte[]
  +            kLoc:KeyLocation
  +            vLoc:ValueLocation
           }
   
       type private LeafState =
  
positive.code:                         {stateWithK with sofar=sofar + neededForInline}
                      else
                          let keyOverflowFirstPage = blk.firstPage
                          let newBlk = writeOverflow blk (new MemoryStream(k))
                          {stateWithK with sofar=sofar + neededForOverflow; blk=newBlk; overflows=overflows.Add(k,keyOverflowFirstPage)}
  
  
  
negative.code:                     prefixLen=(-1)
                      firstLeaf=firstLeaf
                      blk=nextBlk
                      leaves=pgitem(thisPageNumber,(List.head st.keys).key)::st.leaves
                      }
  
              let vbuf:byte[] = Array.zeroCreate pageSize
  
              let foldLeaf st (pair:kvp) = 
                  let k = pair.Key
                  // assert k <> null
                  // but pair.Value might be null (a tombstone)
  
                  // TODO is it possible for this to conclude that the key must be overflowed
                  // when it would actually fit because of prefixing?
  
                  let neededForOverflowPageNumber = sizeof<int32>
  
                  // TODO can the overflow page number become a varint?
  
                  // the max limit of an inline key is when that key is the only
                  // one in the leaf, and its value is overflowed.
  
                  let maxKeyInline = 
                      pageSize 
                      - LEAF_PAGE_OVERHEAD 
                      - 1 // prefixLen
                      - 1 // key flags
                      - Varint.SpaceNeededFor(int64 pageSize) // approx worst case inline key len
                      - 1 // value flags
                      - 9 // worst case varint value len
                      - neededForOverflowPageNumber // overflowed value page
  
                  let blkAfterKey,kloc = 
                      if k.Length <= maxKeyInline then
                          st.blk, Inline
                      else
                          let vPage = st.blk.firstPage
                          let _,newBlk = writeOverflow st.blk (new MemoryStream(k))
                          newBlk, (Overflow (vPage))
  
                  // the max limit of an inline value is when the key is inline
                  // on a new page.
  
                  let availableOnNewPageAfterKey = 
                      pageSize 
                      - LEAF_PAGE_OVERHEAD 
                      - 1 // prefixLen
                      - 1 // key flags
                      - Varint.SpaceNeededFor(int64 k.Length)
                      - k.Length 
                      - 1 // value flags
  
                  // availableOnNewPageAfterKey needs to accomodate the value and its length as a varint.
                  // it might already be <=0 because of the key length
  
                  let maxValueInline = 
                      if availableOnNewPageAfterKey > 0 then                    
                          let neededForVarintLen = Varint.SpaceNeededFor(int64 availableOnNewPageAfterKey)
                          let avail2 = availableOnNewPageAfterKey - neededForVarintLen
                          if avail2 > 0 then avail2 else 0
                      else 0
  
                  let blkAfterValue, vloc = 
                      if pair.Value = null then
                          blkAfterKey, Tombstone
                      else match kloc with
                           | Inline ->
                              if maxValueInline = 0 then
                                  let valuePage = blkAfterKey.firstPage
                                  let len,newBlk = writeOverflow blkAfterKey pair.Value
                                  newBlk, (Overflowed (len,valuePage))
                              else
                                  let vread = utils.ReadFully2(pair.Value, vbuf, 0, maxValueInline+1)
                                  if vread < maxValueInline then
                                      // TODO this alloc+copy is unfortunate
                                      let va:byte[] = Array.zeroCreate vread
                                      System.Array.Copy (vbuf, 0, va, 0, vread)
                                      blkAfterKey, Buffer va
                                  else
                                      let valuePage = blkAfterKey.firstPage
                                      let len,newBlk = writeOverflow blkAfterKey (new myConcatStream(vbuf, vread, pair.Value))
                                      newBlk, (Overflowed (len,valuePage))
                           | Overflow _ ->
                              let valuePage = blkAfterKey.firstPage
                              let len,newBlk = writeOverflow blkAfterKey pair.Value
                              newBlk, (Overflowed (len,valuePage))
  
  
                  let lp = {
                              key=k
                              kLoc=kloc
                              vLoc=vloc
                              }
  
                  // whether/not the key/value are to be overflowed is now already decided.
                  // now all we have to do is decide if this key/value are going into this leaf
                  // or not.  note that it is possible to overflow these and then have them not
                  // fit into the current leaf and end up landing in the next leaf.
  
                  let kLocNeed (k:byte[]) kloc prefixLen =
                      let klen = k.Length
                      match kloc with
                      | Inline ->
                          1 + Varint.SpaceNeededFor(int64 klen) + klen - prefixLen
                      | Overflow _ ->
                          1 + Varint.SpaceNeededFor(int64 klen) + neededForOverflowPageNumber
  
                  let vLocNeed vloc =
                      match vloc with
                      | Tombstone -> 
                          1 + Varint.SpaceNeededFor(0L)
                      | Buffer vbuf ->
                          let vlen = vbuf.Length
                          1 + Varint.SpaceNeededFor(int64 vlen) + vlen
                      | Overflowed (vlen,_) ->
                          1 + Varint.SpaceNeededFor(int64 vlen) + neededForOverflowPageNumber
  
                  let leafPairSize prefixLen lp =
                      kLocNeed lp.key lp.kLoc prefixLen
                      +
                      vLocNeed lp.vLoc
  
                  let defaultPrefixLen (k:byte[]) =
                      // TODO max prefix.  relative to page size?  must fit in byte.
                      if k.Length > 255 then 255 else k.Length
  
                  let maybeWriteLeaf st = 
                      // TODO ignore prefixLen for overflowed keys?
                      let newPrefixLen = 
                          if List.isEmpty st.keys then
                              defaultPrefixLen k
                          else
                              bcmp.PrefixMatch ((List.head st.keys).key) k st.prefixLen
                      let sofar = 
                          if newPrefixLen < st.prefixLen then
                              // the prefixLen would change with the addition of this key,
                              // so we need to recalc sofar
                              // TODO is it a problem that we're doing this without List.rev ?
                              List.sumBy (fun lp -> leafPairSize newPrefixLen lp) st.keys
                          else
                              st.sofarLeaf
                      let available = pageSize - (sofar + LEAF_PAGE_OVERHEAD + 1 + newPrefixLen)
                      let needed = kLocNeed k kloc newPrefixLen + vLocNeed vloc
                      let fit = (available >= needed)
                      let writeThisPage = (not (List.isEmpty st.keys)) && (not fit)
  
                      if writeThisPage then
                          writeLeaf st false
  