#object-pool #pool #lock-free #memory-pool #no-std

no-std opool

高性能、无锁的本地和并发对象池,具有自动分配、清理和验证功能

2个版本

0.1.1 2023年5月23日
0.1.0 2023年5月21日

#432 in 内存管理

每月 22 次下载
用于 2 crates

MIT 许可证

31KB
571

Opool: 快速无锁的并发和本地对象池

Crates.io Documentation MIT licensed

Opool是一个高性能的Rust库,提供并发和本地对象池的实现。它旨在提供效率和灵活性,使您能够管理对象的生命周期并重用它们以最小化分配开销。Opool支持带有alloc的no_std

为何使用Opool

  • 卓越性能:Opool由于其设计选择而优于其他替代方案,特别是其使用PoolAllocator,它通过编译器实现内联功能,从而减少了不必要的函数调用和跳转,产生了更好的执行代码。
  • 无锁设计:Opool不使用任何互斥锁,确保无锁实现。它最大限度地减少了对操作系统的系统调用的依赖,除了alloc crate提供的之外,从而进一步提高了性能。
  • 增强兼容性:Opool支持带有alloc的no_std环境,使其适用于各种Rust项目。
  • 全面接口:Opool提供了一个完整的接口,自动处理对象池的分配、清理和验证。您不再需要手动清理池分配的数据,并且您可以提供一个相关的PoolAllocator::reset函数,在自动收集时清理对象。
  • 引用计数引用:Opool支持引用计数引用,尽管建议尽可能使用静态引用。此功能简化了Rust代码的生命周期,尤其是在特定场景下。

结构

  • PoolAllocator 特征:此特征定义了池分配器的接口。它包括分配、重置和验证对象的方法。重置和验证函数是可选的。
  • Pool 结构体:这个结构体代表一个对象池。它使用 ArrayQueue 进行存储,并使用 PoolAllocator 进行对象管理。
  • LocalPool 结构体:这个结构体代表一个线程局部对象池,限制在当前线程中使用。它使用 VecDeque 进行存储,并使用 PoolAllocator 进行对象管理。
  • RefGuardRcGuardRefLocalGuardRcLocalGuard 结构体:这些结构体是智能指针,当它们被丢弃时,会自动将对象返回到池中。它们还提供了访问底层对象的方法。

用法

首先,通过实现 PoolAllocator 特征来定义您的分配器。这包括提供 PoolAllocator::allocate 方法来创建新对象,可选的 PoolAllocator::reset 方法将对象重置为其初始状态,以及 PoolAllocator::is_valid 方法来检查对象是否仍然有效,可以将其推回到池中。

然后,使用您的分配器创建一个 PoolLocalPool。您可以使用 new 方法创建一个空的池,或者使用 new_prefilled 方法创建一个初始填充了特定数量对象的池。

要从池中获取对象,请使用 get 方法。这将返回一个 RefGuardRcGuard,具体取决于您是否调用了 getget_rc。这些守卫在它们被丢弃时自动将对象返回到池中。

要使用 get_rc,您需要通过在池上调用 to_rc 来将其转换为引用计数版本。

以下是一个示例

use opool::{Pool, PoolAllocator};
struct MyAllocator;

const BUF_SIZE: usize = 1024 * 8;
impl PoolAllocator<Vec<u8>> for MyAllocator {
    #[inline]
    fn allocate(&self) -> Vec<u8> {
        vec![0; BUF_SIZE]
    }

    /// OPTIONAL METHODS:

    #[inline]
    fn reset(&self, _obj: &mut Vec<u8>) {
        // Optionally you can clear or zero object fields here
    }

    #[inline]
    fn is_valid(&self, obj: &Vec<u8>) -> bool {
        // you can optionally is_valid if object is good to be pushed back to the pool
        obj.capacity() == BUF_SIZE
    }
}

let pool = Pool::new(64, MyAllocator);
let obj = pool.get();
// Use the object, and it will be automatically recycled after its lifetime ends.

安装

将此添加到您的 Cargo.toml

[dependencies]
opool = "0.1"

许可证

Opool 使用 MIT 许可证授权。请参阅 LICENSE 文件以获取更多详细信息。

依赖项

~155KB