mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-15 01:52:42 +03:00
updated clay doc and code
This commit is contained in:
parent
c33eab7645
commit
fabf390eac
@ -72,7 +72,7 @@
|
||||
== ::
|
||||
++ room :: fs per ship
|
||||
$: hun=duct :: terminal duct
|
||||
hez=(unit duct) :: sync duch
|
||||
hez=(unit duct) :: sync duct
|
||||
dos=(map desk dojo) :: native desk
|
||||
== ::
|
||||
++ rove (each mood moot) :: stored request
|
||||
|
@ -1798,17 +1798,13 @@
|
||||
++ equiv :: test paths
|
||||
|= [p=(map path lobe) q=(map path lobe)]
|
||||
^- ?
|
||||
%- |= qat=?
|
||||
?. qat %.n
|
||||
%+ roll (~(tap by q) ~)
|
||||
|= [[pat=path lob=lobe] eq=?]
|
||||
^- ?
|
||||
?. eq %.n
|
||||
=- ?. qat %.n
|
||||
%+ levy (~(tap by q) ~)
|
||||
|= [pat=path lob=lobe]
|
||||
(~(has by p) pat)
|
||||
%+ roll (~(tap by p) ~)
|
||||
|= [[pat=path lob=lobe] eq=?]
|
||||
^- ?
|
||||
?. eq %.n
|
||||
^= qat
|
||||
%+ levy (~(tap by p) ~)
|
||||
|= [pat=path lob=lobe]
|
||||
=+ zat=(~(get by q) pat)
|
||||
?~ zat %.n
|
||||
=((lobe-to-noun u.zat) (lobe-to-noun lob))
|
||||
@ -1817,13 +1813,11 @@
|
||||
|= [wen=@da lem=nori] :: edit
|
||||
^+ +>
|
||||
?- -.lem
|
||||
& =+ ^= yet
|
||||
& =^ yak lat :: merge objects
|
||||
%+ forge-yaki wen
|
||||
?: =(let 0) :: initial import
|
||||
[~ q.lem]
|
||||
[(some r:(aeon-to-yaki let)) q.lem]
|
||||
=+ yak=-.yet
|
||||
=. lat +.yet :: merge objects
|
||||
?. ?| =(0 let)
|
||||
!=((lent p.yak) 1)
|
||||
!(equiv q.yak q:(aeon-to-yaki let))
|
||||
|
@ -2136,4 +2136,173 @@ It remains to discuss `++edit:de`.
|
||||
+>.$(dom d, ran r)
|
||||
```
|
||||
|
||||
We very simply call `++edit:ze` and apply the resultant dome and rang back into
|
||||
ourself. As we should expect, the actual handling of the changes themselves
|
||||
is delegated to `++ze` in `arvo/zuse.hoon`.
|
||||
|
||||
```
|
||||
++ edit :: edit:ze
|
||||
|= [wen=@da lem=nori] :: edit
|
||||
^+ +>
|
||||
?- -.lem
|
||||
& =^ yak lat :: merge objects
|
||||
%+ forge-yaki wen
|
||||
?: =(let 0) :: initial import
|
||||
[~ q.lem]
|
||||
[(some r:(aeon-to-yaki let)) q.lem]
|
||||
?. ?| =(0 let)
|
||||
!=((lent p.yak) 1)
|
||||
!(equiv q.yak q:(aeon-to-yaki let))
|
||||
==
|
||||
+>.$ :: silently ignore
|
||||
=: let +(let)
|
||||
hit (~(put by hit) +(let) r.yak)
|
||||
hut (~(put by hut) r.yak yak)
|
||||
==
|
||||
+>.$(ank (checkout-ankh q.yak))
|
||||
| +>.$(lab ?<((~(has by lab) p.lem) (~(put by lab) p.lem let)))
|
||||
==
|
||||
```
|
||||
|
||||
Two kinds of changes may be made to a filesystem: we can modify the contents
|
||||
or we can label a revision.
|
||||
|
||||
Labeling a revision (the `|` case) is much simpler. We first assert that the
|
||||
label doesn't already exist. Then, we put in `lab` in our dome the label
|
||||
associated with the current revision number.
|
||||
|
||||
In the `&` case, we're actually modifying the contents of the filesystem.
|
||||
First, we create the commit in `++forge-yaki` by applying the given changes to
|
||||
our current revision. This also updates `lat` in our rang with the new data
|
||||
objects.
|
||||
|
||||
Unless either this is the initial import, the generated yaki doesn't have
|
||||
exactly one parent, or the data in the generated yaki is the same as that in
|
||||
our current revision, we silently ignore the request. Note that this only
|
||||
allows changes that don't affect the contents of the filesystem if this is a
|
||||
merge.
|
||||
|
||||
If one of the conditions does hold, then we apply the generated commit. We
|
||||
increment `let`, the revision number of our head; associate the new revision
|
||||
number with the hash of the new commit; and put the new commit in `hut`.
|
||||
Finally, we update our current ankh by checking out the new commit.
|
||||
|
||||
We discussed `++checkout-ankh` above, so it remains only to discuss
|
||||
`++forge-yaki` and `++equiv`. We begin with the simpler, `++equiv:ze`.
|
||||
|
||||
```
|
||||
++ equiv :: test paths
|
||||
|= [p=(map path lobe) q=(map path lobe)]
|
||||
^- ?
|
||||
=- ?. qat %.n
|
||||
%+ levy (~(tap by q) ~)
|
||||
|= [pat=path lob=lobe]
|
||||
(~(has by p) pat)
|
||||
^= qat
|
||||
%+ levy (~(tap by p) ~)
|
||||
|= [pat=path lob=lobe]
|
||||
=+ zat=(~(get by q) pat)
|
||||
?~ zat %.n
|
||||
=((lobe-to-noun u.zat) (lobe-to-noun lob))
|
||||
```
|
||||
|
||||
We're checking to see if the data in both filesystem trees is identical. We
|
||||
start by going through `p` and checking to see if (1) the path exists in `q`
|
||||
and (2) the data is the same as in `q`.
|
||||
|
||||
This shows that `q` is a superset of `p`. To show that `p` and `q` are
|
||||
equivalent, we have to make sure there is nothing in `q` that is not also in
|
||||
`p`. Once we've done that, we know `p` and `q` are equivalent.
|
||||
|
||||
```
|
||||
++ forge-yaki :: forge-yaki:ze
|
||||
|= [wen=@da par=(unit tako) lem=soba] :: forge yaki
|
||||
=+ ^= per
|
||||
?~ par ~
|
||||
~[u.par]
|
||||
=+ gar=(update-lat (apply-changes q.lem) lat)
|
||||
:- %^ make-yaki per +.gar wen :: from existing diff
|
||||
-.gar :: fix lat
|
||||
```
|
||||
|
||||
Here, we first make `per`, our list of parents. If we have a parent, we put it
|
||||
in the list, else the list is empty. Simple.
|
||||
|
||||
We then apply the changes and update `lat`, our object store. Finally, we make
|
||||
a yaki out of the generated change information and produce both it and the new
|
||||
object store.
|
||||
|
||||
Lifecycle of a Local Merge
|
||||
--------------------------
|
||||
|
||||
Merges are pretty simple from the perspective of clay. A `%merg` kiss is sent
|
||||
with already-generated merge state, and we simply apply the new state. The
|
||||
question of how the merge is generated is much more complicated, but it is also
|
||||
out of the scope of this section.
|
||||
|
||||
We've seen most of the arms involved, so we'll go through most of it pretty
|
||||
quickly. In `++call` we handle the `%merg` kiss.
|
||||
|
||||
```
|
||||
%merg :: direct state up
|
||||
=^ mos ruf
|
||||
=+ une=(un p.q.hic now ruf)
|
||||
=+ ^= zat
|
||||
(exem:(di:wake:une q.q.hic) hen now r.q.hic)
|
||||
=+ zot=abet.zat
|
||||
:- -.zot
|
||||
=. une (pish:une q.q.hic +.zot ran.zat)
|
||||
abet:une(hez.yar ?.(=(%into -.q.hic) hez.yar.une [~ hen]))
|
||||
[mos ..^$]
|
||||
```
|
||||
|
||||
As we've seen several times before, we set up a core for the local ship with
|
||||
`++un`. We set up a core for the local desk with `++di` and updating our
|
||||
subscribers with `++wake`. We call `++exem` to execute the merge. `++abet:de`,
|
||||
`++pish:un` and `++abet:un` resolve all our changes.
|
||||
|
||||
The only new arm here is `++exem:de`.
|
||||
|
||||
```
|
||||
++ exem :: execute merge
|
||||
|= [hen=duct wen=@da mer=mizu] :: aka direct change
|
||||
?. (gte p.mer let.dom) !! :: no
|
||||
=. +>.$ %= +>.$
|
||||
hut.ran (~(uni by hut.r.mer) hut.ran)
|
||||
lat.ran (~(uni by lat.r.mer) lat.ran)
|
||||
let.dom p.mer
|
||||
hit.dom (~(uni by q.mer) hit.dom)
|
||||
==
|
||||
=+ ^= hed :: head commit
|
||||
=< q
|
||||
%- ~(got by hut.ran)
|
||||
%- ~(got by hit.dom)
|
||||
let.dom
|
||||
=. ank.dom :: real checkout
|
||||
(~(checkout-ankh ze lim dom ran) hed)
|
||||
(echa:wake hen wen mer) :: notify or w/e
|
||||
```
|
||||
|
||||
We first do a quick sanity check that the head of the merge data is greater
|
||||
than the head of the old data. Merges must add at least one revision.
|
||||
|
||||
We merge the new data in the obvious way. We do map merges for `hut` and `lat`
|
||||
in rang to get all the new data and commits, we do a map merge in`hit` in our
|
||||
dome to get all the new revision numbers, and we update our head to the most
|
||||
recent revision.
|
||||
|
||||
Then, we checkout the commit at our head and announce the results to unix.
|
||||
`++echa` is the only new arm here.
|
||||
|
||||
```
|
||||
++ echa :: announce raw
|
||||
|= [hen=duct wen=@da mer=mizu]
|
||||
^+ +>
|
||||
%= +>
|
||||
vag ?~(hez vag :_(vag [u.hez [%ergo who syd let.dom]]))
|
||||
==
|
||||
```
|
||||
|
||||
If we have a sync duct, we tell unix that a new revision is available.
|
||||
|
||||
This concludes our discussion of a local merge.
|
||||
|
Loading…
Reference in New Issue
Block a user