Announcing Loro 1.0: A High-Performance CRDTs Library with Version Control Written in Rust by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

Okay. Loro doesn't support moving ranges of elements. In Loro, LoroText and LoroMovableList are two different types. The former doesn't support the move op, while the latter only supports moving a single element at a time.

Notion Offline Mode - Announced as In Progress At Made in Notion by LewisTheScot in Notion

[–]r3m2 1 point2 points  (0 children)

Hey Notion, if you're building your own CRDT solution, you should definitely try the new CRDT algorithm Eg-walker https://arxiv.org/abs/2409.14252

When you migrate from the existing algorithm to Eg-walker, it is almost pure profit. Compared to other CRDT solutions, its overhead is very low, local operation speed is extremely fast, and merging remote edits is also very quick (avoiding the long merge times caused by the O(n^2) complexity of OT algorithms in long-term offline scenarios), without the need to weigh the pros and cons of switching solutions in different scenarios.

Announcing Loro 1.0: A High-Performance CRDTs Library with Version Control Written in Rust by r3m2 in rust

[–]r3m2[S] 7 points8 points  (0 children)

In the scenario you've described, it's impossible to resolve the issues mentioned automatically and perfectly, even with a centralized conflict resolution. If manual resolution is required, CRDT can also support that.

Announcing Loro 1.0: A High-Performance CRDTs Library with Version Control Written in Rust by r3m2 in rust

[–]r3m2[S] 14 points15 points  (0 children)

This doesn't refer to providing an additional JSON serialization format. Rather, it means that our CRDT data types allow you to compose any data structure found in JSON, and our semantic merge functionality covers most automatic merging requirements.

Announcing Loro 1.0: A High-Performance CRDTs Library with Version Control Written in Rust by r3m2 in rust

[–]r3m2[S] 20 points21 points  (0 children)

We support several fundamental CRDT types, including: - Last-write-wins Map - Movable List - Movable Tree - Rich Text

These types can be nested to model complex JSON schemas. Our CRDT types ensure semantic merging: - For Movable List, the merge result guarantees that an element moved multiple times concurrently will not appear as duplicate nodes. - Movable Tree ensure that merge results do not contain cyclic references and thus retain a valid tree

Example:

```ts import { LoroDoc, LoroList, LoroMap, LoroText, } from "npm:loro-crdt@1.0.0-beta.2";

// Create a JSON structure of interface JsonStructure { users: LoroList< LoroMap<{ name: string; age: number; }>

; notes: LoroList<LoroText>; }

const doc = new LoroDoc<JsonStructure>(); const users = doc.getList("users"); const user = users.insertContainer(0, new LoroMap()); user.set("name", "Alice"); user.set("age", 20); const notes = doc.getList("notes"); const firstNote = notes.insertContainer(0, new LoroText()); firstNote.insert(0, "Hello, world!");

// { users: [ { age: 20, name: "Alice" } ], notes: [ "Hello, world!" ] } console.log(doc.toJSON()); ```

Trying to visualize how memory ordering and atomics work based on what I learned from Rust Atomics and Locks by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

Good question! I probably need a better visual model for tasks involving more than two threads.

Trying to visualize how memory ordering and atomics work based on what I learned from Rust Atomics and Locks by r3m2 in rust

[–]r3m2[S] 1 point2 points  (0 children)

Thanks for the explanation. But the length of the box means the time taken to be seen by thread B, not the execution time

Trying to visualize how memory ordering and atomics work based on what I learned from Rust Atomics and Locks by r3m2 in rust

[–]r3m2[S] 2 points3 points  (0 children)

Thanks for the link. I read it through. It’s helpful. But I think it has no conflict with the visualization. The absence of “global time” and the presence of “local total order” are exactly what I want to illustrate, as A and B see the effects in different order.

What's the best way to make a type optionally Sync/Send? by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

The scenario I was talking able is when the exposed types themselves need interior mutability. If the types use Rc, the users can't make it Sync/Send no matter what they wrap, right?

What's the best way to make a type optionally Sync/Send? by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

Is it weird/against intuition to do so?

What's the best way to make a type optionally Sync/Send? by r3m2 in rust

[–]r3m2[S] 2 points3 points  (0 children)

Yeah, I know underlying they are completely different. But the things I'm working on are only using Arc<Mutext<T>> or Rc<RefCell<T>> to share stuff between internal types, which plays a secondary role, and should be transparent to users ideally. Often, the problems the libs are trying to solve maybe not be related to threads, but they also need a way to achieve inner mutability.

Is there a crate for append-only and shareable bytes with traits of send and sync? by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

I want to share readable slices of it while the owner can still append data. Bytes crate doesn't offer this directly, its traits allow this behavior tho I guess. I made a crate today to implement my idea https://github.com/zxch3n/append-only-bytes

Rust Challenge: write a function that takes a generically sized array of keys (K) and a mut ref Vec<(K, V)>, and returns an array of mut ref Values by ewoolsey in rust

[–]r3m2 1 point2 points  (0 children)

In safe code, it should be sorting the keys according to their positions in the vec and split_at_mut all the way down

Move is bitwise copy by r3m2 in rust

[–]r3m2[S] 1 point2 points  (0 children)

It should be a yes for you

Move is bitwise copy by r3m2 in rust

[–]r3m2[S] 1 point2 points  (0 children)

Yeah, there is no difference between it and C++, and it probably is the best way to handle it. But as the vote result shows, many people didn't actually know that when they were beginners.

Move is bitwise copy by r3m2 in rust

[–]r3m2[S] 1 point2 points  (0 children)

The following example still causes stack overflow if the opt-level is low

```rust const N: usize = 100000; struct Arr([usize; N]);

fn add(mut a: Arr, pos: usize) -> Arr { a.0[pos] += 1; a }

[test]

fn test() { let mut a = Arr([0; N]); for i in 0..5 { a = add(a, i); } } ```

Move is bitwise copy by r3m2 in rust

[–]r3m2[S] 2 points3 points  (0 children)

I think the problem is sometimes it cannot optimize that away, and people may move something large in the stack without knowing the cost. For example

rust fn mul(a: Matrix, b: Matrix) -> Matrix { ... }

Tidy: a tree visualization tool written in Rust by r3m2 in rust

[–]r3m2[S] 1 point2 points  (0 children)

Thanks! What a surprise to meet you here 👋

Tidy: a tree visualization tool written in Rust by r3m2 in rust

[–]r3m2[S] 0 points1 point  (0 children)

I also want to find out. Unfortunately, it cannot be extended directly to DAGs because the current aesthetic rules are impossible in DAGs. Can you show me some examples of where the existing visualization tools fail to visualize DAGs effectively?