blob: e8f4180229578c1d353ba89461deb39f3eb66168 [file] [log] [blame]
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