Skip to content

Commit

Permalink
wasm interface: remove get_file hack, pass File directly
Browse files Browse the repository at this point in the history
also add timing information in debug mode
  • Loading branch information
DesmondWillowbrook committed Jan 21, 2024
1 parent 9623c83 commit 4d16059
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
4 changes: 1 addition & 3 deletions frontend/js/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ onmessage = async function(e) {
let result = [];
let res;
for (let file of files) {
// for communication with exported function 'get_file'
self.readFile = file;
console.debug(file)

try {
res = JSON.parse(wasm.run_json_exported("application/x-gzip" == file.type || "application/gzip" == file.type));
res = JSON.parse(wasm.run_json_exported(file));
// the server depends on the 'name' field to be present
res['name'] = file['name']; // retrieve the sample name
result.push(res);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/extract_comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use crate::{io_utils::get_reader, utils::set_panic_hook};

// Entry points here
#[wasm_bindgen]
pub fn run_json_exported(compressed: bool) -> String {
pub fn run_json_exported(f: web_sys::File) -> String {
set_panic_hook();

let fastq_reader = FASTQReader::new(SampleArgs::default(), get_reader(compressed));
let fastq_reader = FASTQReader::new(SampleArgs::default(), get_reader(f.into()));
run_json(fastq_reader)
}
56 changes: 38 additions & 18 deletions frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,60 @@ pub mod io_utils {
use wasm_bindgen::prelude::*;
use web_sys::FileReaderSync;

#[wasm_bindgen(module = "/js/exports.js")]
extern "C" {
pub fn get_file() -> web_sys::File;
}

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
pub fn debug(msg: &str);

#[cfg(debug_assertions)]
// get js time
#[wasm_bindgen(js_namespace = Date, js_name = now)]
pub fn now() -> f64;
}
use std::io::{self, BufRead, Read};
use std::io::{self, BufReader, Read};

// Credit to: mstange on GitHub
// See: https://github.com/rustwasm/wasm-bindgen/issues/1079#issuecomment-508577627
#[derive(Debug)]
pub struct WasmMemBuffer {
pub struct JSFileReader {
pos: u64,
file_reader: FileReaderSync,
file: File,

#[cfg(debug_assertions)]
thresh: u64,
#[cfg(debug_assertions)]
time_start: f64,
}

#[allow(clippy::new_without_default)]
impl WasmMemBuffer {
pub fn new() -> WasmMemBuffer {
WasmMemBuffer {
file: File::from(unsafe { get_file() }),
impl JSFileReader {
pub fn new(f: File) -> JSFileReader {
JSFileReader {
pos: 0,
file_reader: FileReaderSync::new().unwrap(),
file: f,
#[cfg(debug_assertions)]
time_start: now(),
#[cfg(debug_assertions)]
thresh: 0,
}
}
}

impl Read for WasmMemBuffer {
impl Read for JSFileReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let fr = FileReaderSync::new().unwrap();
let sl = self.file.slice(self.pos, self.pos + buf.len() as u64);
let arr = Uint8Array::new(unsafe { &fr.read_as_array_buffer(sl.as_ref()).unwrap() });
let arr = Uint8Array::new(&self.file_reader.read_as_array_buffer(sl.as_ref()).unwrap());
let len = std::cmp::min(buf.len(), arr.length() as usize);

#[cfg(debug_assertions)] {
self.thresh += len as u64;
if self.thresh > 100_000_000 {
let new_time = now();
debug(format!("Read {} bytes, {} elapsed", self.thresh, new_time - self.time_start).as_str());
self.thresh = 0;
}
}

arr.slice(0, len as u32).copy_to(&mut buf[..len]);

self.pos += len as u64;
Expand All @@ -62,9 +79,12 @@ pub mod io_utils {

// Reader is a wrapper over BufRead
// And provides an interface over the actual reading.
pub fn get_reader(compressed: bool) -> Box<dyn BufRead> {
pub fn get_reader(file: File) -> BufReader<Box<dyn Read>> {
let typ = file.raw_mime_type();
let compressed = typ == "application/gzip" || typ == "application/x-gzip";

fastq2comp::io_utils::compressed_reader(
Box::new(WasmMemBuffer::new()) as Box<dyn Read>,
Box::new(JSFileReader::new(file)) as Box<dyn Read>,
compressed,
)
}
Expand Down

0 comments on commit 4d16059

Please sign in to comment.