You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Yoshiki Hayashi <yo...@xemacs.org> on 2001/02/26 10:12:46 UTC

How can svn_fs_abort_txn be implemented?

I was thinking about how svn_fs_abort_txn can be
implemented.

If I understand it correctly, svn_fs_abort_txn needs
svn_error_t *svn_fs__dag_destroy_tree (dag_node_t *root),
which walk thorough a tree and removes all mutable nodes
from nodes table by calling db->del().  In STACK,
svn_fs__dag_delete is mentioned.  But it's for svn rm (or
whatever it's called) operation and it doesn't remove node
from nodes table, right?

There's an argument for making the nodes immutable when
close_file is called.  You can't do it or you won't be able
to distinguish which nodes were created in that transaction.
Alternatively, you can mark a node immutable and put that
node into a table for later abort but I don't think it's
worth the trouble to have different table for this.

svn_fs_abort_txn will also need svn_fs__destroy_txn, which
will remove transaction entry from transactions table.

I thought about just implementing them but I might be
missing something obvious again.  Am I?

-- 
Yoshiki Hayashi

Re: How can svn_fs_abort_txn be implemented?

Posted by Jim Blandy <ji...@zwingli.cygnus.com>.
Yoshiki Hayashi <yo...@xemacs.org> writes:
> Jim Blandy <ji...@zwingli.cygnus.com> writes:
> 
> > > There's an argument for making the nodes immutable when
> > > close_file is called.  You can't do it or you won't be able
> > > to distinguish which nodes were created in that transaction.
> > 
> > Yes, you can.  Any mutable node reachable from a transaction root
> > belongs to that transaction only.  Mutable nodes are always private to
> > the transaction they were created in; they never appear in more than
> > one transaction's tree.  So you just start from the transaction's
> > root, and delete nodes until you hit mutable nodes.
>                                        ^^^^^^^ immutable?

Yes, sorry, I meant immutable.

> Say fs revision 10 has following structure (number below
> each path component represents node revision ID and M means
> the node is mutable):
> 
> /project/subversion/subversion/libsvn_fs/dag.c
>  (0.8)   (1.6)      (2.4)      (3.4)     (4.3)
>                                          dag.h
>                                          (5.3)
> 
> Then, dag.c is changed in working copy and all the necessary
> changes are done except svn_fs_commit_txn() or
> svn_fs_abort_txn().
> 
> /project/subversion/subversion/libsvn_fs/dag.c
>  (0.9)   (1.7)      (2.5)      (3.5)     (4.4)
>    M       M          M          M         M
>                                          dag.h
>                                          (5.3)
> 
> Suppose svn_fs_abort_txn() is called here.  You need to
> remove revision node ID 0.9, 1.7, 2.5, 3.5, 4.4 from nodes
> table or you'll end up having many stray nodes in the table.
> Luckily, all these freshly created revisions are mutable and
> can be easily distinguished from other already existent node
> like dag.h.  So what svn_fs_abort_txn() will do is to remove
> all mutable nodes reachable from root node of given
> transaction.

Right.

> If you made any node immutable, you'll lose information
> about which node is new.  If dag.c is marked immutable when
> close_file is called, tree will look like:
> 
> /project/subversion/subversion/libsvn_fs/dag.c
>  (0.9)   (1.7)      (2.5)      (3.5)     (4.4)
>    M       M          M          M
>                                          dag.h
>                                          (5.3)
> 
> Here, you can't tell dag.c or dag.h is created in this
> transaction unless you record every new node revision IDs in
> another table.  If svn_fs_abort_txn() is called, dag.c(4.4)
> and dag.h(5.3) remain in nodes table, dag.c(4.4) being
> referenced from nowhere.  Therefore, you can't make any
> mutable nodes immutable before svn_commit_txn() takes place.
> 
> Is this view correct?

That's correct.  All nodes changed so far in a given transaction are
mutable.  Nodes only become immutable when they are committed, and
become part of a revision.

Re: How can svn_fs_abort_txn be implemented?

Posted by Yoshiki Hayashi <yo...@xemacs.org>.
Jim Blandy <ji...@zwingli.cygnus.com> writes:

