内存(管理)#

设备 (Devices)#

class Device : public std::enable_shared_from_this<Device>, public arrow::util::EqualityComparable<Device>#

实验性功能:硬件设备的抽象接口。

该对象表示一个可访问某些内存空间的设备。当处理 Buffer 或原始内存地址时,它允许确定应在何种上下文中解释该原始内存地址(例如,CPU 可访问内存,或特定 GPU 上的嵌入式内存)。

派生类包括 arrow::CPUDevice, arrow::cuda::CudaDevice

公共函数

virtual const char *type_name() const = 0#

该设备类型的简写。

返回值对于每个设备类都是不同的,但对于给定类的所有实例都是相同的。它可用作 RTTI 的替代方案。

virtual std::string ToString() const = 0#

设备的人类可读描述。

返回的值应足够详细,以便在必要时区分不同的实例。

virtual bool Equals(const Device&) const = 0#

此实例是否指向与另一个实例相同的设备。

inline virtual int64_t device_id() const#

如果存在多个此类型的设备,用于标识该设备的设备 ID。

如果不存在等效的“device_id”(例如非 NUMA 系统上的主 CPU 设备),则返回 -1。

inline bool is_cpu() const#

该设备是否为主 CPU 设备。

在确定内存地址是否可由 CPU 访问时,此简写方法非常有用。

virtual std::shared_ptr<MemoryManager> default_memory_manager() = 0#

返回绑定到此设备的 MemoryManager 实例。

返回的实例对该设备类型的 MemoryManager 实现使用默认参数。某些设备也允许使用非默认参数构造 MemoryManager 实例。

virtual DeviceAllocationType device_type() const = 0#

返回此设备的 DeviceAllocationType。

inline virtual Result<std::shared_ptr<Stream>> MakeStream(unsigned int flags)#

创建一个新的设备流。

这应该为设备创建适当的流类型(派生自 Device::Stream),以便进行流有序的事件和内存分配。

inline virtual Result<std::shared_ptr<Stream>> WrapStream(void *device_stream, Stream::release_fn_t release_fn)#

包装一个现有的设备流以及一个释放函数。

参数:
  • device_stream – 指向要包装的流的指针

  • release_fn – 在销毁期间调用的函数,可以传递 nullptr 或无操作函数以指示所有权由外部维护

class Stream#

实验性功能:设备特定流的不透明包装器。

本质上,这只是一个围绕 void* 的包装器,用于表示设备上流/队列的标准概念。派生类应能从其设备特定的对应项中进行简易构造。

派生类包括 arrow::cuda::CudaDevice::Stream

公共函数

virtual Status WaitEvent(const SyncEvent&) = 0#

使流等待提供的事件。

告诉流在不同步阻塞 CPU 的情况下,等待直到同步事件完成。

virtual Status Synchronize() const = 0#

阻塞当前线程,直到流的剩余任务完成。

class SyncEvent#

实验性功能:提供事件/流同步原语的对象。

派生类包括 arrow::cuda::CudaDevice::SyncEvent

公共函数

virtual Status Wait() = 0#

阻塞直到同步事件完成。

virtual Status Record(const Stream&) = 0#

在流上记录包装的事件,以便当流到达队列中的该点时触发事件。

class CPUDevice : public arrow::Device#

公共函数

virtual const char *type_name() const override#

该设备类型的简写。

返回值对于每个设备类都是不同的,但对于给定类的所有实例都是相同的。它可用作 RTTI 的替代方案。

virtual std::string ToString() const override#

设备的人类可读描述。

返回的值应足够详细,以便在必要时区分不同的实例。

virtual bool Equals(const Device&) const override#

此实例是否指向与另一个实例相同的设备。

inline virtual DeviceAllocationType device_type() const override#

返回此设备的 DeviceAllocationType。

virtual std::shared_ptr<MemoryManager> default_memory_manager() override#

返回绑定到此设备的 MemoryManager 实例。

返回的实例对该设备类型的 MemoryManager 实现使用默认参数。某些设备也允许使用非默认参数构造 MemoryManager 实例。

公共静态函数

static std::shared_ptr<Device> Instance()#

返回全局 CPUDevice 实例。

