jdb_alloc 0.1.4

Aligned memory allocator for Direct I/O / Direct I/O 对齐内存分配器
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
[English]#en | [中文]#zh

---

<a id="en"></a>

# jdb_alloc : Aligned Memory Allocator for Direct I/O

## Table of Contents

- [Overview]#overview
- [Features]#features
- [Installation]#installation
- [Usage]#usage
- [API Reference]#api-reference
- [Design]#design
- [Tech Stack]#tech-stack
- [Project Structure]#project-structure
- [History]#history

## Overview

`jdb_alloc` provides 4KB-aligned memory allocation for Direct I/O operations. It offers two core types:

- `AlignedBuf`: Owning buffer with automatic memory management
- `RawIoBuf`: Non-owning, `Copy` buffer for zero-copy async I/O

Designed for high-performance database storage engines and Buffer Pool implementations.

## Features

- 4KB alignment for Direct I/O (O_DIRECT)
- Zero-copy buffer slicing
- `Copy` semantics for async I/O compatibility
- Arena-style memory management
- Integration with [compio]https://github.com/compio-rs/compio async runtime
- OS-optimized zero page allocation (COW)

## Installation

```bash
cargo add jdb_alloc
```

## Usage

### Basic Allocation

```rust
use jdb_alloc::{AlignedBuf, PAGE_SIZE};

// Allocate zeroed 4KB page
let buf = AlignedBuf::page().unwrap();
assert_eq!(buf.len(), PAGE_SIZE);

// Allocate with custom size
let mut buf = AlignedBuf::zeroed(8192).unwrap();
buf.as_mut()[0] = 42;
```

### Zero-Copy I/O

```rust
use jdb_alloc::AlignedBuf;

let mut buf = AlignedBuf::zeroed(4096).unwrap();

// Convert to RawIoBuf for async I/O
let raw = unsafe { buf.as_raw() };

// RawIoBuf is Copy, can be passed to async operations
// while retaining local reference
```

### Buffer Pool Arena Pattern

```rust
use jdb_alloc::{AlignedBuf, RawIoBuf, PAGE_SIZE};

// Allocate large arena (e.g., 32KB = 8 pages)
let arena = AlignedBuf::zeroed(PAGE_SIZE * 8).unwrap();

// Slice into frames
let frames: Vec<RawIoBuf> = unsafe {
  arena.slice_into_raws(PAGE_SIZE).collect()
};

assert_eq!(frames.len(), 8);
```

### Extend Buffer

```rust
use jdb_alloc::AlignedBuf;

let mut buf = AlignedBuf::with_cap(4096).unwrap();
buf.extend(b"hello").unwrap();
buf.extend(b" world").unwrap();
assert_eq!(&buf[..], b"hello world");
```

## API Reference

### Constants

| Name | Value | Description |
|------|-------|-------------|
| `PAGE_SIZE` | 4096 | Standard page size |
| `ALIGNMENT` | 4096 | Direct I/O alignment requirement |

### AlignedBuf

Owning aligned buffer. Releases memory on drop.

| Method | Description |
|--------|-------------|
| `with_cap(cap)` | Create with capacity (uninitialized) |
| `zeroed(size)` | Create zeroed buffer |
| `page()` | Create 4KB zeroed page |
| `as_raw()` | Convert to `RawIoBuf` (unsafe) |
| `as_raw_view()` | Get `RawIoBuf` view (unsafe) |
| `slice_into_raws(chunk)` | Slice into multiple `RawIoBuf` (unsafe) |
| `extend(data)` | Append data |
| `try_clone()` | Clone without panic on OOM |
| `into_raw_parts()` | Deconstruct (leak memory) |
| `from_raw_parts(ptr, len, cap)` | Reconstruct (unsafe) |

### RawIoBuf

Non-owning buffer wrapper. Implements `Copy` for async I/O ergonomics.

| Method | Description |
|--------|-------------|
| `new(ptr, cap)` | Create wrapper (unsafe) |
| `with_len(len)` | Set length (chainable) |
| `from_slice(slice)` | Create from mutable slice |
| `slice(offset, len)` | Slice for reading (unsafe) |
| `slice_data(offset, len)` | Slice for writing (unsafe) |
| `slice_unchecked(offset, len)` | Slice without checks (unsafe) |
| `as_slice()` | Get byte slice |
| `as_mut_slice()` | Get mutable byte slice |

### Compio Integration

Both types implement:
- `IoBuf` - Read buffer trait
- `IoBufMut` - Write buffer trait
- `SetBufInit` - Initialize buffer length

## Design

### Architecture

```mermaid
graph TD
  A[AlignedBuf] -->|owns| B[Aligned Memory]
  A -->|as_raw| C[RawIoBuf]
  A -->|slice_into_raws| D[Multiple RawIoBuf]
  C -->|Copy| E[Async I/O Operation]
  D -->|frames| F[Buffer Pool]
```

### Memory Layout

