Skip to content

WIP feat: Implement StreamWriter and StructuredIrStreamWriter for IR data streaming (based on #74). #76

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

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
35b77c1
feat: Implement StreamWriter and StructuredIrStreamWriter for IR data…
junhaoliao Apr 20, 2025
3698837
chore: Update .gitmodules to reorder existing entries.
junhaoliao Apr 20, 2025
a6f2748
feat: Add support for msgpack serialization and zstd compression in S…
junhaoliao Apr 21, 2025
075ec8d
Update test.mjs to use new object structure
junhaoliao Apr 21, 2025
9a98e0c
refactor: Remove unused serialization tracking in StructuredIrStreamW…
junhaoliao Apr 21, 2025
9f7a5c0
refactor: Remove unused JS object encoding function from StructuredIr…
junhaoliao Apr 21, 2025
ea38b6b
refactor: Simplify memory view creation in write method of Structured…
junhaoliao Apr 21, 2025
559bfb1
refactor: Remove debug output from flush method in StructuredIrStream…
junhaoliao Apr 21, 2025
74b807b
refactor: Enhance StreamWriter to accept WriterOptions for compressio…
junhaoliao Apr 21, 2025
3e5ada2
refactor: Update StreamWriter documentation to correct writing direct…
junhaoliao Apr 21, 2025
238590b
refactor: Use const for packed_user_gen_handle_length and memoryView …
junhaoliao Apr 21, 2025
d3d0080
refactor: Remove unused Emscripten headers from StructuredIrStreamWriter
junhaoliao Apr 21, 2025
cea226d
refactor: Mark WebStreamWriter class as final to prevent inheritance
junhaoliao Apr 21, 2025
7b426ad
refactor: Remove TODO comment regarding configurable compression leve…
junhaoliao Apr 21, 2025
2bbd1e8
refactor: Update pre-js dependency and modify packing method in Struc…
junhaoliao Apr 21, 2025
e9112bf
refactor: Expect msgpack bytes in StructuredIrStreamWriter::write()
junhaoliao Apr 21, 2025
940f234
refactor: Move msgpackr to devDependencies and update import path in …
junhaoliao Apr 21, 2025
fd2c60f
Bind desiredSize to property
zzxthehappiest Apr 26, 2025
426d4ab
QAQ cannot keep going based on current codebase
zzxthehappiest Apr 27, 2025
931a9aa
Modify unit test code
zzxthehappiest Apr 24, 2025
f73ed33
Implement the desiredSize
zzxthehappiest Apr 26, 2025
88319f0
Expose last write promise
zzxthehappiest Apr 27, 2025
e2b36d4
Finish abort and unit test
zzxthehappiest Apr 28, 2025
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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ build
cmake-build-*
dist

# Node.js
node_modules
package-lock.json

# Generated lint configs
.clang-format
.clang-tidy

# IDEs
.idea
.vscode

# Apple
.DS_Store

# Test
test/clp-ffi-js
test/assets
9 changes: 6 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
[submodule "src/submodules/fmt"]
path = src/submodules/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "src/submodules/msgpack"]
path = src/submodules/msgpack
url = https://github.com/msgpack/msgpack-c.git
[submodule "src/submodules/spdlog"]
path = src/submodules/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "tools/yscope-dev-utils"]
path = tools/yscope-dev-utils
url = https://github.com/y-scope/yscope-dev-utils.git
[submodule "src/submodules/zstd"]
path = src/submodules/zstd
url = https://github.com/facebook/zstd.git
[submodule "tools/yscope-dev-utils"]
path = tools/yscope-dev-utils
url = https://github.com/y-scope/yscope-dev-utils.git
43 changes: 42 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,13 @@ set(CLP_FFI_JS_COMMON_COMPILE_OPTIONS
-fwasm-exceptions
)
set(CLP_FFI_JS_COMMON_LINK_OPTIONS
-fwasm-exceptions
# -fwasm-exceptions
-sALLOW_MEMORY_GROWTH
-sEXPORT_ES6
-sMAXIMUM_MEMORY=4GB
-sMODULARIZE
-sWASM_BIGINT
-sASYNCIFY=1
)
if(CMAKE_BUILD_TYPE MATCHES "Release")
list(APPEND CLP_FFI_JS_COMMON_COMPILE_OPTIONS
Expand All @@ -102,7 +103,9 @@ endif()

set(CLP_FFI_JS_SRC_MAIN
src/clp_ffi_js/ir/StreamReader.cpp
src/clp_ffi_js/ir/StreamWriter.cpp
src/clp_ffi_js/ir/StructuredIrStreamReader.cpp
src/clp_ffi_js/ir/StructuredIrStreamWriter.cpp
src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp
src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp
)
Expand All @@ -119,6 +122,11 @@ set(CLP_FFI_JS_SRC_CLP_CORE
src/submodules/clp/components/core/src/clp/ReaderInterface.cpp
src/submodules/clp/components/core/src/clp/streaming_compression/zstd/Decompressor.cpp
src/submodules/clp/components/core/src/clp/TimestampPattern.cpp

src/submodules/clp/components/core/src/clp/ffi/ir_stream/Serializer.cpp
src/submodules/clp/components/core/src/clp/ffi/ir_stream/encoding_methods.cpp
src/submodules/clp/components/core/src/clp/ir/parsing.cpp
src/submodules/clp/components/core/src/clp/streaming_compression/zstd/Compressor.cpp
)

set(CLP_FFI_JS_SRC_FMT src/submodules/fmt/src/format.cc)
Expand All @@ -134,6 +142,19 @@ set(CLP_FFI_JS_SRC_ZSTD
src/submodules/zstd/lib/decompress/zstd_ddict.c
src/submodules/zstd/lib/decompress/zstd_decompress_block.c
src/submodules/zstd/lib/decompress/zstd_decompress.c

src/submodules/zstd/lib/compress/fse_compress.c
src/submodules/zstd/lib/compress/hist.c
src/submodules/zstd/lib/compress/huf_compress.c
src/submodules/zstd/lib/compress/zstd_compress.c
src/submodules/zstd/lib/compress/zstd_compress_literals.c
src/submodules/zstd/lib/compress/zstd_compress_sequences.c
src/submodules/zstd/lib/compress/zstd_compress_superblock.c
src/submodules/zstd/lib/compress/zstd_double_fast.c
src/submodules/zstd/lib/compress/zstd_fast.c
src/submodules/zstd/lib/compress/zstd_lazy.c
src/submodules/zstd/lib/compress/zstd_ldm.c
src/submodules/zstd/lib/compress/zstd_opt.c
)

set(CLP_FFI_JS_SUPPORTED_ENVIRONMENTS
Expand Down Expand Up @@ -183,6 +204,7 @@ Link options: ${CLP_FFI_JS_LINK_OPTIONS}."
src/submodules/clp/components/core/src/clp
src/submodules/clp/components/core/submodules
src/submodules/fmt/include
src/submodules/msgpack/include
src/submodules/spdlog/include
src/submodules/zstd/lib
)
Expand All @@ -198,3 +220,22 @@ Link options: ${CLP_FFI_JS_LINK_OPTIONS}."
${CLP_FFI_JS_SRC_ZSTD}
)
endforeach()