static std::shared_ptr<MemoryManager> memory_manager(MemoryPool *pool)#

创建一个 MemoryManager

返回的 MemoryManager 将使用给定的 MemoryPool 进行分配。

std::shared_ptr<MemoryManager> arrow::default_cpu_memory_manager()#

返回默认的 CPU MemoryManager 实例。

返回的单例实例使用默认的 MemoryPool。此函数是 CPUDevice::Instance()->default_memory_manager() 的一种更快的写法。

内存管理器#

class MemoryManager : public std::enable_shared_from_this<MemoryManager>#

实验性功能:提供内存管理原语的对象。

一个 MemoryManager 总是绑定到特定的 Device 实例。它还可以具有附加参数(例如用于分配 CPU 内存的 MemoryPool)。

派生类包括 arrow::CPUMemoryManager, arrow::cuda::CudaMemoryManager

公共函数

inline const std::shared_ptr<Device> &device() const#

MemoryManager 绑定的设备。

inline bool is_cpu() const#

MemoryManager 是否绑定到主 CPU 设备。

在确定内存地址是否可由 CPU 访问时,此简写方法非常有用。

virtual Result<std::shared_ptr<io::RandomAccessFile>> GetBufferReader(std::shared_ptr<Buffer> buf) = 0#

创建一个 RandomAccessFile 以读取特定的缓冲区。

给定的缓冲区必须绑定到此 MemoryManager

另请参阅 Buffer::GetReader 简写。

virtual Result<std::shared_ptr<io::OutputStream>> GetBufferWriter(std::shared_ptr<Buffer> buf) = 0#

创建一个 OutputStream 以写入特定的缓冲区。

给定的缓冲区必须是可变的,并绑定到此 MemoryManager。返回的流对象会写入缓冲区的底层内存(但不会调整其大小)。

另请参阅 Buffer::GetWriter 简写。

virtual Result<std::unique_ptr<Buffer>> AllocateBuffer(int64_t size) = 0#

分配一个(可变的)Buffer

缓冲区将在设备的内存中分配。

virtual Result<std::shared_ptr<Device>::SyncEvent>> MakeDeviceSyncEvent()#

创建一个新的 SyncEvent。

此版本应为设备构建适当的事件,并提供具有正确事件类型删除器的 unique_ptr。如果设备不需要或不使用任何同步,则允许返回 nullptr。

virtual Result<std::shared_ptr<Device>::SyncEvent>> WrapDeviceSyncEvent(void *sync_event, Device::SyncEvent::release_fn_t release_sync_event)#

将一个事件包装到 SyncEvent 中。

参数:
  • sync_event – 传入的 sync_event(应为指向适当类型的指针)

  • release_sync_event – 释放 sync_event 的析构函数。可以传递 nullptr 以指示无需销毁/释放

公共静态函数

static Result<std::shared_ptr<Buffer>> CopyBuffer(const std::shared_ptr<Buffer> &source, const std::shared_ptr<MemoryManager> &to)#

Buffer 复制到目标 MemoryManager

另请参阅 Buffer::Copy 简写。

static Result<std::unique_ptr<Buffer>> CopyNonOwned(const Buffer &source, const std::shared_ptr<MemoryManager> &to)#

将非所有权 Buffer 复制到目标 MemoryManager

这适用于源内存区域是外部管理的情况(其生命周期不绑定到源 Buffer),否则请使用 CopyBuffer()

static Result<std::shared_ptr<Buffer>> ViewBuffer(const std::shared_ptr<Buffer> &source, const std::shared_ptr<MemoryManager> &to)#

在目标 MemoryManager 中制作一个无拷贝的 Buffer 视图。

另请参阅 Buffer::View 简写。

static Status CopyBufferSliceToCPU(const std::shared_ptr<Buffer> &buf, int64_t offset, int64_t length, uint8_t *out_data)#

将缓冲区的一个切片复制到 CPU 指针中。

class CPUMemoryManager : public arrow::MemoryManager#

公共函数

virtual Result<std::shared_ptr<io::RandomAccessFile>> GetBufferReader(std::shared_ptr<Buffer> buf) override#

创建一个 RandomAccessFile 以读取特定的缓冲区。

