loro/crates/compact-bytes
Zixuan Chen c105ff2220
Feat: checkout to target version & use unicode index by default (#98)
* feat: checkout to frontiers

* feat: record timestamp

* fix: use unicode len by default for text
now "你好" has length of 2 instead of 6

* chore: rm dbg!
2023-08-04 10:45:23 +08:00
..
benches feat: make capacity adjustable 2023-07-14 00:47:02 +08:00
examples refactor: refine compact bytes interface 2023-07-14 12:51:06 +08:00
fuzz Revert "perf: make mem more compact" 2023-07-14 02:57:53 +08:00
src Feat: checkout to target version & use unicode index by default (#98) 2023-08-04 10:45:23 +08:00
Cargo.toml Revert "perf: make mem more compact" 2023-07-14 02:57:53 +08:00
deno.json perf: skip when matched len < 4 2023-07-14 03:03:51 +08:00
README.md docs: update todo for compact-bytes 2023-07-13 17:01:19 +08:00

compact-bytes

It's a append-only bytes arena. Appending new bytes will get a pointer to a slice of the append-only bytes. It will try to reuse the allocated old bytes to reduce memory usage, if possible.

Example

use compact_bytes::CompactBytes;

let mut arena = CompactBytes::new();
let bytes1 = arena.alloc(b"hello");
let bytes2 = arena.alloc(b"world");
assert_eq!(bytes1.as_bytes(), b"hello");
assert_eq!(bytes2.as_bytes(), b"world");

// bytes3 will be a pointer to the same bytes as bytes1
let bytes3 = arena.alloc(b"hello");
assert_eq!(bytes3.as_bytes(), b"hello");
assert_eq!(bytes3.start(), bytes1.start());
assert_eq!(bytes3.start(), 0);
assert_eq!(bytes3.end(), 5);

// Allocatting short bytes will not reuse the old bytes.
// Because it will make merging neighboring slices easier so that when
// serializing the bytes it will be more compact.
let mut bytes4 = arena.alloc(b"h");
assert_eq!(bytes4.start(), 10);
let bytes5 = arena.alloc(b"e");
assert_eq!(bytes5.start(), 11);
// bytes4 and bytes5 can be merged
assert_eq!(bytes4.can_merge(&bytes5), true);
assert!(bytes4.try_merge(&bytes5).is_ok());

In advance mode, it will try to reuse the old bytes as much as possible. So it will break the bytes into small pieces to reuse them.

use compact_bytes::CompactBytes;
use std::ops::Range;

let mut arena = CompactBytes::new();
let bytes1 = arena.alloc(b"hello");
// it breaks the bytes into 3 pieces "hi ", "hello", " world"
let bytes2: Vec<Range<usize>> = arena.alloc_advance(b"hi hello world");

Or you can use append to not reuse the old bytes at all.

use compact_bytes::CompactBytes;

let mut arena = CompactBytes::new();
let bytes1 = arena.alloc(b"hello");
let bytes2 = arena.append(b"hello");
assert_ne!(bytes1.start(), bytes2.start());

TODO

  • More memory efficient implementation