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
//! # getattrlistbulk
//!
//! Safe Rust bindings for the macOS `getattrlistbulk()` system call.
//!
//! This crate provides high-performance directory enumeration by retrieving
//! file metadata in bulk, reducing the number of syscalls from O(n) to O(n/batch_size).
//!
//! ## Performance
//!
//! | Approach | Complexity | 10K Files |
//! |----------|------------|-----------|
//! | Traditional (`readdir` + `stat`) | O(n) | ~20,000 syscalls |
//! | **`getattrlistbulk`** | O(n/batch) | **~12 syscalls** |
//!
//! **~1,600x fewer syscalls → ~4x faster** on NVMe SSDs (up to 50x on network storage).
//!
//! ```text
//! Traditional: opendir() → [readdir() + stat()] × N → closedir()
//! This crate: open() → getattrlistbulk() × ceil(N/800) → close()
//! ```
//!
//! Run `cargo bench --bench compare` for reproducible benchmarks on your hardware.
//!
//! ## Example
//!
//! ```no_run
//! use getattrlistbulk::{read_dir, RequestedAttributes};
//!
//! let attrs = RequestedAttributes {
//! name: true,
//! size: true,
//! ..Default::default()
//! };
//!
//! for entry in read_dir("/Users", attrs).unwrap() {
//! let entry = entry.unwrap();
//! println!("{}: {} bytes", entry.name, entry.size.unwrap_or(0));
//! }
//! ```
//!
//! ## Platform Support
//!
//! This crate only compiles on macOS. Attempting to compile on other platforms
//! will result in a compile-time error.
compile_error!;
pub use ;
pub use Error;
pub use DirEntries;
pub use DirReader;
use Path;
/// Read directory entries with specified attributes.
///
/// Uses a default buffer size of 64KB. For large directories,
/// consider using [`read_dir_with_buffer`] with a larger buffer.
///
/// # Example
///
/// ```no_run
/// use getattrlistbulk::{read_dir, RequestedAttributes};
///
/// let attrs = RequestedAttributes {
/// name: true,
/// size: true,
/// object_type: true,
/// ..Default::default()
/// };
///
/// for entry in read_dir("/tmp", attrs)? {
/// println!("{:?}", entry?);
/// }
/// # Ok::<(), getattrlistbulk::Error>(())
/// ```
/// Read directory entries with custom buffer size.
///
/// Larger buffers result in fewer syscalls but use more memory.
/// Recommended buffer sizes:
/// - 64KB: Default, good for most directories
/// - 256KB: Large directories (10,000+ files)
/// - 1MB: Very large directories (100,000+ files)