给定的缓冲区必须绑定到此 MemoryManager

另请参阅 Buffer::GetReader 简写。

virtual Result<std::shared_ptr<io::OutputStream>> GetBufferWriter(std::shared_ptr<Buffer> buf) override#

创建一个 OutputStream 以写入特定的缓冲区。

给定的缓冲区必须是可变的,并绑定到此 MemoryManager。返回的流对象会写入缓冲区的底层内存(但不会调整其大小)。

另请参阅 Buffer::GetWriter 简写。

virtual Result<std::unique_ptr<Buffer>> AllocateBuffer(int64_t size) override#

分配一个(可变的)Buffer

缓冲区将在设备的内存中分配。

inline MemoryPool *pool() const#

返回与此 MemoryManager 关联的 MemoryPool

缓冲区 (Buffers)#

class Buffer#

包含指向具有特定大小的连续内存块的指针的对象。

缓冲区有两个相关的长度概念:大小(size)和容量(capacity)。大小是可能包含有效数据的字节数。容量是为缓冲区总共分配的字节数。

Buffer 基类不拥有其内存,但子类通常拥有。

以下不变量始终成立:大小 <= 容量

派生类包括 arrow::MutableBuffer, arrow::cuda::CudaBuffer

公共函数

inline Buffer(const uint8_t *data, int64_t size)#

从缓冲区和大小构造,无需复制内存。

注意

传递的内存必须通过其他方式保持活动状态

参数:
  • data[in] 内存缓冲区

  • size[in] 缓冲区大小

inline explicit Buffer(std::string_view data)#

从 string_view 构造,无需复制内存。

注意

data 查看的内存不得在 Buffer 的生命周期内被解除分配;临时右值字符串必须存储在某处的左值中

参数:

data[in] string_view 对象

inline Buffer(std::shared_ptr<Buffer> parent, const int64_t offset, const int64_t size)#

属于另一个缓冲区的数据的偏移量,但我们希望即使在父缓冲区的其他 shared_ptr 被销毁后,也能保留指向它的有效指针。

此方法不对缓冲区的对齐或填充做任何断言,但通常我们期望缓冲区对齐并填充到 64 字节。将来我们可能会添加实用方法来帮助确定缓冲区是否满足此约定。

std::string ToHexString()#

构建一个包含缓冲区十六进制表示的新 std::string。

返回:

std::string

bool Equals(const Buffer &other, int64_t nbytes) const#

如果两个缓冲区大小相同且在比较的字节数内包含相同的字节,则返回 true。

bool Equals(const Buffer &other) const#

如果两个缓冲区大小相同且包含相同的字节,则返回 true。

Result<std::shared_ptr<Buffer>> CopySlice(const int64_t start, const int64_t nbytes, MemoryPool *pool = default_memory_pool()) const#

将缓冲区的一部分复制到新的 Buffer 中。

inline void ZeroPadding()#

将填充中的字节清零,即 size_ 和 capacity_ 之间的字节。

std::string ToString() const#

将缓冲区内容复制到新的 std::string 中。

注意

如果缓冲区很大,可能会抛出 std::bad_alloc

返回:

std::string

inline explicit operator std::string_view() const#

以 std::string_view 的形式查看缓冲区内容。

返回:

std::string_view

inline const uint8_t *data() const#

返回指向缓冲区数据的指针。

缓冲区必须是 CPU 缓冲区(is_cpu() 为 true)。否则,可能会抛出断言或返回空指针。

要获取缓冲区的物理数据地址,无论其位于何种设备,请调用 address()

template<typename T>
inline const T *data_as() const#

返回转换为特定类型的缓冲区数据指针。

缓冲区必须是 CPU 缓冲区(is_cpu() 为 true)。否则,可能会抛出断言或返回空指针。

template<typename T>
inline std::span<const T> span_as() const#

以 span 形式返回缓冲区数据。

inline uint8_t *mutable_data()#

返回指向缓冲区数据的可写指针。

缓冲区必须是可变的 CPU 缓冲区(is_cpu()is_mutable() 均为 true)。否则,可能会抛出断言或返回空指针。

要获取缓冲区的可写数据地址,无论其位于何种设备,请调用 mutable_address()

