3个版本
0.1.2 | 2022年6月30日 |
---|---|
0.1.1 | 2022年6月30日 |
0.1.0 | 2022年6月30日 |
#2204 在 算法
59KB
1K SLoC
提供ObjectStore
类型,这是一种容器,只要对象实现了Castable
,就可以存储任意对象。
提供无生命周期的句柄,以后可以安全地用来访问存储对象的引用。支持将句柄转换为存储对象实现的任何特质的对象,并在其Castable
实例中注册。内部数据布局有效地打包对象,为类型转换和搜索存储最少元数据。
变体
支持根据需要存储的类型支持变体
Send
和Sync
:ObjectStore<tag::SendSync>
Send
但不Sync
:ObjectStore<tag::Send>
- 既不是
Send
也不是Sync
:ObjectStore<tag::ThreadLocal>
缓冲区
ObjectStore
包含多个概念上的“缓冲区”,以u32
作为键。当你将对象推送到存储时,你必须选择将其分配到哪个缓冲区索引。在最简单的使用中,只能使用一个缓冲区(索引0)。然而,利用多个缓冲区可以提高性能
- 推送到同一缓冲区的对象在内存中存储在附近。
ObjectStore::find
操作在单个缓冲区上,因此缓冲区索引可以被视为主键以加快搜索。
注意事项
推动性用例是存储整个程序生命周期中存在的对象。因此,一旦对象被推送到ObjectStore
,它们就不会被丢弃,直到整个存储被丢弃。由于句柄的实现方式,还存在一个限制,即在整个程序生命周期中最多可以创建2^32个ObjectStore
实例。这可能会限制一些作为临时区域分配器的用例。
将对象推送到存储中不够快,无法在热循环中进行。在常见情况下,它涉及哈希查找和几个间接引用,以及每次推送先前未见过类型的对象时的一些分配和线性搜索。存储主要是为了快速访问、搜索和类型转换,而不是快速分配。
内部,内存被分割成2MB大小的分配。这对用户有三个主要影响,需要用户注意。
- 任何尝试将单个大于2MB的对象推送到
ObjectStore
都将引发panic。 - 如果对象大小是2MB的很大一部分,则在每个段的末尾都可能浪费内存。
- 每个缓冲区索引至少分配2MB。如果使用了1000个不同的缓冲区索引,这将是2GB,相当可观。因此,在多个缓冲区中存储少量小对象是不高效的。
依赖关系
~170KB