[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn_delta_path_driver(), its purpose and future

From: Hyrum K Wright <hyrum.wright_at_wandisco.com>
Date: Tue, 29 Nov 2011 15:56:32 -0600

On Tue, Nov 29, 2011 at 3:02 PM, C. Michael Pilato <cmpilato_at_collab.net> wrote:
> On 11/29/2011 02:33 PM, Hyrum K Wright wrote:
>> Ev2 doesn't bother with a depth-first tree traversal, the sender just
>> invokes paths in whatever order it sees fit.  There are a few obvious
>> restrictions, such as directories need to exist before their children
>> can be processed, for example, but it's much looser than the delta
>> editor.  Also, the APIs are a bit more streamlined, in that it's not
>> legal to set the properties on a node multiple times in the same
>> drive, for instance.
>>
>> To handle the conversion from the delta editor to Ev2, we create an
>> editor which receives all the calls from the sender, queues them up,
>> and then drives an Ev2 editor in the receiver.  Likewise, a similar
>> shim exists which receives Ev2 calls, queues them up and then drives a
>> delta editor in the proper order.  It's all terribly inefficient due
>> to the fact that the entire drive is stored in memory prior to being
>> translated and replayed to the target editor (whether Ev2 or the delta
>> editor), but it's also meant as a temporary measure.
>>
>> However, svn_delta_path_driver() looks like it interacts with the
>> editor while the thing is being driven.  It counts on all the prior
>> calls actually reaching the target editor before the callback is
>> invoked, which means it will have an adverse reaction to something
>> which queues up the calls and then replays them, since none of the
>> preceding calls will have succeeded by the time its callback is
>> invoked.
>
> Of course svn_delta_path_driver() interacts with the editor while it's being
> driven -- it's helping to drive it!
>
> Look, what this interface does is pretty straightforward.  It examines a
> list of interesting paths provided it.  Interesting paths are paths which
> are added, deleted, or modified.  It sorts them into depth-first order, and
> drives the provided editor in such a way that all those paths are reached as
> part of the editor drive.  As each one is reached, it calls its callback
> function to say, "Hey, we're at the point of the editor drive where you can
> do whatever it is to path FOO that you needed done, so do it and then return
> when you're finished."  And then it continues along, opening and closing
> directories until it reaches the next interesting path, continuing until
> every interesting path has been reached as part of the drive and all
> intermediate directories have been closed.
>
> For example, say I have a list of paths and the actions I want to do to them:
>
>   'trunk/mu':  delete it
>   'trunk/A/D/G/florp':  add it as a directory
>   'trunk/A/B/E/alpha':  set the property 'foo' to 'bar' on it
>
> I can tell that the longest common ancestor of these paths is 'trunk', so I
> anchor the editor which is supposed to absorb these changes (maybe its an RA
> commit editor) there, convert my list of paths to be relative to that
> location, then pass the list and the editor to svn_delta_path_driver().
>
> svn_delta_path_driver (SDPD) sorts my relative paths by depth:
>
>   'mu'
>   'A/B/E/alpha'
>   'A/D/G/florp'
>
> and then starts driving the editor to handle intermediate directories
> between and around my interesting paths.  In my scenario, it doesn't get far
> before it reaches one of my interesting paths:
>
>   SDPD: db1 = open_root('')
>
> Now, it's at the point where it can act on 'mu', but it doesn't know what
> needs to happen to 'mu'.  So it calls the path driver callback (PDCB) I
> provided to allow that sucker to do the real work on 'mu', providing 'mu's
> parent directory baton to the callback.  My callback function knows that I
> wanted to delete 'mu' (I had that information stuffed into its baton), so it
> does so by calling the delete_entry() function on the same editor that
> svn_path_delta_driver() is using.
>
>   PDCB: delete_entry(db1, 'mu')
>
> Then it returns.
>
> SDPD continues, driving the editor to the next interesting path
> ('A/B/E/alpha'), which requires a few more open-dir's:
>
>   SDPD:  db2 = open_directory(db1, 'A')
>   SDPD:  db3 = open_directory(db2, 'A/B')
>   SDPD:  db4 = open_directory(db3, 'A/B/E')
>
> Having arrived at the next interesting path, it calls my callback to do the
> interesting work, and the callback fills in some more of the missing editor
> calls:
>
>   PDCB:  fb = open_file(db4, 'A/B/E/alpha')
>   PDCB:  change_file_prop(fb, 'foo', 'bar')
>   PDCB:  close_file(fb)
>
> Back in SDPD again, we drive to the next destination, which requires moving
> up a directory and back down again into another subtree:
>
>   SDPD:  close_directory(db4)
>   SDPD:  db4 = open_directory(db3, 'A/D/G')
>
> Then it calls the callback again for 'A/D/G/florp', which does:
>
>   PDCB:  db5 = add_directory(db4, 'A/D/G/florp')
>
> This time the callback does something a little different, though -- because
> it opened or added a directory, it returns the dir baton for that directory
> so that SDPD can use it to address immediate children (if any) of this
> directory.  In my example, there are none, so when program control returns
> to SDPD, it just closes my new directory as part of its wrap-up of open
> directories back to the root.
>
>   SDPD:  close_directory(db5)
>   SDPD:  close_directory(db4)
>   SDPD:  close_directory(db3)
>   SDPD:  close_directory(db2)
>   SDPD:  close_directory(db1)
>
> And the edit drive is complete save for the close_edit() called from outside
> the svn_delta_path_driver() call tree.

Thank you very much for this example, it was quite illuminating.

It sounds very much like SDPD is simply a mechanism for doing with Ev1
what Ev2 is explicitly designed for: operating on arbitrary paths in
the delta tree. All SDPD does is fill in the gaps so that the sender
doesn't have to worry about all the intermediate calls between the
paths of interest, right?

>> Now, after having written all then, I wonder if there would be a way
>> to set up a system whereby the delta_path_driver callback was invoked
>> during the replay of the queued items, rather than the initial calls
>> to them.  It would involve a bit more shim code, but this may be the
>> better solution.  Hmmm.....
>
> Any consumer of the svn_delta_path_driver() will need to be using Ev1 --
> that's what's supported by the API.  If their particular editor is a shim to
> an Ev2 under the hood, that's fine -- the caller need never be aware of that
> any more than they would be if they were manually driving the editor.  And
> it sounds as if we don't need to rev svn_delta_path_driver() for an Ev2
> flavor because Ev2 solves the primary problem that SDPD exists to solve:
> the depth-first requirement of editor drives.

I understand and expect that consumers of SDPD as currently
implemented will need to use Ev1. The problem is that they don't take
very kindly to instances where Ev1 is driven in an asynchronous mode,
which doesn't technically violate the Ev1 API. But I think this is a
problem that we can work around.

Thanks for the help!

-Hyrum

-- 
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com/
Received on 2011-11-29 22:57:06 CET

This is an archived mail posted to the Subversion Dev mailing list.