|
| 1 | +Ropey is a utf8-text rope library for Rust, designed for efficient editing and |
| 2 | +manipulation of large texts. |
| 3 | + |
| 4 | +Note: this repository is currently a WIP for the new implementation of Ropey, |
| 5 | +and is not yet published to crates.io. The currently published versions can be |
| 6 | +found at https://github.com/cessen/ropey_old |
| 7 | + |
| 8 | + |
| 9 | +# Features |
| 10 | + |
| 11 | +## Strong Unicode support |
| 12 | +Ropey treats Unicode code points as the base unit of text. In other words, |
| 13 | +you can index into, slice by, and iterate over a rope by `char` index. |
| 14 | + |
| 15 | +Ropey also ensures that [grapheme clusters](https://www.unicode.org/reports/tr29/) |
| 16 | +are never split in its internal representation, and thus can always be accessed |
| 17 | +as coherent `&str` slices. Moreover, Ropey provides APIs for iterating over |
| 18 | +graphemes and querying about grapheme boundaries. |
| 19 | + |
| 20 | +## Slicing |
| 21 | + |
| 22 | +Ropey has rope slices that allows you to work with just parts of a rope, using |
| 23 | +any of the read-only operations of a full rope including iterators and making |
| 24 | +sub-slices. |
| 25 | + |
| 26 | + |
| 27 | +## Line-aware |
| 28 | + |
| 29 | +Ropey knows about line breaks, allowing you to index into and iterate over lines |
| 30 | +of text. |
| 31 | + |
| 32 | + |
| 33 | +## Streaming loading and saving |
| 34 | + |
| 35 | +Ropey provides APIs for efficiently streaming text data to and from ropes. This |
| 36 | +is primarily intended for efficiently saving a rope's text to disk and |
| 37 | +efficiently loading text from disk into a new rope. But the APIs are flexible, |
| 38 | +and can be used for whatever you like. |
| 39 | + |
| 40 | + |
| 41 | +## Efficient |
| 42 | + |
| 43 | +Ropey is fast and minimizes memory usage: |
| 44 | + |
| 45 | +- On a recent mobile i7 Intel CPU, Ropey was able to perform over 700,000 small |
| 46 | + incoherent insertions per second, building up a text roughly 100 MB large. |
| 47 | + Coherent insertions (i.e. all near the same place in the text) are even |
| 48 | + faster, doing the same task at over 1.1 million insertions per second. |
| 49 | +- Cloning ropes is _extremely_ cheap. Rope clones share data, so an initial |
| 50 | + clone only takes 8 bytes of memory. After that, memory usage will grow |
| 51 | + incrementally as the clones diverge due to edits. |
| 52 | +- Freshly loading a file from disk incurs roughly 30% memory overhead. For |
| 53 | + example, a 100 MB text file will occupy about 130 MB of memory when loaded |
| 54 | + by Ropey. Memory overhead will increase slowly with edits, but is bounded |
| 55 | + (fragmentation from memory allocators aside). |
| 56 | + |
| 57 | + |
| 58 | +## Thread safe |
| 59 | + |
| 60 | +Ropey ensures that even though clones share memory, everything is thread-safe. |
| 61 | +Clones can be sent to other threads for both reading and writing. |
| 62 | + |
| 63 | + |
| 64 | +# Things to still investigate |
| 65 | + |
| 66 | +Although text loaded from a file has low memory overhead, the same size text |
| 67 | +created from scratch by many small inserts has a lot more overhead. In the |
| 68 | +worst cases it can be almost 140%. This likely isn't a problem for the primary |
| 69 | +intended application of Ropey (e.g. as the backing storage for text editors) |
| 70 | +since text typed out in a single session is unlikely to be in the megabytes, but |
| 71 | +it would be good to address this anyway. |
| 72 | + |
| 73 | +The most likely solution is to be more aggressive about merging leaf nodes when |
| 74 | +possible, even during insertion. The tricky part will be doing that without |
| 75 | +harming performance too much. |
| 76 | + |
| 77 | +# Contributing |
| 78 | + |
| 79 | +Contributions are absolutely welcome! However, I do have a feeling for how I |
| 80 | +want Ropey to be structured and work, so please open an issue or email me to |
| 81 | +discuss larger changes, to avoid doing a lot of work for nothing. |
| 82 | + |
| 83 | +By submitting a pull request to this repository, you implicitly license your |
| 84 | +code under the same license (MIT, see LICENSE.md) as Ropey. |
0 commit comments