# Copy final JS and WASM outputs to the test directory
foreach(env ${CLP_FFI_JS_SUPPORTED_ENVIRONMENTS})
set(bin_name "ClpFfiJs-${env}")
set(js_output "${CMAKE_CURRENT_BINARY_DIR}/${bin_name}.js")
set(wasm_output "${CMAKE_CURRENT_BINARY_DIR}/${bin_name}.wasm")
set(tsd_output "${CMAKE_CURRENT_BINARY_DIR}/${bin_name}.d.ts")
set(test_output_dir "${CMAKE_CURRENT_SOURCE_DIR}/test/clp-ffi-js")

add_custom_command(
TARGET ${bin_name}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${test_output_dir}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${js_output} ${test_output_dir}/${bin_name}.js
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${wasm_output} ${test_output_dir}/${bin_name}.wasm
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${tsd_output} ${test_output_dir}/${bin_name}.d.ts
COMMENT "Copying ${bin_name} build output to test/clp-ffi-js directory"
)
endforeach()
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"import": "./dist/ClpFfiJs-worker.js",
"types": "./dist/ClpFfiJs-worker.d.ts"
}
},
"devDependencies": {
"msgpackr": "^1.11.2"
}
}
32 changes: 32 additions & 0 deletions src/clp_ffi_js/ir/StreamWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <emscripten/bind.h>
#include <emscripten/val.h>

