Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fractional index to order the children of the tree #298

Merged
merged 65 commits into from
May 7, 2024

Conversation

Leeeon233
Copy link
Member

@Leeeon233 Leeeon233 commented Mar 27, 2024

This PR introduces the integration of the Fractional Index feature, which allows children nodes in a Tree structure to maintain order. This is particularly useful in scenarios such as ordered nested lists and ordered outline notes.

Fractional Index

We have forked the Fractional Index implementation from drifting-in-space/fractional_index and made simple extensions to fit Loro's usage requirements.

  • Generate new Fractional Indexes evenly between left and right positions
  • Optionally add random jitter to each generation of the Fractional Index. It can be used to avoid creating the element with the same fractional index.

Ordered Tree Node Children

With each node's creation and movement, we update a Fractional Index to represent its position. In the Tree Container, concurrent insertions or movements of new nodes at the same position will result in nodes with identical Fractional Indexes. However, we can use mechanisms like Lamport clocks as a tiebreaker. The challenge of creating or inserting nodes among those with the same Fractional Index remains.

To address this, we backtrack to the first unique Fractional Index to serve as the new right node. We then evenly distribute n new Fractional Index, assigning them to both the nodes with identical FIs and the newly created nodes.

API

import { Loro } from "loro-crdt";
let doc = new Loro();
doc.setFractionalIndexJitter(7);
let tree = doc.getTree("tree");
let root = tree.createNode();
let node = root.createNode(); // By default, append to the end of the parent node's children list
let node2 = root.createNode(0);  // Specify the child's position
node2.move(node); 
node.move(node2, 0); // Specify the child's position
node.move(); // Move to become the root node
node.moveAfter(node2);  // Move after the node
node.moveBefore(node2);  // Move before the node
node.index() // Index 0

Benchmark

group main rate pr
1000 node checkout 10^3 88.0±1.52ms 3.00 263.8±3.47ms
300 deep node random checkout 10^3 751.0±4.02ms 1.85 1391.8±9.23ms
create node append/1000 199.2±0.57µs 4.62 920.9±25.80µs
create node append/10000 2.9±0.02ms 4.11 12.1±0.44ms
create node append/100000 36.3±0.19ms 7.24 262.4±3.10ms
create node append/1000000 547.3±6.89ms 21.78 11.9±0.03s
create node front/1000 200.4±1.29µs 3.89 780.5±5.02µs
create node front/10000 3.0±0.06ms 3.57 10.6±0.09ms
create node front/100000 36.8±0.68ms 6.63 244.1±2.30ms
create node front/1000000 562.9±24.39ms 18.64 10.5±0.09s
move node append/1000 870.8±47.06µs 3.03 2.6±0.53ms
move node append/10000 8.7±0.55ms 2.87 25.0±4.54ms
move node append/100000 85.9±4.05ms 3.00 257.7±14.12ms
move node append/1000000 915.3±3.72ms 9.64 8.8±0.04s
move node front/1000 876.3±50.56µs 2.95 2.6±0.52ms
move node front/10000 8.7±0.50ms 2.85 24.7±4.73ms
move node front/100000 86.9±4.55ms 2.74 237.8±3.07ms
move node front/1000000 919.5±9.55ms 9.57 8.8±0.03s
realtime tree move 625.8±141.63ms 1.00 628.2±178.52ms

@Leeeon233 Leeeon233 self-assigned this Mar 27, 2024
@Leeeon233 Leeeon233 marked this pull request as ready for review April 17, 2024 13:14
@Leeeon233 Leeeon233 requested a review from zxch3n April 29, 2024 12:32
crates/fractional_index/src/lib.rs Outdated Show resolved Hide resolved
crates/loro-internal/src/diff_calc/tree.rs Show resolved Hide resolved
crates/loro-internal/src/state/tree_state.rs Outdated Show resolved Hide resolved
crates/loro-internal/src/state/tree_state.rs Outdated Show resolved Hide resolved
crates/loro-internal/src/state/tree_state.rs Show resolved Hide resolved
crates/loro-internal/src/state/tree_state.rs Outdated Show resolved Hide resolved
crates/loro-internal/src/handler.rs Outdated Show resolved Hide resolved
crates/loro-internal/src/value.rs Show resolved Hide resolved
crates/loro-internal/Cargo.toml Outdated Show resolved Hide resolved
@Leeeon233 Leeeon233 requested a review from zxch3n May 5, 2024 07:25
crates/loro/src/lib.rs Show resolved Hide resolved
@Leeeon233 Leeeon233 merged commit fffd49b into main May 7, 2024
1 check passed
@Leeeon233 Leeeon233 deleted the leon/sorted-movable-tree branch May 7, 2024 06:01
@github-actions github-actions bot mentioned this pull request May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants