pitrou commented on code in PR #38799:
URL: https://github.com/apache/arrow/pull/38799#discussion_r1399618165
##########
dev/archery/archery/integration/tester_rust.py:
##########
@@ -117,3 +128,102 @@ def flight_request(self, port, json_path=None,
scenario_name=None):
if self.debug:
log(' '.join(cmd))
run_cmd(cmd)
+
+ def make_c_data_exporter(self):
+ return RustCDataExporter(self.debug, self.args)
+
+ def make_c_data_importer(self):
+ return RustCDataImporter(self.debug, self.args)
+
+
+_rust_c_data_entrypoints = """
+ const char* arrow_rs_cdata_integration_export_schema_from_json(
+ const char* json_path, uintptr_t out);
+ const char* arrow_rs_cdata_integration_import_schema_and_compare_to_json(
+ const char* json_path, uintptr_t c_schema);
+
+ const char* arrow_rs_cdata_integration_export_batch_from_json(
+ const char* json_path, int num_batch, uintptr_t out);
+ const char* arrow_rs_cdata_integration_import_batch_and_compare_to_json(
+ const char* json_path, int num_batch, uintptr_t c_array);
+
+ void arrow_rs_free_error(const char*);
+ """
+
+
[email protected]_cache
+def _load_ffi(ffi, lib_path=_INTEGRATION_DLL):
+ ffi.cdef(_rust_c_data_entrypoints)
+ dll = ffi.dlopen(lib_path)
+ return dll
+
+
+class _CDataBase:
+
+ def __init__(self, debug, args):
+ self.debug = debug
+ self.args = args
+ self.ffi = cdata.ffi()
+ self.dll = _load_ffi(self.ffi)
+
+ def _pointer_to_int(self, c_ptr):
+ return self.ffi.cast('uintptr_t', c_ptr)
+
+ def _check_rust_error(self, rs_error):
+ """
+ Check a `const char*` error return from an integration entrypoint.
+
+ A null means success, a non-empty string is an error message.
+ The string is dynamically allocated on the Rust side.
+ """
+ assert self.ffi.typeof(rs_error) is self.ffi.typeof("const char*")
+ if rs_error != self.ffi.NULL:
+ try:
+ error = self.ffi.string(rs_error).decode(
+ 'utf8', errors='replace')
+ raise RuntimeError(
+ f"Rust C Data Integration call failed: {error}")
+ finally:
+ self.dll.arrow_rs_free_error(rs_error)
+
+
+class RustCDataExporter(CDataExporter, _CDataBase):
+
+ def export_schema_from_json(self, json_path, c_schema_ptr):
+ rs_error = self.dll.arrow_rs_cdata_integration_export_schema_from_json(
+ str(json_path).encode(), self._pointer_to_int(c_schema_ptr))
+ self._check_rust_error(rs_error)
+
+ def export_batch_from_json(self, json_path, num_batch, c_array_ptr):
+ rs_error = self.dll.arrow_rs_cdata_integration_export_batch_from_json(
+ str(json_path).encode(), num_batch,
+ self._pointer_to_int(c_array_ptr))
+ self._check_rust_error(rs_error)
+
+ @property
+ def supports_releasing_memory(self):
+ return True
+
+ def record_allocation_state(self):
+ # FIXME is it possible to measure the amount of Rust-allocated memory?
Review Comment:
I think we can open an issue, though this depends on Rust exposing
appropriate primitives:
https://github.com/apache/arrow-rs/pull/5080#issuecomment-1814225737
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]