#include <clp_ffi_js/ir/StreamWriter.hpp>
#include <clp_ffi_js/ir/StructuredIrStreamWriter.hpp>

namespace {
EMSCRIPTEN_BINDINGS(ClpStreamWriter) {
// JS types used as inputs
emscripten::register_type<clp_ffi_js::ir::WriterOptions>("{compressionLevel: number | undefined}");

// JS types used as outputs

emscripten::class_<clp_ffi_js::ir::StreamWriter>("StreamWriter")
.constructor(
&clp_ffi_js::ir::StreamWriter::create,
emscripten::return_value_policy::take_ownership()
)
.function("abort", &clp_ffi_js::ir::StreamWriter::abort)
.function("write", &clp_ffi_js::ir::StreamWriter::write)
.function("close", &clp_ffi_js::ir::StreamWriter::close)
.function("getLastWritePromise",
&clp_ffi_js::ir::StreamWriter::get_last_write_promise)
.property("desiredSize", &clp_ffi_js::ir::StreamWriter::get_desired_size);
}
} // namespace

namespace clp_ffi_js::ir {
auto StreamWriter::create(emscripten::val const& stream, WriterOptions const& writer_options) -> std::unique_ptr<StreamWriter> {
return std::make_unique<StructuredIrStreamWriter>(stream, writer_options);
}
} // namespace clp_ffi_js::ir
77 changes: 77 additions & 0 deletions src/clp_ffi_js/ir/StreamWriter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef CLP_FFI_JS_IR_STREAMWRITER_HPP
#define CLP_FFI_JS_IR_STREAMWRITER_HPP

#include <clp/ffi/ir_stream/Serializer.hpp>
#include <clp/ir/types.hpp>
#include <emscripten/val.h>

namespace clp_ffi_js::ir {
// JS types used as inputs
EMSCRIPTEN_DECLARE_VAL_TYPE(WriterOptions);

class StreamWriter {
public:
using ClpIrSerializer = clp::ffi::ir_stream::Serializer<clp::ir::four_byte_encoded_variable_t>;
using BufferView = ClpIrSerializer::BufferView;

/**
* Creates a `StreamWriter` to write to a give string.
*
* @return The created instance.
* @throw ClpFfiJsException if any error occurs.
*/
[[nodiscard]] static auto
create(emscripten::val const& stream, WriterOptions const& writer_options)
-> std::unique_ptr<StreamWriter>;

// Delete copy & move constructors and assignment operators
StreamWriter(StreamWriter const&) = delete;
StreamWriter(StreamWriter&&) = delete;
auto operator=(StreamWriter const&) -> StreamWriter& = delete;
auto operator=(StreamWriter&&) -> StreamWriter& = delete;

// Destructor
virtual ~StreamWriter() = default;

/**
* FIXME: consider separation.
* Writes a passed chunk of data to a WritableStream and its underlying sink.
*/
virtual auto write(emscripten::val chunk) -> void = 0;

/**
* FIXME: look into integrating this with `WritableStreamDefaultWriter.ready`
* Flushes the underlying IR buffer and `m_output_stream`.
*/
virtual auto flush() -> void = 0;

/**
* Closes the serializer by writing the buffered results into the output
* stream with end-of-stream IR Unit appended in the end.
* @return true on success.
* @return false on failure.
*/
virtual auto close() -> void = 0;

/**
* Abort any ongoing writing and invalidate the serializer.
* @param reason
* @return a promise.
*/
virtual auto abort(emscripten::val reason) -> emscripten::val = 0;

/**
* Get the desiredSize property from the writer
* @return desiredSize
*/
virtual auto get_desired_size() const -> const int& = 0;

virtual auto get_last_write_promise() -> emscripten::val = 0;

protected:
// TODO: add docs
StreamWriter() = default;
};
} // namespace clp_ffi_js::ir

#endif // CLP_FFI_JS_IR_STREAMWRITER_HPP
Loading
Loading