template<typename T>
inline T *mutable_data_as()#

返回转换为特定类型的缓冲区可写数据指针。

缓冲区必须是可变的 CPU 缓冲区(is_cpu()is_mutable() 均为 true)。否则,可能会抛出断言或返回空指针。

template<typename T>
inline std::span<T> mutable_span_as()#

以 span 形式返回缓冲区的可写数据。

inline uintptr_t address() const#

返回缓冲区数据的设备地址。

inline uintptr_t mutable_address() const#

返回指向缓冲区数据的可写设备地址。

缓冲区必须是可变缓冲区(is_mutable() 为 true)。否则,可能会抛出断言或返回 0。

inline int64_t size() const#

以字节为单位返回缓冲区大小。

inline int64_t capacity() const#

返回缓冲区的容量(分配的字节数)

inline bool is_cpu() const#

缓冲区是否可由 CPU 直接访问。

如果此函数返回 true,您可以直接从缓冲区的 data() 指针读取。否则,您必须对其进行 View()Copy() 操作。

inline bool is_mutable() const#

缓冲区是否可变。

如果此函数返回 true,则允许您使用由 mutable_data()mutable_address() 返回的指针修改缓冲区内容。

公共静态函数

static std::shared_ptr<Buffer> FromString(std::string data)#

构造一个不可变缓冲区,该缓冲区获取 std::string 内容的所有权(无需复制)。

参数:

data[in] 要获取所有权的字符串

返回:

一个新的 Buffer 实例

template<typename T>
static inline std::shared_ptr<Buffer> FromVector(std::vector<T> vec)#

构造一个不可变缓冲区,该缓冲区获取 std::vector 内容的所有权(无需复制)。

只有 TrivialType 对象(整数、浮点数等)的向量才能被此函数封装。

参数:

vec[in] 要获取所有权的向量

返回:

一个新的 Buffer 实例

template<typename T, typename SizeType = int64_t>
static inline std::shared_ptr<Buffer> Wrap(const T *data, SizeType length)#

创建一个引用类型化内存且具有一定长度的缓冲区,无需复制。

参数:
  • data[in] 作为 C 数组的类型化内存

  • length[in] 数组中的值数量

返回:

一个新的 shared_ptr<Buffer>

template<typename T>
static inline std::shared_ptr<Buffer> Wrap(const std::vector<T> &data)#

创建一个引用 std::vector 且具有一定长度的缓冲区,无需复制。

参数:

data[in] 要被引用的向量。如果该向量发生更改,缓冲区可能会失效

返回:

一个新的 shared_ptr<Buffer>

static Result<std::shared_ptr<io::RandomAccessFile>> GetReader(std::shared_ptr<Buffer>)#

获取用于读取缓冲区的 RandomAccessFile。

返回的文件对象从该缓冲区的底层内存进行读取。

static Result<std::shared_ptr<io::OutputStream>> GetWriter(std::shared_ptr<Buffer>)#

获取用于写入缓冲区的 OutputStream。

缓冲区必须是可变的。返回的流对象写入缓冲区的底层内存(但不会调整其大小)。

static Result<std::shared_ptr<Buffer>> Copy(std::shared_ptr<Buffer> source, const std::shared_ptr<MemoryManager> &to)#

复制缓冲区。

缓冲区内容将被复制到由给定的 MemoryManager 分配的新缓冲区中。此函数支持跨设备复制。

static Result<std::unique_ptr<Buffer>> CopyNonOwned(const Buffer &source, const std::shared_ptr<MemoryManager> &to)#

复制非所属缓冲区。

这对于源内存区域是外部管理(其生命周期不绑定到源 Buffer)的情况很有用,否则请使用 Copy()

static Result<std::shared_ptr<Buffer>> View(std::shared_ptr<Buffer> source, const std::shared_ptr<MemoryManager> &to)#

查看缓冲区。

返回一个反映此缓冲区的 Buffer,可以从另一个设备查看,而无需显式复制内容。底层机制通常由内核或设备驱动程序实现,并且可能涉及在目标设备的内存上对部分缓冲区内容进行延迟缓存。

