##// END OF EJS Templates
rust-mixed-index: move the mmap keepalive into a function...
Raphaël Gomès -
r52080:8c4e8d06 default
parent child Browse files
Show More
@@ -314,6 +314,44 b' py_class!(pub class MixedIndex |py| {'
314
314
315 });
315 });
316
316
317 /// Take a (potentially) mmap'ed buffer, and return the underlying Python
318 /// buffer along with the Rust slice into said buffer. We need to keep the
319 /// Python buffer around, otherwise we'd get a dangling pointer once the buffer
320 /// is freed from Python's side.
321 ///
322 /// # Safety
323 ///
324 /// The caller must make sure that the buffer is kept around for at least as
325 /// long as the slice.
326 #[deny(unsafe_op_in_unsafe_fn)]
327 unsafe fn mmap_keeparound(
328 py: Python,
329 data: PyObject,
330 ) -> PyResult<(
331 PyBuffer,
332 Box<dyn std::ops::Deref<Target = [u8]> + Send + 'static>,
333 )> {
334 let buf = PyBuffer::get(py, &data)?;
335 let len = buf.item_count();
336
337 // Build a slice from the mmap'ed buffer data
338 let cbuf = buf.buf_ptr();
339 let bytes = if std::mem::size_of::<u8>() == buf.item_size()
340 && buf.is_c_contiguous()
341 && u8::is_compatible_format(buf.format())
342 {
343 unsafe { std::slice::from_raw_parts(cbuf as *const u8, len) }
344 } else {
345 return Err(PyErr::new::<ValueError, _>(
346 py,
347 "Nodemap data buffer has an invalid memory representation"
348 .to_string(),
349 ));
350 };
351
352 Ok((buf, Box::new(bytes)))
353 }
354
317 impl MixedIndex {
355 impl MixedIndex {
318 fn new(py: Python, cindex: PyObject) -> PyResult<MixedIndex> {
356 fn new(py: Python, cindex: PyObject) -> PyResult<MixedIndex> {
319 Self::create_instance(
357 Self::create_instance(
@@ -427,29 +465,12 b' impl MixedIndex {'
427 docket: PyObject,
465 docket: PyObject,
428 nm_data: PyObject,
466 nm_data: PyObject,
429 ) -> PyResult<PyObject> {
467 ) -> PyResult<PyObject> {
430 let buf = PyBuffer::get(py, &nm_data)?;
468 // Safety: we keep the buffer around inside the class as `nodemap_mmap`
469 let (buf, bytes) = unsafe { mmap_keeparound(py, nm_data)? };
431 let len = buf.item_count();
470 let len = buf.item_count();
432
433 // Build a slice from the mmap'ed buffer data
434 let cbuf = buf.buf_ptr();
435 let bytes = if std::mem::size_of::<u8>() == buf.item_size()
436 && buf.is_c_contiguous()
437 && u8::is_compatible_format(buf.format())
438 {
439 unsafe { std::slice::from_raw_parts(cbuf as *const u8, len) }
440 } else {
441 return Err(PyErr::new::<ValueError, _>(
442 py,
443 "Nodemap data buffer has an invalid memory representation"
444 .to_string(),
445 ));
446 };
447
448 // Keep a reference to the mmap'ed buffer, otherwise we get a dangling
449 // pointer.
450 self.nodemap_mmap(py).borrow_mut().replace(buf);
471 self.nodemap_mmap(py).borrow_mut().replace(buf);
451
472
452 let mut nt = NodeTree::load_bytes(Box::new(bytes), len);
473 let mut nt = NodeTree::load_bytes(bytes, len);
453
474
454 let data_tip = docket
475 let data_tip = docket
455 .getattr(py, "tip_rev")?
476 .getattr(py, "tip_rev")?
General Comments 0
You need to be logged in to leave comments. Login now