```
AlignedBuf (Owning)
┌─────────────────────────────────────┐
│ ptr: NonNull<u8>  (4KB aligned)     │
│ len: usize        (initialized)     │
│ cap: usize        (allocated)       │
└─────────────────────────────────────┘
RawIoBuf (Non-owning, Copy)
┌─────────────────────────────────────┐
│ ptr: *mut u8      (borrowed)        │
│ len: usize                          │
│ cap: usize                          │
└─────────────────────────────────────┘
```

### Call Flow

1. Allocate `AlignedBuf` as arena
2. Slice into `RawIoBuf` frames via `slice_into_raws`
3. Pass `RawIoBuf` to async I/O (Copy semantics)
4. I/O completion updates buffer content
5. Arena (`AlignedBuf`) manages lifetime

## Tech Stack

| Component | Technology |
|-----------|------------|
| Language | Rust 2024 Edition |
| Async I/O | compio-buf |
| Error Handling | thiserror |
| Memory | std::alloc (aligned) |

## Project Structure

```
jdb_alloc/
├── src/
│   ├── lib.rs      # Core types: AlignedBuf, RawIoBuf
│   └── error.rs    # Error definitions
├── tests/
│   └── main.rs     # Unit tests
├── readme/
│   ├── en.md       # English documentation
│   └── zh.md       # Chinese documentation
└── Cargo.toml
```

## History

Direct I/O emerged in the 1990s as databases sought to bypass the OS page cache for predictable performance. The `O_DIRECT` flag, introduced in Linux 2.4.10 (2001), requires strict alignment—typically 512 bytes for older disks, 4KB for modern SSDs.

The 4KB alignment matches the standard page size on most architectures, a design dating back to the VAX-11/780 (1977) which popularized 512-byte disk sectors and 4KB virtual memory pages.

Modern NVMe SSDs with 4KB logical blocks make this alignment even more critical. Misaligned I/O can cause read-modify-write cycles, degrading performance by 2-10x.

This library draws inspiration from database systems like PostgreSQL's buffer manager and RocksDB's aligned buffer implementation, optimized for Rust's ownership model and async I/O patterns.

---

## About

