Skip to content

Commit 24a4a7a

Browse files
fix: bound LMDB growth + deprecate unsafe no-lock mode (#441)
* fix: bound LMDB growth + deprecate unsafe no-lock mode Adds runaway-growth safeguards (closes #437) report of multi-GB frecency cache. Deprecates the old unsafe_no_lock mode. Refs: #437 * chore: Update docs for - fix: bound LMDB growth + deprecate unsafe no-lock mode
1 parent 1bcbce2 commit 24a4a7a

14 files changed

Lines changed: 387 additions & 185 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ This repository contains **FFF.nvim (Fast File Finder)**, a high-performance fil
44

55
## Development Commands
66

7+
Always prefer Makefile commands listed to the cargo/bun/node if possible.
8+
79
### Building
810

9-
- `cargo build --release` - Build the Rust fuzzy matcher and file picker
11+
- `make build` - build everything
1012

1113
### Testing and Development Tools
1214

@@ -17,7 +19,6 @@ This project does not have a traditional test suite. Testing is done through:
1719

1820
### Code Quality
1921

20-
- `cargo fmt` - Format Rust code (follows standard conventions)
2122
- `make lint` - Rust linting and code analysis
2223
- `make format` - Format all code
2324
- `make test` - Run unit tests (limited coverage, primarily integration testing)

crates/fff-c/include/fff.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,16 @@ typedef struct FffMixedSearchResult {
352352
* cache-budget configuration. This function delegates to `fff_create_instance2`
353353
* with NULL log paths and auto cache budget, so behaviour is unchanged.
354354
*
355+
* The `use_unsafe_no_lock` parameter is deprecated and ignored; see
356+
* [`fff_create_instance2`] for details.
357+
*
355358
* ## Safety
356359
* See `fff_create_instance2`.
357360
*/
358361
struct FffResult *fff_create_instance(const char *base_path,
359362
const char *frecency_db_path,
360363
const char *history_db_path,
361-
bool use_unsafe_no_lock,
364+
bool _use_unsafe_no_lock,
362365
bool enable_mmap_cache,
363366
bool enable_content_indexing,
364367
bool watch,
@@ -375,7 +378,7 @@ struct FffResult *fff_create_instance(const char *base_path,
375378
* * `base_path` – directory to index (required)
376379
* * `frecency_db_path` – frecency LMDB database path (NULL/empty to skip)
377380
* * `history_db_path` – query history LMDB database path (NULL/empty to skip)
378-
* * `use_unsafe_no_lock` – use MDB_NOLOCK for LMDB (useful in single-process setups)
381+
* * `use_unsafe_no_lock` – **deprecated, ignored.** Previously enabled
379382
* * `enable_mmap_cache` – pre-populate mmap caches after the initial scan
380383
* * `enable_content_indexing` – build content index after the initial scan
381384
* * `watch` – start a background file-system watcher for live updates
@@ -399,7 +402,7 @@ struct FffResult *fff_create_instance(const char *base_path,
399402
struct FffResult *fff_create_instance2(const char *base_path,
400403
const char *frecency_db_path,
401404
const char *history_db_path,
402-
bool use_unsafe_no_lock,
405+
bool _use_unsafe_no_lock,
403406
bool enable_mmap_cache,
404407
bool enable_content_indexing,
405408
bool watch,

crates/fff-c/src/lib.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,17 @@ fn default_i32(val: i32, default: i32) -> i32 {
110110
/// cache-budget configuration. This function delegates to `fff_create_instance2`
111111
/// with NULL log paths and auto cache budget, so behaviour is unchanged.
112112
///
113+
/// The `use_unsafe_no_lock` parameter is deprecated and ignored; see
114+
/// [`fff_create_instance2`] for details.
115+
///
113116
/// ## Safety
114117
/// See `fff_create_instance2`.
115118
#[unsafe(no_mangle)]
116119
pub unsafe extern "C" fn fff_create_instance(
117120
base_path: *const c_char,
118121
frecency_db_path: *const c_char,
119122
history_db_path: *const c_char,
120-
use_unsafe_no_lock: bool,
123+
_use_unsafe_no_lock: bool,
121124
enable_mmap_cache: bool,
122125
enable_content_indexing: bool,
123126
watch: bool,
@@ -128,7 +131,7 @@ pub unsafe extern "C" fn fff_create_instance(
128131
base_path,
129132
frecency_db_path,
130133
history_db_path,
131-
use_unsafe_no_lock,
134+
false,
132135
enable_mmap_cache,
133136
enable_content_indexing,
134137
watch,
@@ -152,7 +155,11 @@ pub unsafe extern "C" fn fff_create_instance(
152155
/// * `base_path` – directory to index (required)
153156
/// * `frecency_db_path` – frecency LMDB database path (NULL/empty to skip)
154157
/// * `history_db_path` – query history LMDB database path (NULL/empty to skip)
155-
/// * `use_unsafe_no_lock` – use MDB_NOLOCK for LMDB (useful in single-process setups)
158+
/// * `use_unsafe_no_lock` – **deprecated, ignored.** Previously enabled
159+
/// `MDB_NOLOCK|MDB_NOSYNC|MDB_NOMETASYNC` for LMDB; benchmarks showed no
160+
/// measurable win under realistic contention, so the flag is now a no-op.
161+
/// The parameter remains in the signature for ABI compatibility and will be
162+
/// removed in a future release.
156163
/// * `enable_mmap_cache` – pre-populate mmap caches after the initial scan
157164
/// * `enable_content_indexing` – build content index after the initial scan
158165
/// * `watch` – start a background file-system watcher for live updates
@@ -177,7 +184,7 @@ pub unsafe extern "C" fn fff_create_instance2(
177184
base_path: *const c_char,
178185
frecency_db_path: *const c_char,
179186
history_db_path: *const c_char,
180-
use_unsafe_no_lock: bool,
187+
_use_unsafe_no_lock: bool,
181188
enable_mmap_cache: bool,
182189
enable_content_indexing: bool,
183190
watch: bool,
@@ -214,12 +221,12 @@ pub unsafe extern "C" fn fff_create_instance2(
214221
let _ = std::fs::create_dir_all(parent);
215222
}
216223

217-
match FrecencyTracker::new(frecency_path, use_unsafe_no_lock) {
224+
match FrecencyTracker::open(frecency_path) {
218225
Ok(tracker) => {
219226
if let Err(e) = shared_frecency.init(tracker) {
220227
return FffResult::err(&format!("Failed to acquire frecency lock: {}", e));
221228
}
222-
let _ = shared_frecency.spawn_gc(frecency_path.clone(), use_unsafe_no_lock);
229+
let _ = shared_frecency.spawn_gc(frecency_path.clone());
223230
}
224231
Err(e) => return FffResult::err(&format!("Failed to init frecency db: {}", e)),
225232
}
@@ -231,7 +238,7 @@ pub unsafe extern "C" fn fff_create_instance2(
231238
let _ = std::fs::create_dir_all(parent);
232239
}
233240

234-
match QueryTracker::new(history_path, use_unsafe_no_lock) {
241+
match QueryTracker::open(history_path) {
235242
Ok(tracker) => {
236243
if let Err(e) = query_tracker.init(tracker) {
237244
return FffResult::err(&format!("Failed to acquire query tracker lock: {}", e));

0 commit comments

Comments
 (0)