如果给定设备上的缓冲区不支持非复制视图,则返回 nullptr。如果某些低级操作失败(例如内存不足),则可能返回错误。

static Result<std::shared_ptr<Buffer>> ViewOrCopy(std::shared_ptr<Buffer> source, const std::shared_ptr<MemoryManager> &to)#

查看或复制缓冲区。

尝试在给定 MemoryManager 的设备上查看缓冲区内容,但如果不支持非复制视图,则回退到复制。

class MutableBuffer : public arrow::Buffer#

内容可变的 Buffer

可能拥有也可能不拥有其数据。

子类包括 arrow::ResizableBuffer, arrow::cuda::CudaHostBuffer

公共静态函数

template<typename T, typename SizeType = int64_t>
static inline std::shared_ptr<Buffer> Wrap(T *data, SizeType length)#

创建引用类型化内存且具有一定长度的缓冲区。

参数:
  • data[in] 作为 C 数组的类型化内存

  • length[in] 数组中的值数量

返回:

一个新的 shared_ptr<Buffer>

class ResizableBuffer : public arrow::MutableBuffer#

可调整大小的可变缓冲区。

公共函数

virtual Status Resize(const int64_t new_size, bool shrink_to_fit) = 0#

将缓冲区报告的大小更改为指定大小,必要时分配内存。

这将确保缓冲区的容量是 Layout.md 中定义的 64 字节的倍数。随后考虑使用 ZeroPadding 以符合 Arrow 布局规范。

参数:
  • new_size – 缓冲区的新大小。

  • shrink_to_fit – 如果新大小 < 当前大小,是否收缩容量

virtual Status Reserve(const int64_t new_capacity) = 0#

确保缓冲区分配了足够的内存以容纳指定的容量(并满足 Layout.md 中的 64 字节对齐要求)。

它不会更改缓冲区报告的大小,也不会将填充区域归零。

非所属缓冲区#

警告

此类仅作为 arrow::ArraySpan 的构建块公开。对于任何其他目的,请使用 arrow::Buffer

class BufferSpan#

非所属 Buffer 引用。

内存池#

MemoryPool *arrow::default_memory_pool()#

返回进程范围的默认内存池。

Status arrow::jemalloc_memory_pool(MemoryPool **out)#

返回一个基于 jemalloc 的进程范围内存池。

如果 jemalloc 不可用,可能返回 NotImplemented。

Status arrow::mimalloc_memory_pool(MemoryPool **out)#

返回一个基于 mimalloc 的进程范围内存池。

如果 mimalloc 不可用,可能返回 NotImplemented。

MemoryPool *arrow::system_memory_pool()#

返回一个基于系统分配器的进程范围内存池。

class MemoryPool#

用于 CPU 上内存分配的基类。

除了跟踪已分配字节数外,分配器还应负责所需的 64 字节对齐。

子类包括 arrow::CappedMemoryPool, arrow::LoggingMemoryPool, arrow::ProxyMemoryPool, arrow::stl::STLMemoryPool< Allocator >

公共函数

inline Status Allocate(int64_t size, uint8_t **out)#

分配至少 size 字节的新内存区域。

分配的区域应为 64 字节对齐。

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) = 0#

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) = 0#

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) = 0#

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

inline virtual void ReleaseUnused()#

将未使用的内存返回给操作系统。

仅适用于保留未使用内存的分配器。这属于尽力而为,内存池可能未实现此功能,或者由于碎片问题而无法满足请求。

inline virtual void PrintStats()#

打印统计信息。

将分配统计信息打印到 stderr。输出格式是实现特定的。并非所有内存池都实现此方法。

virtual int64_t bytes_allocated() const = 0#

通过此分配器分配且尚未释放的字节数。

virtual int64_t max_memory() const#

返回此内存池中的峰值内存分配。

返回:

已分配的最大字节数。如果未知(或未实现),则返回 -1

virtual int64_t total_bytes_allocated() const = 0#

已分配的字节数。

virtual int64_t num_allocations() const = 0#

已请求的分配或重新分配次数。

virtual std::string backend_name() const = 0#

MemoryPool 所使用的后端名称(例如“system”或“jemalloc”)。

公共静态函数

static std::unique_ptr<MemoryPool> CreateDefault()#

