| Crates.io | peoplesgrocers-lseq |
| lib.rs | peoplesgrocers-lseq |
| version | 0.99.0 |
| created_at | 2025-12-13 05:34:23.020807+00 |
| updated_at | 2025-12-13 05:34:23.020807+00 |
| description | L-SEQ algorithm implementation for fractional indexing and list CRDTs |
| homepage | https://peoplesgrocers.com/code/oss/lseq |
| repository | https://peoplesgrocers.com/code/oss/lseq |
| max_upload_size | |
| id | 1982588 |
| size | 30,013 |
Rust implementation of the L-SEQ algorithm for fractional indexing and list CRDTs.
Add this to your Cargo.toml:
[dependencies]
peoplesgrocers-lseq = "1.0.0"
use peoplesgrocers_lseq::{LSEQ, SortKey, compare_lseq};
use rand::thread_rng;
// Create a new L-SEQ instance
let mut lseq = LSEQ::new(thread_rng());
// Allocate identifiers
let id1 = lseq.alloc(None, None); // First identifier
let id2 = lseq.alloc(Some(&id1), None); // After id1
let id3 = lseq.alloc(Some(&id1), Some(&id2)); // Between id1 and id2
// Sort identifiers
let mut ids = vec![id3.clone(), id1.clone(), id2.clone()];
ids.sort();
println!("{:?}", ids); // [id1, id3, id2] - properly ordered
// Convert to/from strings
let key_str = id1.to_string();
let parsed_key: SortKey = key_str.parse().unwrap();
assert_eq!(id1, parsed_key);
// Use with deterministic RNG for testing
use rand::rngs::StdRng;
use rand::SeedableRng;
let rng = StdRng::seed_from_u64(42);
let mut deterministic_lseq = LSEQ::new(rng);
LSEQ<R: Rng>new(rng: R) -> SelfCreates a new L-SEQ instance with the given random number generator.
alloc(&mut self, before: Option<&SortKey>, after: Option<&SortKey>) -> SortKeyAllocates a new identifier between two existing identifiers.
before: The identifier that should come before the new one (or None for beginning)after: The identifier that should come after the new one (or None for end)before and afterSortKeyA sort key that implements Ord, Serialize, Deserialize, and string conversion.
EvenSpacingIteratorUtility for generating evenly spaced sort keys for bulk operations.
L-SEQ generates identifiers using a base-64 alphabet that maintains lexicographic ordering. Each identifier is a sequence of characters from this alphabet, and new identifiers are generated by finding space between existing ones at different depths.
The algorithm uses alternating allocation strategies (bias toward min or max) at different depths to avoid degenerative cases and maintain good performance characteristics.