-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This started out as a fix for corruption corner cases, grew into simplifying how we build the remote tree, and turned into a rewrite (again >.>). Instead of managing two different sets of structure at insert and merge time, we now store items and parent-child relationships in a tree builder, then build a consistent tree that flags divergent items. The old tree was complicated because it had to maintain a valid structure before and after every insert, but with references to potentially unknown parents and children. Since we couldn't insert an item without knowing its parent, we had to pick a canonical structure (parents by `children`), insert children in level order, and note divergent structure (by `parentid`) separately. This meant Desktop's `Store::fetch_remote_tree()` had to left-join `mirror.items` to `mirror.structure`, store the items in a pseudo-tree, then recursively walk children to inflate the complete tree. This was complicated enough with a valid tree, let alone orphans and multiple parents. With the new approach, we build the tree in three steps: 1. First, we add all items, without structure. 2. Next, we set parent-child relationships. Parents by `children` require the parent to exist, but not the child; this handles the case where a folder mentions nonexistent or deleted GUIDs in its `children`. Parents by `parentid` require the item to exist, but not its parent; this handles orphans that reference missing or non-folder parents. 3. Finally, once we've added all entries to the tree, we have a complete view of the structure, so we can resolve missing, multiple, and conflicting parents. For cases where we know the structure is valid and in level order, like Desktop's `Store::fetch_local_tree()`, we handle steps 1 and 2 at the same time: `builder.item(item)?.by_structure(&parent_guid)?`. For the remote tree, we insert all items and their `parentid`s first (`builder.item(item)?.by_parent_guid(&parent_guid)?`, where `parent_guid` might not be in the tree), then add structure from children later: `builder.parent_for(&child_guid)?.by_children(&parent_guid)?`, where `child_guid` might not be in the tree. Closes #22.
- Loading branch information
1 parent
8dc54ef
commit c7bad2e
Showing
4 changed files
with
669 additions
and
678 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.