实验性功能。创建默认 MemoryPool 的新实例。

class LoggingMemoryPool : public arrow::MemoryPool#

公共函数

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) override#

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) override#

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) override#

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

virtual void ReleaseUnused() override#

将未使用的内存返回给操作系统。

仅适用于保留未使用内存的分配器。这属于尽力而为,内存池可能未实现此功能,或者由于碎片问题而无法满足请求。

virtual void PrintStats() override#

打印统计信息。

将分配统计信息打印到 stderr。输出格式是实现特定的。并非所有内存池都实现此方法。

virtual int64_t bytes_allocated() const override#

通过此分配器分配且尚未释放的字节数。

virtual int64_t max_memory() const override#

返回此内存池中的峰值内存分配。

返回:

已分配的最大字节数。如果未知(或未实现),则返回 -1

virtual int64_t total_bytes_allocated() const override#

已分配的字节数。

virtual int64_t num_allocations() const override#

已请求的分配或重新分配次数。

virtual std::string backend_name() const override#

MemoryPool 所使用的后端名称(例如“system”或“jemalloc”)。

inline Status Allocate(int64_t size, uint8_t **out)#

分配至少 size 字节的新内存区域。

分配的区域应为 64 字节对齐。

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) = 0

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) = 0

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) = 0

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

class ProxyMemoryPool : public arrow::MemoryPool#

用于内存分配的派生类。

跟踪通过其直接调用分配的字节数和最大内存。实际分配委托给 MemoryPool 类。

公共函数

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) override#

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) override#

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) override#

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

virtual void ReleaseUnused() override#

将未使用的内存返回给操作系统。

仅适用于保留未使用内存的分配器。这属于尽力而为,内存池可能未实现此功能,或者由于碎片问题而无法满足请求。

virtual void PrintStats() override#

打印统计信息。

将分配统计信息打印到 stderr。输出格式是实现特定的。并非所有内存池都实现此方法。

virtual int64_t bytes_allocated() const override#

通过此分配器分配且尚未释放的字节数。

virtual int64_t max_memory() const override#

返回此内存池中的峰值内存分配。

返回:

已分配的最大字节数。如果未知(或未实现),则返回 -1

virtual int64_t total_bytes_allocated() const override#

已分配的字节数。

virtual int64_t num_allocations() const override#

已请求的分配或重新分配次数。

virtual std::string backend_name() const override#

MemoryPool 所使用的后端名称(例如“system”或“jemalloc”)。

inline Status Allocate(int64_t size, uint8_t **out)#

分配至少 size 字节的新内存区域。

分配的区域应为 64 字节对齐。

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) = 0

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) = 0

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) = 0

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

std::vector<std::string> arrow::SupportedMemoryBackendNames()#

返回此 Arrow 构建所支持的后端名称。

内存分配函数#

这些函数用于从特定的内存池中分配缓冲区。

Result<std::unique_ptr<Buffer>> AllocateBuffer(const int64_t size, MemoryPool *pool = NULLPTR)#

从内存池中分配指定大小的可变缓冲区,并将填充区域清零。

参数:
  • size[in] 要分配的缓冲区大小

  • pool[in] 内存池

Result<std::unique_ptr<Buffer>> AllocateBuffer(const int64_t size, int64_t alignment, MemoryPool *pool = NULLPTR)#
Result<std::unique_ptr<ResizableBuffer>> AllocateResizableBuffer(const int64_t size, MemoryPool *pool = NULLPTR)#

从内存池中分配可调整大小的缓冲区,并将填充区域清零。

参数:
  • size[in] 要分配的缓冲区大小

  • pool[in] 内存池

Result<std::unique_ptr<ResizableBuffer>> AllocateResizableBuffer(const int64_t size, const int64_t alignment, MemoryPool *pool = NULLPTR)#
Result<std::shared_ptr<Buffer>> AllocateBitmap(int64_t length, MemoryPool *pool = NULLPTR)#

从内存池中分配一个位图缓冲区,不保证初始值。

参数:
  • length[in] 要分配的位图大小(以位为单位)

  • pool[in] 用于分配内存的内存池