> > There's an argument for making the nodes immutable when
> > close_file is called.  You can't do it or you won't be able
> > to distinguish which nodes were created in that transaction.
> 
> Yes, you can.  Any mutable node reachable from a transaction root
> belongs to that transaction only.  Mutable nodes are always private to
> the transaction they were created in; they never appear in more than
> one transaction's tree.  So you just start from the transaction's
> root, and delete nodes until you hit mutable nodes.
                                       ^^^^^^^ immutable?

Sorry, I don't understand the first sentence.  I also don't
understand last sentence as it is, so it might be better to
state how I think it works.

Say fs revision 10 has following structure (number below
each path component represents node revision ID and M means
the node is mutable):

/project/subversion/subversion/libsvn_fs/dag.c
 (0.8)   (1.6)      (2.4)      (3.4)     (4.3)
                                         dag.h
                                         (5.3)

Then, dag.c is changed in working copy and all the necessary
changes are done except svn_fs_commit_txn() or
svn_fs_abort_txn().

/project/subversion/subversion/libsvn_fs/dag.c
 (0.9)   (1.7)      (2.5)      (3.5)     (4.4)
   M       M          M          M         M
                                         dag.h
                                         (5.3)

Suppose svn_fs_abort_txn() is called here.  You need to
remove revision node ID 0.9, 1.7, 2.5, 3.5, 4.4 from nodes
table or you'll end up having many stray nodes in the table.
Luckily, all these freshly created revisions are mutable and
can be easily distinguished from other already existent node
like dag.h.  So what svn_fs_abort_txn() will do is to remove
all mutable nodes reachable from root node of given
transaction.

If you made any node immutable, you'll lose information
about which node is new.  If dag.c is marked immutable when
close_file is called, tree will look like:

/project/subversion/subversion/libsvn_fs/dag.c
 (0.9)   (1.7)      (2.5)      (3.5)     (4.4)
   M       M          M          M
                                         dag.h
                                         (5.3)

Here, you can't tell dag.c or dag.h is created in this
transaction unless you record every new node revision IDs in
another table.  If svn_fs_abort_txn() is called, dag.c(4.4)
and dag.h(5.3) remain in nodes table, dag.c(4.4) being
referenced from nowhere.  Therefore, you can't make any
mutable nodes immutable before svn_commit_txn() takes place.

Is this view correct?

-- 
Yoshiki Hayashi

Re: How can svn_fs_abort_txn be implemented?

Posted by Jim Blandy <ji...@zwingli.cygnus.com>.
Yoshiki Hayashi <yo...@xemacs.org> writes:
> If I understand it correctly, svn_fs_abort_txn needs
> svn_error_t *svn_fs__dag_destroy_tree (dag_node_t *root),
> which walk thorough a tree and removes all mutable nodes
> from nodes table by calling db->del().  In STACK,
> svn_fs__dag_delete is mentioned.  But it's for svn rm (or
> whatever it's called) operation and it doesn't remove node
> from nodes table, right?

If the node being deleted is mutable, svn_fs__dag_delete must remove
it from the nodes table.  We're currently missing functions in
node-rev.c and nodes-table.h to support this; they'll need to be
added.

Since the documentation for svn_fs__dag_delete says that "if the node
being deleted is a mutable directory, it must be empty," we don't need
to do any recursive tree walking here.

If we do need a recursive deletion function, it must *not* be in
dag.c.  The whole point of dag.c is to be as simple as possible while
still having enough information to guarantee the consistency of the
filesystem.  So anything which can be written as a client of dag.c's
interface should be.  If this causes major performance losses, then we
need to think things over.

> There's an argument for making the nodes immutable when
> close_file is called.  You can't do it or you won't be able
> to distinguish which nodes were created in that transaction.

Yes, you can.  Any mutable node reachable from a transaction root
belongs to that transaction only.  Mutable nodes are always private to
the transaction they were created in; they never appear in more than
one transaction's tree.  So you just start from the transaction's
root, and delete nodes until you hit mutable nodes.

> svn_fs_abort_txn will also need svn_fs__destroy_txn, which
> will remove transaction entry from transactions table.

That's right.  We'll need to add a function to txn-table.[ch].