Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: implement FFI for manifest, picklist and selection in Rust #2726

Draft
wants to merge 1 commit into
base: latest
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions include/sourmash.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ enum HashFunctions {
};
typedef uint32_t HashFunctions;

enum PickStyle {
PICK_STYLE_INCLUDE = 1,
PICK_STYLE_EXCLUDE = 2,
};
typedef uint32_t PickStyle;

enum SourmashErrorCode {
SOURMASH_ERROR_CODE_NO_ERROR = 0,
SOURMASH_ERROR_CODE_PANIC = 1,
Expand Down Expand Up @@ -53,14 +59,24 @@ typedef struct SourmashHyperLogLog SourmashHyperLogLog;

typedef struct SourmashKmerMinHash SourmashKmerMinHash;

typedef struct SourmashManifest SourmashManifest;

typedef struct SourmashManifestRowIter SourmashManifestRowIter;

typedef struct SourmashNodegraph SourmashNodegraph;

typedef struct SourmashPicklist SourmashPicklist;

typedef struct SourmashRevIndex SourmashRevIndex;

typedef struct SourmashSearchResult SourmashSearchResult;

typedef struct SourmashSelection SourmashSelection;

typedef struct SourmashSignature SourmashSignature;

typedef struct SourmashSignatureIter SourmashSignatureIter;

typedef struct SourmashZipStorage SourmashZipStorage;

/**
Expand All @@ -81,6 +97,15 @@ typedef struct {
bool owned;
} SourmashStr;

typedef struct {
uint32_t ksize;
bool with_abundance;
SourmashStr md5;
SourmashStr internal_location;
SourmashStr name;
SourmashStr moltype;
} SourmashManifestRow;

bool computeparams_dayhoff(const SourmashComputeParameters *ptr);

bool computeparams_dna(const SourmashComputeParameters *ptr);
Expand Down Expand Up @@ -267,6 +292,10 @@ void kmerminhash_slice_free(uint64_t *ptr, uintptr_t insize);

bool kmerminhash_track_abundance(const SourmashKmerMinHash *ptr);

SourmashManifestRowIter *manifest_rows(const SourmashManifest *ptr);

const SourmashManifestRow *manifest_rows_iter_next(SourmashManifestRowIter *ptr);

void nodegraph_buffer_free(uint8_t *ptr, uintptr_t insize);

bool nodegraph_count(SourmashNodegraph *ptr, uint64_t h);
Expand Down Expand Up @@ -311,6 +340,18 @@ SourmashNodegraph *nodegraph_with_tables(uintptr_t ksize,
uintptr_t starting_size,
uintptr_t n_tables);

void picklist_free(SourmashPicklist *ptr);

SourmashPicklist *picklist_new(void);

void picklist_set_coltype(SourmashPicklist *ptr, const char *coltype_ptr, uintptr_t insize);

void picklist_set_column_name(SourmashPicklist *ptr, const char *prop_ptr, uintptr_t insize);

void picklist_set_pickfile(SourmashPicklist *ptr, const char *prop_ptr, uintptr_t insize);

void picklist_set_pickstyle(SourmashPicklist *ptr, PickStyle pickstyle);

void revindex_free(SourmashRevIndex *ptr);

const SourmashSearchResult *const *revindex_gather(const SourmashRevIndex *ptr,
Expand Down Expand Up @@ -356,6 +397,36 @@ double searchresult_score(const SourmashSearchResult *ptr);

SourmashSignature *searchresult_signature(const SourmashSearchResult *ptr);

bool selection_abund(const SourmashSelection *ptr);

bool selection_containment(const SourmashSelection *ptr);

uint32_t selection_ksize(const SourmashSelection *ptr);

HashFunctions selection_moltype(const SourmashSelection *ptr);

SourmashSelection *selection_new(void);

uint32_t selection_num(const SourmashSelection *ptr);

const SourmashPicklist *selection_picklist(const SourmashSelection *ptr);

uint32_t selection_scaled(const SourmashSelection *ptr);

void selection_set_abund(SourmashSelection *ptr, bool new_abund);

void selection_set_containment(SourmashSelection *ptr, bool new_containment);

void selection_set_ksize(SourmashSelection *ptr, uint32_t new_ksize);

void selection_set_moltype(SourmashSelection *ptr, HashFunctions new_moltype);

void selection_set_num(SourmashSelection *ptr, uint32_t new_num);

void selection_set_picklist(SourmashSelection *ptr, SourmashPicklist *new_picklist);

void selection_set_scaled(SourmashSelection *ptr, uint32_t new_scaled);

void signature_add_protein(SourmashSignature *ptr, const char *sequence);

void signature_add_sequence(SourmashSignature *ptr, const char *sequence, bool force);
Expand Down Expand Up @@ -390,6 +461,8 @@ void signature_set_mh(SourmashSignature *ptr, const SourmashKmerMinHash *other);

void signature_set_name(SourmashSignature *ptr, const char *name);

const SourmashSignature *signatures_iter_next(SourmashSignatureIter *ptr);

SourmashSignature **signatures_load_buffer(const char *ptr,
uintptr_t insize,
bool _ignore_md5sum,
Expand Down
166 changes: 166 additions & 0 deletions src/core/src/ffi/index/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
#[cfg(feature = "branchwater")]
pub mod revindex;

use crate::ffi::HashFunctions;
use crate::selection::Selection;
use crate::storage::SigStore;

use crate::signature::Signature;

use crate::ffi::picklist::SourmashPicklist;
use crate::ffi::signature::SourmashSignature;
use crate::ffi::utils::{ForeignObject, SourmashStr};

Expand Down Expand Up @@ -37,3 +42,164 @@ pub unsafe extern "C" fn searchresult_signature(
let result = SourmashSearchResult::as_rust(ptr);
SourmashSignature::from_rust((result.1).clone())
}

//================================================================

pub struct SourmashSelection;

impl ForeignObject for SourmashSelection {
type RustObject = Selection;
}

#[no_mangle]
pub unsafe extern "C" fn selection_new() -> *mut SourmashSelection {
SourmashSelection::from_rust(Selection::default())
}

#[no_mangle]
pub unsafe extern "C" fn selection_ksize(ptr: *const SourmashSelection) -> u32 {
let sel = SourmashSelection::as_rust(ptr);
if let Some(ksize) = sel.ksize() {
ksize
} else {
todo!("empty ksize case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_ksize(ptr: *mut SourmashSelection, new_ksize: u32) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_ksize(new_ksize);
}

#[no_mangle]
pub unsafe extern "C" fn selection_num(ptr: *const SourmashSelection) -> u32 {
let sel = SourmashSelection::as_rust(ptr);
if let Some(num) = sel.num() {
num
} else {
todo!("empty num case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_num(ptr: *mut SourmashSelection, new_num: u32) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_num(new_num);
}

#[no_mangle]
pub unsafe extern "C" fn selection_scaled(ptr: *const SourmashSelection) -> u32 {
let sel = SourmashSelection::as_rust(ptr);
if let Some(scaled) = sel.scaled() {
scaled
} else {
todo!("empty scaled case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_scaled(ptr: *mut SourmashSelection, new_scaled: u32) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_scaled(new_scaled);
}

#[no_mangle]
pub unsafe extern "C" fn selection_containment(ptr: *const SourmashSelection) -> bool {
let sel = SourmashSelection::as_rust(ptr);
if let Some(containment) = sel.containment() {
containment
} else {
todo!("empty scaled case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_containment(
ptr: *mut SourmashSelection,
new_containment: bool,
) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_containment(new_containment);
}

#[no_mangle]
pub unsafe extern "C" fn selection_abund(ptr: *const SourmashSelection) -> bool {
let sel = SourmashSelection::as_rust(ptr);
if let Some(abund) = sel.abund() {
abund
} else {
todo!("empty abund case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_abund(ptr: *mut SourmashSelection, new_abund: bool) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_abund(new_abund);
}

#[no_mangle]
pub unsafe extern "C" fn selection_moltype(ptr: *const SourmashSelection) -> HashFunctions {
let sel = SourmashSelection::as_rust(ptr);
if let Some(hash_function) = sel.moltype() {
hash_function.into()
} else {
todo!("empty hash_function case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_moltype(
ptr: *mut SourmashSelection,
new_moltype: HashFunctions,
) {
let sel = SourmashSelection::as_rust_mut(ptr);
sel.set_moltype(new_moltype.into());
}

#[no_mangle]
pub unsafe extern "C" fn selection_picklist(
ptr: *const SourmashSelection,
) -> *const SourmashPicklist {
let sel = SourmashSelection::as_rust(ptr);
if let Some(picklist) = sel.picklist() {
SourmashPicklist::from_rust(picklist)
} else {
todo!("empty picklist case not supported yet")
}
}

#[no_mangle]
pub unsafe extern "C" fn selection_set_picklist(
ptr: *mut SourmashSelection,
new_picklist: *mut SourmashPicklist,
) {
let sel = SourmashSelection::as_rust_mut(ptr);
let pick = SourmashPicklist::into_rust(new_picklist);
sel.set_picklist(*pick);
}

//================================================================
//
pub struct SignatureIterator {
iter: Box<dyn Iterator<Item = SigStore>>,
}

pub struct SourmashSignatureIter;

impl ForeignObject for SourmashSignatureIter {
type RustObject = SignatureIterator;
}

#[no_mangle]
pub unsafe extern "C" fn signatures_iter_next(
ptr: *mut SourmashSignatureIter,
) -> *const SourmashSignature {
let iterator = SourmashSignatureIter::as_rust_mut(ptr);

match iterator.iter.next() {
Some(sig) => SourmashSignature::from_rust(sig.into()),
None => std::ptr::null(),
}
}
68 changes: 68 additions & 0 deletions src/core/src/ffi/manifest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::manifest::{Manifest, Record};

use crate::ffi::utils::{ForeignObject, SourmashStr};

pub struct SourmashManifest;

impl ForeignObject for SourmashManifest {
type RustObject = Manifest;
}

pub struct ManifestRowIterator {
iter: Box<dyn Iterator<Item = &'static Record>>,
}

pub struct SourmashManifestRowIter;

impl ForeignObject for SourmashManifestRowIter {
type RustObject = ManifestRowIterator;
}

#[no_mangle]
pub unsafe extern "C" fn manifest_rows_iter_next(
ptr: *mut SourmashManifestRowIter,
) -> *const SourmashManifestRow {
let iterator = SourmashManifestRowIter::as_rust_mut(ptr);

match iterator.iter.next() {
Some(row) => SourmashManifestRow::from_rust(row.into()),
None => std::ptr::null(),
}
}

#[no_mangle]
pub unsafe extern "C" fn manifest_rows(
ptr: *const SourmashManifest,
) -> *mut SourmashManifestRowIter {
let manifest = SourmashManifest::as_rust(ptr);

let iter = Box::new(manifest.iter());
SourmashManifestRowIter::from_rust(ManifestRowIterator { iter })
}

#[repr(C)]
pub struct SourmashManifestRow {
pub ksize: u32,
pub with_abundance: bool,
pub md5: SourmashStr,
pub internal_location: SourmashStr,
pub name: SourmashStr,
pub moltype: SourmashStr,
}

impl ForeignObject for SourmashManifestRow {
type RustObject = SourmashManifestRow;
}

impl From<&Record> for SourmashManifestRow {
fn from(record: &Record) -> SourmashManifestRow {
Self {
ksize: *record.ksize(),
with_abundance: *record.with_abundance(),
md5: record.md5().clone().into(),
name: record.name().clone().into(),
moltype: record.moltype().to_string().into(),
internal_location: record.internal_location().to_string().into(),
}
}
}
2 changes: 2 additions & 0 deletions src/core/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ pub mod utils;
pub mod cmd;
pub mod hyperloglog;
pub mod index;
pub mod manifest;
pub mod minhash;
pub mod nodegraph;
pub mod picklist;
pub mod signature;
pub mod storage;

Expand Down
Loading