Result<std::shared_ptr<Buffer>> AllocateEmptyBitmap(int64_t length, MemoryPool *pool = NULLPTR)#

从内存池中分配一个初始化为零的位图缓冲区。

参数:
  • length[in] 要分配的位图大小(以位为单位)

  • pool[in] 用于分配内存的内存池

Result<std::shared_ptr<Buffer>> AllocateEmptyBitmap(int64_t length, int64_t alignment, MemoryPool *pool = NULLPTR)#
Result<std::shared_ptr<Buffer>> ConcatenateBuffers(const BufferVector &buffers, MemoryPool *pool = NULLPTR)#

将多个缓冲区连接成单个缓冲区。

参数:
  • buffers[in] 待连接的缓冲区

  • pool[in] 用于分配新缓冲区的内存池

切片#

static inline std::shared_ptr<Buffer> SliceBuffer(std::shared_ptr<Buffer> buffer, const int64_t offset, const int64_t length)#

在给定的偏移量和长度处构造缓冲区的视图。

该函数不会失败,也不检查错误(调试版本除外)。

static inline std::shared_ptr<Buffer> SliceBuffer(std::shared_ptr<Buffer> buffer, const int64_t offset)#

在给定的偏移量处构造直到缓冲区末尾的视图。

该函数不会失败,也不检查错误(调试版本除外)。

Result<std::shared_ptr<Buffer>> SliceBufferSafe(std::shared_ptr<Buffer> buffer, int64_t offset)#

SliceBuffer 的输入检查版本。

如果请求的切片越界,则返回 Invalid Status

Result<std::shared_ptr<Buffer>> SliceBufferSafe(std::shared_ptr<Buffer> buffer, int64_t offset, int64_t length)#

SliceBuffer 的输入检查版本。

如果请求的切片越界,则返回 Invalid Status。注意:与 SliceBuffer 不同,length 不会被截断为可用缓冲区大小。

std::shared_ptr<Buffer> SliceMutableBuffer(std::shared_ptr<Buffer> buffer, const int64_t offset, const int64_t length)#

类似于 SliceBuffer,但构造一个可变缓冲区切片。

如果父缓冲区不可变,则行为未定义(在调试版本中可能会中止)。

static inline std::shared_ptr<Buffer> SliceMutableBuffer(std::shared_ptr<Buffer> buffer, const int64_t offset)#

类似于 SliceBuffer,但构造一个可变缓冲区切片。

如果父缓冲区不可变,则行为未定义(在调试版本中可能会中止)。

Result<std::shared_ptr<Buffer>> SliceMutableBufferSafe(std::shared_ptr<Buffer> buffer, int64_t offset)#

SliceMutableBuffer 的输入检查版本。

如果请求的切片越界,则返回 Invalid Status

Result<std::shared_ptr<Buffer>> SliceMutableBufferSafe(std::shared_ptr<Buffer> buffer, int64_t offset, int64_t length)#

SliceMutableBuffer 的输入检查版本。

如果请求的切片越界,则返回 Invalid Status。注意:与 SliceBuffer 不同,length 不会被截断为可用缓冲区大小。

缓冲区构建器#

class BufferBuilder#

用于增量构建内存中连续数据块的类。

公共函数

inline explicit BufferBuilder(std::shared_ptr<ResizableBuffer> buffer, MemoryPool *pool = default_memory_pool(), int64_t alignment = kDefaultBufferAlignment)#

构造一个新的构建器,它将开始使用提供的缓冲区,直到调用 Finish/Reset。

缓冲区不会被调整大小。

inline Status Resize(const int64_t new_capacity, bool shrink_to_fit = true)#

将缓冲区调整为 64 字节的倍数。

参数:
  • new_capacity – 构建器的新容量。将向上舍入为 64 字节的倍数以进行填充

  • shrink_to_fit – 如果新容量小于现有容量,则重新分配内部缓冲区。设置为 false 以在缩小构建器时避免重新分配。

返回:

Status(状态)

inline Status Reserve(const int64_t additional_bytes)#

确保构建器可以容纳额外的字节数,而无需执行分配。

参数:

additional_bytes[in] 需要腾出空间的额外字节数

返回:

Status(状态)

inline Status Append(const void *data, const int64_t length)#

