cudf-cxx 0.2.0

cxx-based FFI bridge between Rust and NVIDIA libcudf C++ API
Documentation
#pragma once

#include <cudf/table/table.hpp>
#include <cudf/table/table_view.hpp>
#include <cudf/copying.hpp>
#include <cudf/io/types.hpp>
#include <memory>
#include <string>
#include <vector>
#include "rust/cxx.h"
#include "column_shim.h"

namespace cudf_shims {

/// Owning wrapper around std::unique_ptr<cudf::table>.
struct OwnedTable {
    std::unique_ptr<cudf::table> inner;
    // Populated lazily on first release_column call.
    std::vector<std::unique_ptr<cudf::column>> released_columns;
    bool released = false;

    explicit OwnedTable(std::unique_ptr<cudf::table> tbl)
        : inner(std::move(tbl)) {}

    int32_t num_columns() const {
        if (released) return static_cast<int32_t>(released_columns.size());
        return inner->num_columns();
    }
    int32_t num_rows() const {
        if (released) return 0;
        return inner->view().num_rows();
    }

    cudf::table_view view() const {
        if (released) throw std::runtime_error("table already released");
        return inner->view();
    }

    /// Release all columns from the table into the released_columns vector.
    /// Safe to call multiple times (idempotent).
    void ensure_released() {
        if (!released) {
            released_columns = inner->release();
            released = true;
        }
    }
};

/// Owning wrapper around a table + column name metadata from IO readers.
struct OwnedTableWithMetadata {
    std::unique_ptr<cudf::table> table;
    std::vector<std::string> column_names;

    OwnedTableWithMetadata(std::unique_ptr<cudf::table> tbl,
                           std::vector<std::string> names)
        : table(std::move(tbl)), column_names(std::move(names)) {}

    int32_t num_columns() const {
        return static_cast<int32_t>(column_names.size());
    }
};

/// Builder for constructing a table column-by-column.
/// Avoids passing Vec<UniquePtr<T>> across the cxx boundary.
struct TableBuilder {
    std::vector<std::unique_ptr<cudf::column>> columns;

    void add_column(std::unique_ptr<OwnedColumn> col) {
        if (!col) {
            throw std::runtime_error("Null column pointer in TableBuilder::add_column");
        }
        columns.push_back(std::move(col->inner));
    }

    std::unique_ptr<OwnedTable> build() {
        auto table = std::make_unique<cudf::table>(std::move(columns));
        columns.clear();
        return std::make_unique<OwnedTable>(std::move(table));
    }
};

// ── Construction ───────────────────────────────────────────────

/// Create a new table builder.
std::unique_ptr<TableBuilder> table_builder_new();

// ── Column access ──────────────────────────────────────────────

/// Get a copy of a single column from the table.
std::unique_ptr<OwnedColumn> table_get_column(
    const OwnedTable& table, int32_t index);

/// Release a single column by index (extracts it from the underlying table).
std::unique_ptr<OwnedColumn> table_release_column(
    OwnedTable& table, int32_t index);

// ── TableWithMetadata accessors ────────────────────────────────

/// Number of columns in the metadata wrapper.
int32_t table_meta_num_columns(const OwnedTableWithMetadata& meta);

/// Get the column name at a given index.
rust::String table_meta_column_name(const OwnedTableWithMetadata& meta, int32_t index);

/// Extract the inner table, consuming the metadata wrapper.
std::unique_ptr<OwnedTable> table_meta_into_table(std::unique_ptr<OwnedTableWithMetadata> meta);

} // namespace cudf_shims