[Top][All Lists]
[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
[Monotone-devel] Re: nuskool & certs created after a revision, Lapo Luchini, 2008/05/02