refactor(cli): classify dictionary load diagnostics in Rust
The file-I/O wrapper already delegated dictionary loading to Rust but kept all status interpretation in C. That duplicated the malloc and mmap status families and made the platform-specific error branches part of the C policy surface. Add a Rust classifier that maps the shared numeric loader statuses to diagnostic actions, including the distinct mmap failure classes. Keep metadata lookup, platform handles, ownership, and the exact EXM_THROW text in C, where the configured platform APIs still belong. The classifier also rejects out-of-range type/status values; the valid malloc and mmap enums intentionally share numeric values and therefore cannot be distinguished beyond their family tag. Test Plan: - `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets` -- passed (192 tests) - Broader native and original-test verification remains pending for the complete batch.
This commit is contained in:
+64
-43
@@ -378,6 +378,20 @@ int FIO_rust_setDictBufferMalloc(const char* fileName,
|
||||
size_t maxSize,
|
||||
void** buffer,
|
||||
size_t* loadedSize);
|
||||
/* Rust owns the dictionary-loader status classification. C keeps the
|
||||
* metadata, ownership handles, and exact diagnostics around the existing
|
||||
* narrow loader status ABI. */
|
||||
enum {
|
||||
FIO_RUST_DICT_DIAGNOSTIC_OK = 0,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_OPEN_FAILED = 1,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_TOO_LARGE = 2,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_ALLOCATION_FAILED = 3,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_READ_FAILED = 4,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_MAP_FAILED = 5,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_VIEW_FAILED = 6,
|
||||
FIO_RUST_DICT_DIAGNOSTIC_INVALID = 7,
|
||||
};
|
||||
int FIO_rust_dictLoadDiagnostic(int dictBufferType, int status);
|
||||
#if (PLATFORM_POSIX_VERSION > 0) || defined(_MSC_VER) || defined(_WIN32)
|
||||
enum {
|
||||
FIO_DICT_MMAP_SUCCESS = 0,
|
||||
@@ -805,6 +819,7 @@ static size_t FIO_setDictBufferMalloc(FIO_Dict_t* dict, const char* fileName, FI
|
||||
FIO_DICT_LOAD_READ_FAILED = 4,
|
||||
};
|
||||
int status;
|
||||
int diagnostic;
|
||||
|
||||
assert(bufferPtr != NULL);
|
||||
assert(dictFileStat != NULL);
|
||||
@@ -824,23 +839,24 @@ static size_t FIO_setDictBufferMalloc(FIO_Dict_t* dict, const char* fileName, FI
|
||||
dictSizeMax,
|
||||
bufferPtr,
|
||||
&loadedSize);
|
||||
if (status == FIO_DICT_LOAD_SUCCESS) return loadedSize;
|
||||
if (status == FIO_DICT_LOAD_OPEN_FAILED) {
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
diagnostic = FIO_rust_dictLoadDiagnostic((int)FIO_mallocDict, status);
|
||||
switch (diagnostic) {
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OK:
|
||||
return loadedSize;
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OPEN_FAILED:
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_TOO_LARGE:
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_ALLOCATION_FAILED:
|
||||
EXM_THROW(34, "%s", strerror(errno));
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_READ_FAILED:
|
||||
EXM_THROW(35, "Error reading dictionary file %s : %s",
|
||||
fileName, strerror(errno));
|
||||
default:
|
||||
assert(0); /* unexpected Rust diagnostic */
|
||||
return 0;
|
||||
}
|
||||
if (status == FIO_DICT_LOAD_TOO_LARGE) {
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
}
|
||||
if (status == FIO_DICT_LOAD_ALLOCATION_FAILED) {
|
||||
EXM_THROW(34, "%s", strerror(errno));
|
||||
}
|
||||
if (status == FIO_DICT_LOAD_READ_FAILED) {
|
||||
EXM_THROW(35, "Error reading dictionary file %s : %s",
|
||||
fileName, strerror(errno));
|
||||
}
|
||||
assert(0); /* unexpected Rust status */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (PLATFORM_POSIX_VERSION > 0)
|
||||
@@ -850,6 +866,7 @@ static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_
|
||||
size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX;
|
||||
void** bufferPtr = &dict->dictBuffer;
|
||||
int status;
|
||||
int diagnostic;
|
||||
|
||||
assert(bufferPtr != NULL);
|
||||
assert(dictFileStat != NULL);
|
||||
@@ -870,19 +887,21 @@ static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_
|
||||
bufferPtr,
|
||||
&dict->dictBufferSize,
|
||||
NULL);
|
||||
if (status == FIO_DICT_MMAP_SUCCESS) return dict->dictBufferSize;
|
||||
if (status == FIO_DICT_MMAP_OPEN_FAILED) {
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
diagnostic = FIO_rust_dictLoadDiagnostic((int)FIO_mmapDict, status);
|
||||
switch (diagnostic) {
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OK:
|
||||
return dict->dictBufferSize;
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OPEN_FAILED:
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_TOO_LARGE:
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_MAP_FAILED:
|
||||
EXM_THROW(34, "%s", strerror(errno));
|
||||
default:
|
||||
assert(0); /* unexpected Rust diagnostic */
|
||||
return 0;
|
||||
}
|
||||
if (status == FIO_DICT_MMAP_TOO_LARGE) {
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
}
|
||||
if (status == FIO_DICT_MMAP_FAILED) {
|
||||
EXM_THROW(34, "%s", strerror(errno));
|
||||
}
|
||||
assert(0); /* unexpected Rust status */
|
||||
return 0;
|
||||
}
|
||||
#elif defined(_MSC_VER) || defined(_WIN32)
|
||||
static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat)
|
||||
@@ -891,6 +910,7 @@ static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_
|
||||
size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX;
|
||||
void** bufferPtr = &dict->dictBuffer;
|
||||
int status;
|
||||
int diagnostic;
|
||||
|
||||
assert(bufferPtr != NULL);
|
||||
assert(dictFileStat != NULL);
|
||||
@@ -911,22 +931,23 @@ static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_
|
||||
bufferPtr,
|
||||
&dict->dictBufferSize,
|
||||
(void**)&dict->dictHandle);
|
||||
if (status == FIO_DICT_MMAP_SUCCESS) return dict->dictBufferSize;
|
||||
if (status == FIO_DICT_MMAP_OPEN_FAILED) {
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
diagnostic = FIO_rust_dictLoadDiagnostic((int)FIO_mmapDict, status);
|
||||
switch (diagnostic) {
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OK:
|
||||
return dict->dictBufferSize;
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_OPEN_FAILED:
|
||||
EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno));
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_TOO_LARGE:
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_MAP_FAILED:
|
||||
EXM_THROW(35, "Couldn't map dictionary %s: %s", fileName, strerror(errno));
|
||||
case FIO_RUST_DICT_DIAGNOSTIC_VIEW_FAILED:
|
||||
EXM_THROW(36, "%s", strerror(errno));
|
||||
default:
|
||||
assert(0); /* unexpected Rust diagnostic */
|
||||
return 0;
|
||||
}
|
||||
if (status == FIO_DICT_MMAP_TOO_LARGE) {
|
||||
EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)",
|
||||
fileName, (unsigned)dictSizeMax); /* avoid extreme cases */
|
||||
}
|
||||
if (status == FIO_DICT_MMAP_FAILED) {
|
||||
EXM_THROW(35, "Couldn't map dictionary %s: %s", fileName, strerror(errno));
|
||||
}
|
||||
if (status == FIO_DICT_MMAP_VIEW_FAILED) {
|
||||
EXM_THROW(36, "%s", strerror(errno));
|
||||
}
|
||||
assert(0); /* unexpected Rust status */
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat)
|
||||
|
||||
Reference in New Issue
Block a user