Skip to content

Commit 4ba127d

Browse files
committed
try to make dictBuffer a slice
1 parent 04cd2f0 commit 4ba127d

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

lib/dictBuilder/zdict.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::mem::MaybeUninit;
12
use std::time::{Duration, Instant};
23

34
use libc::{free, malloc, size_t};
@@ -1184,13 +1185,15 @@ unsafe fn finalize_dictionary(
11841185
}
11851186

11861187
unsafe fn ZDICT_addEntropyTablesFromBuffer_advanced(
1187-
dictBuffer: *mut core::ffi::c_void,
1188+
dictBuffer: &mut [MaybeUninit<u8>],
11881189
dictContentSize: size_t,
1189-
dictBufferCapacity: size_t,
11901190
samples: &[u8],
11911191
samplesSizes: &[usize],
11921192
params: ZDICT_params_t,
11931193
) -> size_t {
1194+
let dictBufferCapacity = dictBuffer.len();
1195+
let dictBuffer = dictBuffer.as_mut_ptr().cast::<core::ffi::c_void>();
1196+
11941197
let compressionLevel = if params.compressionLevel == 0 {
11951198
ZSTD_CLEVEL_DEFAULT
11961199
} else {
@@ -1212,7 +1215,7 @@ unsafe fn ZDICT_addEntropyTablesFromBuffer_advanced(
12121215
samplesSizes,
12131216
dictBuffer
12141217
.byte_add(dictBufferCapacity)
1215-
.byte_offset(-(dictContentSize as isize)),
1218+
.byte_sub(dictContentSize),
12161219
dictContentSize,
12171220
notificationLevel,
12181221
);
@@ -1226,7 +1229,7 @@ unsafe fn ZDICT_addEntropyTablesFromBuffer_advanced(
12261229
let randomID = ZSTD_XXH64(
12271230
dictBuffer
12281231
.byte_add(dictBufferCapacity)
1229-
.byte_offset(-(dictContentSize as isize)),
1232+
.byte_sub(dictContentSize),
12301233
dictContentSize,
12311234
0,
12321235
);
@@ -1241,10 +1244,10 @@ unsafe fn ZDICT_addEntropyTablesFromBuffer_advanced(
12411244

12421245
if hSize.wrapping_add(dictContentSize) < dictBufferCapacity {
12431246
core::ptr::copy(
1244-
(dictBuffer as *mut core::ffi::c_char)
1245-
.add(dictBufferCapacity)
1246-
.sub(dictContentSize),
1247-
(dictBuffer as *mut core::ffi::c_char).add(hSize),
1247+
dictBuffer
1248+
.byte_add(dictBufferCapacity)
1249+
.byte_sub(dictContentSize),
1250+
dictBuffer.byte_add(hSize),
12481251
dictContentSize,
12491252
)
12501253
}
@@ -1406,45 +1409,56 @@ fn ZDICT_trainFromBuffer_unsafe_legacy(
14061409
dictList[0].pos = n;
14071410
dictContentSize_0 = currentSize;
14081411

1409-
unsafe {
1410-
if let Err(e) = build_dictionary_content(dictBuffer, maxDictSize, samples, &dictList) {
1411-
return e.to_error_code();
1412+
let dictBuffer = unsafe {
1413+
if dictBuffer.is_null() || maxDictSize == 0 {
1414+
&mut []
1415+
} else {
1416+
core::slice::from_raw_parts_mut(dictBuffer.cast::<MaybeUninit<u8>>(), maxDictSize)
14121417
}
1418+
};
1419+
1420+
if let Err(e) = build_dictionary_content(dictBuffer, samples, &dictList) {
1421+
return e.to_error_code();
1422+
}
14131423

1424+
unsafe {
14141425
ZDICT_addEntropyTablesFromBuffer_advanced(
14151426
dictBuffer,
14161427
dictContentSize_0 as size_t,
1417-
maxDictSize,
14181428
samples,
14191429
samplesSizes,
14201430
params.zParams,
14211431
)
14221432
}
14231433
}
14241434

1425-
unsafe fn build_dictionary_content(
1426-
dictBuffer: *mut core::ffi::c_void,
1427-
maxDictSize: size_t,
1435+
fn build_dictionary_content(
1436+
dictBuffer: &mut [MaybeUninit<u8>],
14281437
samples: &[u8],
14291438
dictList: &[DictItem],
14301439
) -> Result<(), Error> {
14311440
// convention: table[0].pos stores the number of elements
14321441
let max = dictList[0].pos;
14331442

1434-
let mut ptr = (dictBuffer as *mut u8).add(maxDictSize);
1443+
let mut ptr = dictBuffer.len();
14351444
for item in &dictList[1..max as usize] {
1436-
let l = item.length;
1437-
ptr = ptr.sub(l as usize);
1438-
debug_assert!(ptr >= dictBuffer as *mut u8);
1439-
if ptr < dictBuffer as *mut u8 {
1440-
return Err(Error::GENERIC); // should not happen
1441-
}
1442-
core::ptr::copy_nonoverlapping(samples[item.pos as usize..].as_ptr(), ptr, l as size_t);
1445+
let l = item.length as usize;
1446+
ptr = match ptr.checked_sub(l) {
1447+
None => return Err(Error::GENERIC), // should not happen
1448+
Some(v) => v,
1449+
};
1450+
1451+
let src = uninit_slice(&samples[item.pos as usize..][..l]);
1452+
dictBuffer[ptr..][..l].copy_from_slice(src);
14431453
}
14441454

14451455
Ok(())
14461456
}
14471457

1458+
fn uninit_slice<T>(slice: &[T]) -> &[MaybeUninit<T>] {
1459+
unsafe { &*(slice as *const [T] as *const [MaybeUninit<T>]) }
1460+
}
1461+
14481462
/// Train a dictionary from an array of samples.
14491463
///
14501464
/// Samples must be stored concatenated in a single flat buffer `samplesBuffer`, supplied with an
@@ -1586,6 +1600,12 @@ pub unsafe extern "C" fn ZDICT_addEntropyTablesFromBuffer(
15861600
samplesSizes: *const size_t,
15871601
nbSamples: core::ffi::c_uint,
15881602
) -> size_t {
1603+
let dictBuffer = if dictBuffer.is_null() || dictBufferCapacity == 0 {
1604+
&mut []
1605+
} else {
1606+
core::slice::from_raw_parts_mut(dictBuffer.cast::<MaybeUninit<u8>>(), dictBufferCapacity)
1607+
};
1608+
15891609
let samplesSizes = if samplesSizes.is_null() || nbSamples == 0 {
15901610
&[]
15911611
} else {
@@ -1602,7 +1622,6 @@ pub unsafe extern "C" fn ZDICT_addEntropyTablesFromBuffer(
16021622
ZDICT_addEntropyTablesFromBuffer_advanced(
16031623
dictBuffer,
16041624
dictContentSize,
1605-
dictBufferCapacity,
16061625
samples,
16071626
samplesSizes,
16081627
params,

0 commit comments

Comments
 (0)