monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] Re: nuskool & certs created after a revision


From: Graydon Hoare
Subject: [Monotone-devel] Re: nuskool & certs created after a revision
Date: Fri, 02 May 2008 09:32:08 -0700
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Lapo Luchini wrote:

Reading William's and Graydon's answers, I'm not sure I perfectly understood their proposal and why it doesn't have the same problem as mine. Graydon, what's the relation between your synthetic tree file and branches?

I'm assuming you're asking what the formal connection is between a branch B and its the synthetic lineage of cert-file-states (let's call this a "cert lineage") on revisions found in B. It's a good question and I fumbled over it for a while but found a pleasing answer that doesn't involve any external metadata. The magic of content-addressing saves us once more.

If I have a branch B, the task of associating a cert lineage with the revisions in B reduces to the task of associating the *name* "B" with a particular founder or "root" revision ID, which I'll call R. That is, we want to provide a mapping:

  B="net.venge.monotone" -->   R=<some-cert-lineage-revid>

Once we do this, we can take all the revision-graph descendants of R as the input set to gsync and calculate their heads, merge them, record any new certs found in the merger and whatnot. We just need that one mapping. If we're syncing a branch pattern that covers multiple B values, we can just union the DAGs associated with all the associated R values, at least for the sync operation -- for the subsequent auto-merging we have to auto-merge each cert lineage independently, to keep them disjoint. In the worst case, if branches B1 and B2 overlap and contain the same revs in various places, the certs of that rev will wind up replicated in disjoint cert lineages R1 and R2. No big deal: it's just set-member redundancy.

Anyway, I initially thought to use a policy branch, but that's extra machinery and it's increasingly clear nobody is going to get around to writing that. Fair. So then I thought to use DB vars, but that's fragile and stateful, can get set wrong. Then I stumbled on a solution that is so tidy it feels naturally correct: uniquely determine R *from the string name* of B.

How? Well, rather than "fake" a revision ID, you just cook up a full (but harmless) uniquely-determined root revision, and hash it. In particular:

   Construct a revision in memory with the empty revision as ancestor,
   with no files in it aside from the root file node "/", and with only
   one synthetic event in it: set_attr "/" "mtn:cert-lineage" = "B"

If you hash this revision, you'll get a unique R value -- disjoint from all other cert-revisions root values due to the presence of the harmless set-attribute event in it -- that you can use to root your cert lineage associated with B, from which, as I say, you can take "all the descendants of R" as your full subgraph to sync. You can then feed that subgraph to gsync and away you go.

The advantage of this approach is that it works with almost entirely existing machinery, no new theory and no new data structures. All you do is reserve 1 new cert name ("mtn:cert-lineage") and encode this procedure for synthesizing a root revid R and finding all its descendants. No change to the cert format, no change to the branch structure, no policy branches, nothing. Won't even require a db_migrate in order to start working.

-Graydon





reply via email to

[Prev in Thread] Current Thread [Next in Thread]