On Fri, Jul 28, 2023 at 7:18 AM Edward K. Ream <[email protected]> wrote:

> This Engineering Notebook post announces several momentous Ahas all
directly related to VNodes.
...

> Define *p.archive* (yes, p) something like this (untested, but the code
passes mypy):

def archive(self) -> dict[str, Any]:
    """Return a json-like archival dictionary for p/v.unarchive."""
    p = self

    # Create a list of all vnodes in p.self_and_subtree.
    all_unique_vnodes: list[VNode] = []
    for p in p.self_and_subtree():
        if p.v not in all_unique_vnodes:
            all_unique_vnodes.append(p.b)  <--- Oops, I meant p.v

The code above contains a subtle bug. The all_unique_vnode list is
incomplete. It should also contain (at minimum) all vnodes in all v.parents
and v.children arrays.

Instead, p.archive should be something like this (untested, but passes
mypy):

def archive(self) -> dict[str, Any]:
    """Return a json-like archival dictionary for p/v.unarchive."""
    p = self
    c = p.v.context

    # Create an *initial* list of all vnodes in p.self_and_subtree.
    all_unique_vnodes: list[VNode] = []
    for p in p.self_and_subtree():
        if p.v not in all_unique_vnodes:
            all_unique_vnodes.append(p.v)

    def ref(v: VNode) -> Optional[str]:
        if v == c.hiddenRootNode:
            return None
        if v.gnx not in all_unique_vnodes:
            all_unique_vnodes.append(v.gnx)
        return v.gnx

    parents_dict: dict[str, list[str]] = {}
    for p2 in p.self_and_subtree():
        v = p2.v
        parents_list = [ref(z) for z in v.parents]
        parents_dict[v.gnx] = [z for z in parents_list if z]

    children_dict: dict[str, list[str]] = {}
    for p2 in p.self_and_subtree():
        v = p2.v
        childrens_list = [ref(z.gnx) for z in v.children]
        children_dict[v.gnx] = [z for z in childrens_list if z]

    marks_dict: dict[str, str] = {}
    for v in all_unique_vnodes:
        marks_dict[v.gnx] = str(int(v.isMarked()))

    uas_dict: dict[str, dict] = {}
    for v in all_unique_vnodes:
        uas_dict[v.gnx] = v.archive_ua()  # To do.

    return {
        'vnodes': all_unique_vnodes,
        'parents': parents_dict,
        'children': children_dict,
        'marks': marks_dict,
        'uAs': uas_dict,
    }

I *think* this strategy is enough.  However,* this code does not
necessarily archive all the vnodes contained in the parents and child
arrays!* To do that we would need to compute the transitive closure of
all_unique_vnodes. In general, that would be all the vnodes in the outline!

Notice that the new code computes the parents and children dicts by
iterating on:

    for p2 in p.self_and_subtree():

rather than:

    for v in all_unique_vnodes:

The latter would start to compute a transitive closure!

*Summary*

We probably don't need the transitive closure of all vnodes when doing a
paste-retaining-clones when the source and target outlines are the same.
I'm not sure about cross-outline paste-retaining-clones.

In short, all aspects of archiving nodes are tricky :-)

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/CAMF8tS3R-9UgtAM881u18sGjE3RF8HR-x8EPO4vjfH0yq2S0gQ%40mail.gmail.com.

Reply via email to