18 个版本

使用旧的Rust 2015

0.4.3 2022年3月27日
0.4.2 2021年1月8日
0.4.1 2018年12月7日
0.4.0 2017年6月29日
0.1.3 2015年7月27日

#20 in 内存管理

Download history 114152/week @ 2024-02-14 124087/week @ 2024-02-21 137525/week @ 2024-02-28 139156/week @ 2024-03-06 128431/week @ 2024-03-13 136211/week @ 2024-03-20 143041/week @ 2024-03-27 130419/week @ 2024-04-03 120923/week @ 2024-04-10 129765/week @ 2024-04-17 128898/week @ 2024-04-24 126763/week @ 2024-05-01 122462/week @ 2024-05-08 137224/week @ 2024-05-15 144664/week @ 2024-05-22 150269/week @ 2024-05-29

578,818 每月下载量
用于 1,180 个crate (51 直接)

MIT/Apache

135KB
3.5K SLoC

tendril

警告:此库处于非常早期的开发阶段,其中包含大量unsafe代码。请自行承担风险!

Build Status

API文档

简介

Tendril 是一种紧凑的字符串/缓冲区类型,针对零拷贝解析进行了优化。藤蔓具有所有权的字符串语义,但有时是共享缓冲区的视图。当你修改藤蔓时,如果需要,将创建一个所有权的副本。进一步的修改将在原地发生,直到字符串变为共享,例如通过 clone()subtendril()

通过线程局部(非原子)引用计数来实现缓冲区共享,它具有非常低的开销。Rust类型系统将在编译时防止你将藤蔓在线程之间发送。(下面有关于放宽此限制的想法。)

与在堆中为任何非空字符串分配的 String 不同,Tendril 可以将小字符串(最多 8 个字节)内联存储,无需堆分配。Tendril 在 64 位平台上也比 String 小——16 个字节比 24 个字节小。Option<Tendril> 的大小与 Tendril 相同,多亏了 NonZero

最大 tendril 长度为 4 GB。如果您尝试超过此限制,库将引发 panic。

格式和编码

Tendril 使用 虚类型 来跟踪缓冲区的格式。这确定在编译时,哪些操作可以在给定的 tendril 上使用。例如,Tendril<UTF8>Tendril<Bytes> 可以分别借用为 &str&[u8]

Tendril 还与 rust-encoding 集成,并初步支持 WTF-8 缓冲区。

未来计划

绳子

html5ever 将使用 Tendril 作为零拷贝文本表示。保留这种表示一直到 Servo 的 DOM 是一件好事。这将减少内存消耗,并可能加快文本形状和绘制。然而,DOM 文本可能比 4 GB 大,并且无论如何也不会在内存中连续,例如字符实体引用周围。

解决方案: 在这些字符串之上构建一个 rope,并使用它作为 Servo 的 DOM 文本表示。我们也许可以对绳子的不同部分进行并行文本形状和/或绘制。html5ever 还可以将此绳类型用作 BufferQueue 的替代品。

因为底层缓冲区是引用计数的,所以这个绳子的大部分已经是 持久数据结构。考虑将两个绳子附加在一起以获取一个“新”绳子时会发生什么。基于向量的绳子将复制一个小结构体的向量,每个部分一个,并增加相应的引用计数。但它不会复制任何字符串数据。

如果我们想要更多的共享,那么 2-3 finger tree 可能是一个不错的选择。我们可能会继续使用 VecDeque 来处理一定大小以下的绳子。

UTF-16 兼容性

SpiderMonkey 期望大部分文本以 UCS-2 格式存在。在 UTF-8 上实现 JavaScript 字符串的语义很困难。这也适用于通过 document.write 进行 HTML 解析。此外,传递给 SpiderMonkey 的非连续内存字符串将产生额外的开销和复杂性,如果不是完整的复制。

解决方案: 在解析和在 DOM 中使用 WTF-8。Servo 将在必要时 转换为连续的 UTF-16。如果发现一次转换大量文本块是实用的,则转换可以轻松并行化。

源跨度信息

一些html5ever API消费者希望知道每个标记或解析错误的HTML源文件中的原始位置。一个示例应用是一个命令行HTML验证器,其诊断输出类似于rustc的。

解决方案:接受每个输入字符串的一些元数据。元数据的类型由API消费者选择;默认为(),大小为零。对于任何非内联字符串,我们都可以提供关联的元数据以及字节数。

依赖关系

~0–1.2MB
~35K SLoC