This project is an open-source component of [js0.site ⋅ Refactoring the Internet Plan](https://js0.site).

We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:

* [Google Group]https://groups.google.com/g/js0-site
* [js0site.bsky.social]https://bsky.app/profile/js0site.bsky.social

---

<a id="zh"></a>

# jdb_alloc : Direct I/O 对齐内存分配器

## 目录

- [概述]#概述
- [特性]#特性
- [安装]#安装
- [使用]#使用
- [API 参考]#api-参考
- [设计]#设计
- [技术栈]#技术栈
- [项目结构]#项目结构
- [历史]#历史

## 概述

`jdb_alloc` 提供 4KB 对齐的内存分配,用于 Direct I/O 操作。核心类型:

- `AlignedBuf`: 拥有所有权的缓冲区,自动管理内存
- `RawIoBuf`: 无所有权、可 `Copy` 的缓冲区,用于零拷贝异步 I/O

专为高性能数据库存储引擎和 Buffer Pool 设计。

## 特性

- 4KB 对齐,支持 Direct I/O (O_DIRECT)
- 零拷贝缓冲区切片
- `Copy` 语义,兼容异步 I/O
- Arena 风格内存管理
- 集成 [compio]https://github.com/compio-rs/compio 异步运行时
- OS 优化的零页分配 (COW)

## 安装

```bash
cargo add jdb_alloc
```

## 使用

### 基础分配

```rust
use jdb_alloc::{AlignedBuf, PAGE_SIZE};

// 分配零初始化的 4KB 页
let buf = AlignedBuf::page().unwrap();
assert_eq!(buf.len(), PAGE_SIZE);

// 自定义大小分配
let mut buf = AlignedBuf::zeroed(8192).unwrap();
buf.as_mut()[0] = 42;
```

### 零拷贝 I/O

```rust
use jdb_alloc::AlignedBuf;

let mut buf = AlignedBuf::zeroed(4096).unwrap();

// 转换为 RawIoBuf 用于异步 I/O
let raw = unsafe { buf.as_raw() };

// RawIoBuf 是 Copy 的,可传递给异步操作
// 同时保留本地引用
```

### Buffer Pool Arena 模式

```rust
use jdb_alloc::{AlignedBuf, RawIoBuf, PAGE_SIZE};

// 分配大型 arena(如 32KB = 8 页)
let arena = AlignedBuf::zeroed(PAGE_SIZE * 8).unwrap();

// 切分为帧
let frames: Vec<RawIoBuf> = unsafe {
  arena.slice_into_raws(PAGE_SIZE).collect()
};

assert_eq!(frames.len(), 8);
```

### 扩展缓冲区

```rust
use jdb_alloc::AlignedBuf;

let mut buf = AlignedBuf::with_cap(4096).unwrap();
buf.extend(b"hello").unwrap();
buf.extend(b" world").unwrap();
assert_eq!(&buf[..], b"hello world");
```

## API 参考

### 常量

| 名称 || 描述 |
|------|-------|-------------|
| `PAGE_SIZE` | 4096 | 标准页大小 |
| `ALIGNMENT` | 4096 | Direct I/O 对齐要求 |

### AlignedBuf

拥有所有权的对齐缓冲区。Drop 时释放内存。

| 方法 | 描述 |
|--------|-------------|
| `with_cap(cap)` | 创建指定容量(未初始化) |
| `zeroed(size)` | 创建零初始化缓冲区 |
| `page()` | 创建 4KB 零初始化页 |
| `as_raw()` | 转换为 `RawIoBuf` (unsafe) |
| `as_raw_view()` | 获取 `RawIoBuf` 视图 (unsafe) |
| `slice_into_raws(chunk)` | 切分为多个 `RawIoBuf` (unsafe) |
| `extend(data)` | 追加数据 |
| `try_clone()` | 克隆,OOM 时不 panic |
| `into_raw_parts()` | 解构(泄漏内存) |
| `from_raw_parts(ptr, len, cap)` | 重建 (unsafe) |

### RawIoBuf

无所有权的缓冲区包装器。实现 `Copy` 以便于异步 I/O。

| 方法 | 描述 |
|--------|-------------|
| `new(ptr, cap)` | 创建包装器 (unsafe) |
| `with_len(len)` | 设置长度(链式调用) |
| `from_slice(slice)` | 从可变切片创建 |
| `slice(offset, len)` | 切片用于读取 (unsafe) |
| `slice_data(offset, len)` | 切片用于写入 (unsafe) |
| `slice_unchecked(offset, len)` | 无检查切片 (unsafe) |
| `as_slice()` | 获取字节切片 |
| `as_mut_slice()` | 获取可变字节切片 |

### Compio 集成

两种类型都实现:
- `IoBuf` - 读缓冲区 trait
- `IoBufMut` - 写缓冲区 trait
- `SetBufInit` - 初始化缓冲区长度

## 设计

### 架构

```mermaid
graph TD
  A[AlignedBuf] -->|拥有| B[对齐内存]
  A -->|as_raw| C[RawIoBuf]
  A -->|slice_into_raws| D[多个 RawIoBuf]
  C -->|Copy| E[异步 I/O 操作]
  D -->|| F[Buffer Pool]
```

### 内存布局

```
AlignedBuf (拥有所有权)
┌─────────────────────────────────────┐
│ ptr: NonNull<u8>  (4KB 对齐)        │
│ len: usize        (已初始化)        │
│ cap: usize        (已分配)          │
└─────────────────────────────────────┘
RawIoBuf (无所有权, Copy)
┌─────────────────────────────────────┐
│ ptr: *mut u8      (借用)            │
│ len: usize                          │
│ cap: usize                          │
└─────────────────────────────────────┘
```

### 调用流程

1. 分配 `AlignedBuf` 作为 arena
2. 通过 `slice_into_raws` 切分为 `RawIoBuf`3.`RawIoBuf` 传递给异步 I/O(Copy 语义)
4. I/O 完成后更新缓冲区内容
5. Arena (`AlignedBuf`) 管理生命周期

## 技术栈

| 组件 | 技术 |
|-----------|------------|
| 语言 | Rust 2024 Edition |
| 异步 I/O | compio-buf |
| 错误处理 | thiserror |
| 内存 | std::alloc (对齐) |

## 项目结构

```
jdb_alloc/
├── src/
│   ├── lib.rs      # 核心类型: AlignedBuf, RawIoBuf
│   └── error.rs    # 错误定义
├── tests/
│   └── main.rs     # 单元测试
├── readme/
│   ├── en.md       # 英文文档
│   └── zh.md       # 中文文档
└── Cargo.toml
```

## 历史

Direct I/O 诞生于 1990 年代,数据库系统为获得可预测的性能而绕过 OS 页缓存。Linux 2.4.10 (2001) 引入的 `O_DIRECT` 标志要求严格对齐——旧磁盘通常 512 字节,现代 SSD 为 4KB。

4KB 对齐与大多数架构的标准页大小一致,这一设计可追溯到 VAX-11/780 (1977),它普及了 512 字节磁盘扇区和 4KB 虚拟内存页。

现代 NVMe SSD 采用 4KB 逻辑块,使对齐更加关键。未对齐的 I/O 会导致读-修改-写循环,性能下降 2-10 倍。

本库借鉴了 PostgreSQL 缓冲区管理器和 RocksDB 对齐缓冲区实现,针对 Rust 所有权模型和异步 I/O 模式优化。

---

## 关于

本项目为 [js0.site ⋅ 重构互联网计划](https://js0.site) 的开源组件。

我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注:

* [谷歌邮件列表]https://groups.google.com/g/js0-site
* [js0site.bsky.social]https://bsky.app/profile/js0site.bsky.social