After working through the several email messages, and discussion, I
believe we're now down to a simple change:
* add a "prior_deleted" flag to NODES
The flag simply means that a node exists prior to this layer and has
been deleted or moved-away. The 'presence' column may say the same
thing, but it might also describe data that is replacing the
When a deletion (of a subtree) occurs, then we create a new layer at
<relpath, op_depth>. New rows are written for the root, and all
children, using that op_depth value. If this is a moved-away, then we
store the destination into moved_to at the root *only* (which can then
later discriminate between the two types of deletions; children need
to look to the root to discriminate; I bet this need is rare). Note
that the deletion process needs to look for mods to descendents:
deletes are integrated into this one; other operations may error with
"can't delete local mods" or somesuch.
For the following actions, these are applied to the root of a deletion:
If an add occurs, then the root is updated to set presence='added'. No
other changes are needed.
If a copied-here or moved-here occurs, then the root is updated with
the appropriate status and source information. Child nodes *may* have
their presence switched from 'deleted' to 'copied-here' or
'moved-here' (depends on whether the arriving nodes intersect with the
old namespace). New nodes may be introduced, with presence=$whatever
and prior_deleted=0 (FALSE)
If a deletion of a child (subtree) of copied-here or moved-here
occurs, then it has a new op_depth and defines a whole new layer. The
"prior_deleted" is set to 1 (TRUE) indicating the prior layer (which
happens to be the copy/move-here) has been deleted.
Deletion of an add is effectively a revert. If this is a child, then
the layer is simply removed (it only has one node). If the
deletion/revert of an add has prior_deleted=1 (meaning it is a root),
then the node is rewritten to presence='deleted', restoring it to the
state when the deletion first occurred. (and yes, a second revert
undoes the deletion, etc...).
Reverting a child of a moved/copied-here tree is invalid. When you
revert the root, then the children at this op_depth are traversed: any
nodes with prior_deleted=1 are restored to presence=deleted, and nodes
with prior_deleted=0 (newly-arrived from the copy/move) are simply
Note that prior_deleted is set to TRUE only for a deletion operation
(when presence is set to 'deleted'). That implies a prior node
existed. For the sequence [rm A/B, add A/B, add A/B/foo], the node
A/B/foo will have op_depth=3 and prior_deleted=0 since the row was
created by an add. Assuming that A/B/foo existed originally, then
prior_deleted=1 at <A/B/foo, op_depth=2>.
I think that is it. Summarized a bit better from the earlier thread.
Received on 2010-09-20 22:41:15 CEST