将给定的数据追加到缓冲区。

如果需要,缓冲区会自动扩展。

inline Status Append(std::string_view v)#

将给定的数据追加到缓冲区。

如果需要,缓冲区会自动扩展。

inline Status Append(const int64_t num_copies, uint8_t value)#

将值的多个副本追加到缓冲区。

如果需要,缓冲区会自动扩展。

inline Status Finish(std::shared_ptr<Buffer> *out, bool shrink_to_fit = true)#

将构建器的结果作为 Buffer 对象返回。

构建器会被重置,之后可以重复使用。

参数:
  • out[out] 完成后的 Buffer 对象

  • shrink_to_fit – 如果缓冲区大小小于其容量,则重新分配以使其在内存中更紧凑。设置为 false 以避免重新分配,但可能会消耗更多内存。

返回:

Status(状态)

inline Result<std::shared_ptr<Buffer>> FinishWithLength(int64_t final_length, bool shrink_to_fit = true)#

类似于 Finish,但覆盖最终缓冲区大小。

这在直接将数据写入构建器内存而不调用 Append 方法(基本上,在主要使用 BufferBuilder 进行内存分配时)后很有用。

inline void Rewind(int64_t position)#

将大小设置为较小的值而不修改构建器内容。

适用于可重复使用的 BufferBuilder 类。

参数:

position[in] 必须是非负数且小于或等于当前的 length()

公共静态函数

static inline int64_t GrowByFactor(int64_t current_capacity, int64_t new_capacity)#

返回按所需增长因子扩展后的容量。

template<typename T, typename Enable = void>
class TypedBufferBuilder#

STL 集成#

template<class T>
class allocator#

将分配委托给 Arrow MemoryPool 的 STL 分配器。

公共函数

inline allocator() noexcept#

使用默认 MemoryPool 构造分配器。

inline explicit allocator(MemoryPool *pool) noexcept#

使用给定的 MemoryPool 构造分配器。

template<class U>
struct rebind#
template<typename Allocator = std::allocator<uint8_t>>
class STLMemoryPool : public arrow::MemoryPool#

将分配委托给 STL 分配器的 MemoryPool 实现。

请注意,STL 分配器不提供调整大小操作,因此任何缓冲区调整大小都将执行完整的重新分配和复制。

公共函数

inline explicit STLMemoryPool(const Allocator &alloc)#

使用给定的分配器构造内存池。

inline virtual Status Allocate(int64_t size, int64_t, uint8_t **out) override#

分配至少 size 字节且对齐到 alignment 的新内存区域。

inline virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t, uint8_t **ptr) override#

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。

inline virtual void Free(uint8_t *buffer, int64_t size, int64_t) override#

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

inline virtual int64_t bytes_allocated() const override#

通过此分配器分配且尚未释放的字节数。

inline virtual int64_t max_memory() const override#

返回此内存池中的峰值内存分配。

返回:

已分配的最大字节数。如果未知(或未实现),则返回 -1

inline virtual int64_t total_bytes_allocated() const override#

已分配的字节数。

inline virtual int64_t num_allocations() const override#

已请求的分配或重新分配次数。

inline virtual std::string backend_name() const override#

MemoryPool 所使用的后端名称(例如“system”或“jemalloc”)。

inline Status Allocate(int64_t size, uint8_t **out)#

分配至少 size 字节的新内存区域。

分配的区域应为 64 字节对齐。

virtual Status Allocate(int64_t size, int64_t alignment, uint8_t **out) = 0

分配至少 size 字节且对齐到 alignment 的新内存区域。

virtual void Free(uint8_t *buffer, int64_t size, int64_t alignment) = 0

释放已分配区域。

参数:
  • buffer – 指向已分配内存区域起始位置的指针

  • size – 位于 buffer 处的已分配大小。分配器实现可以使用此信息来跟踪已分配的字节数,以及在后端支持的情况下进行更快的解除分配。

  • alignment – 分配的对齐方式。默认为 64 字节。

virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment, uint8_t **ptr) = 0

调整已分配内存部分的大小。

由于默认情况下大多数平台上的默认分配器不支持对齐重新分配,因此此函数可能涉及对底层数据的复制。