NODE_DATA Design (Sheffield 2010-08-18)
=======================================

Essentially it replaces BASE_NODE and WORKING_NODE by combining all
the existing columns with a new op_depth column where op_depth == 0 is
the old BASE_NODE and op_depth != 0 is the old WORKING_NODE.

  Category     Columns

  indexing:    wc_id, local_relpath, parent_relpath, op_depth
  status:      presence
  node-rev:    repos_id, repos_relpath, revnum
  content:     kind, properties, depth, target, checksum
  last-change: changed_rev, changed_date, changed_author
  wc-cache:    translated_size, last_mod_time
  misc:        dav_cache, file_external

When op_depth == 0 the node-rev columns represent the checked-out
repository node, otherwise they represent the copyfrom node.

Presence has the same six values as BASE_NODE/WORKING_NODE: normal,
incomplete, absent, excluded, not-present, base-deleted.  There are
some presence/op_depth constraints, e.g. base-deleted is not valid for
op_depth 0 and absent is not valid for op_depth != 0.

The wc-cache values are only valid for the greatest op_depth for any
local_relpath.  This is acceptable partly because the overhead of
having them in a separate table (which would need to include wc_id and
local_relpath) offsets the redundancy of having them at all op_depth.

Basic Delete/Copy
-----------------

Key:
n normal
b base-deleted
p not-present
+ operation root (op_depth == number of components in local_relpath)
~ operation pseudo-root (revnum != revnum of parent)
* not expected on disk

Checkout/update:
             
Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1                n
 f2                n
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/            n
       f1          n
       h1          n


Delete f1, add f3, delete A2/B1:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1*               n      b+
 f2                n
 f3                       n+
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/*           n             b+
       f1*         n             b
       h1*         n             b

Copy A1 to A2/B1 (a replace):

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1*               n      b+
 f2                n
 f3                       n+
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/            n             n+
       f1          n             n
       h1*         n             b
       g1          n             n


Delete A2/B1/f1, add A2/B1/C1, A2/B1/C1/f1:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1*               n      b+
 f2                n
 f3                       n+
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/            n             n+
       f1*         n             n      b+
       h1*         n             b
       g1          n             n
       C1/                              n+
          f1                                 n+

Copy f2 to A2/B1/f1 (a replace):

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1*               n      b+
 f2                n
 f3                       n+
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/            n             n+
       f1          n             n      n+
       h1*         n             b
       g1          n             n
       C1/                              n+
          f1                                 n+


Copy A1 to A2/C1/D1:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 f1*               n      b+
 f2                n
 f3                       n+
 A1/               n
    f1             n
    g1             n
 A2/               n
    B1/            n             n+
       f1          n             n      n+
       h1*         n             b
       g1          n             n
       C1/                              n+
          f1                                   n+
          D1/                                  n+
             f1                                n
             g1                                n


Handling Mixed Revisions
========================

Checkout/update/edit/delete/commit:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n 3
 A1/               n 3
    f1             n 3
    f2*            n 3    b
    f3*            p
    B1/            n 5
       f1          n 5
       h1          n 7

Copy A1 to A2:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n 3
 A1/               n 3
    f1             n 3
    f2*            n 3    b
    f3*            p
    B1/            n 5
       f1          n 5
       h1          n 7
 A2/                      n+3
    f1                    n 3
    f2*                   p
    f3*                   p
    B1/                   n~5
       f1                 n 5
       h1                 n~7

Where revnum != revnum of parent the node is pseudo-root and must be
added during commit (the FS layer converts to a replace if required,
see issue 3314).

Delete Storage Optimisation
---------------------------

Rather than store deletes as a layer with a new op_depth we could
store them in the nearest existing layer, using a delete flag.  This
is because delete doesn't need to store anything other than the fact
of the delete.  This would make each op_depth layer correspond to an
add/copy onto a deleted node or as a new node.  This would remove the
base-deleted presence value.

Checkout/update/copy A1 to A3/A1:
             
Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 A1/               n
    B1/            n
       f1          n
 A2/               n
 A3/               n
    A1/                          n+
       B1/                       n
          f1                     n

Delete A2/B2/B1:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 A1/               n
    B1/            n
       f1          n
 A2/               n
 A3/               n
    A1/                          n+
       B1/*                      nd
          f1*                    nd

Copy A2 to A3/A1/A2:

Local_Relpath   NODE_DATA
                   0      1      2      3      4
------------------------------------------------
/                  n
 A1/               n
    B1/            n
       f1          n
 A2/               n
 A3/               n
    A1/                          n+
       B1/                       nd     n
          f1*                    nd