#include <memory>
#include <vector>
#include <string>
#include <utility>
#include <cstring>
#include "../../../agc/src/core/agc_compressor.h"
#include "../../../agc/src/common/lz_diff.h"
#include "agc_compressor_rust.h"
extern "C" {
struct AgcCompressParams {
const char* out_archive_name;
uint32_t pack_cardinality; uint32_t kmer_length; const char* reference_file; uint32_t segment_size; uint32_t min_match_length; bool concatenated_genomes; bool adaptive_compression; uint32_t verbosity; uint32_t no_threads; double fallback_frac; };
struct AgcSampleFile {
const char* sample_name;
const char* file_path;
};
bool agc_compress_create(
const AgcCompressParams* params,
const AgcSampleFile* samples,
size_t n_samples
) {
if (!params || !samples || n_samples == 0) {
return false;
}
try {
CAGCCompressor compressor;
bool ok = compressor.Create(
std::string(params->out_archive_name),
params->pack_cardinality,
params->kmer_length,
std::string(params->reference_file),
params->segment_size,
params->min_match_length,
params->concatenated_genomes,
params->adaptive_compression,
params->verbosity,
params->no_threads,
params->fallback_frac
);
if (!ok) {
return false;
}
std::vector<std::pair<std::string, std::string>> v_sample_files;
v_sample_files.reserve(n_samples);
for (size_t i = 0; i < n_samples; ++i) {
v_sample_files.emplace_back(
std::string(samples[i].sample_name),
std::string(samples[i].file_path)
);
}
ok = compressor.AddSampleFiles(v_sample_files, params->no_threads);
if (!ok) {
return false;
}
ok = compressor.Close(params->no_threads);
return ok;
} catch (const std::exception& e) {
if (params->verbosity > 0) {
fprintf(stderr, "C++ AGC compression error: %s\n", e.what());
}
return false;
} catch (...) {
if (params->verbosity > 0) {
fprintf(stderr, "C++ AGC compression error: unknown exception\n");
}
return false;
}
}
bool agc_compress_create_with_rust_splitters(
const AgcCompressParams* params,
const AgcSampleFile* samples,
size_t n_samples
) {
if (!params || !samples || n_samples == 0) {
return false;
}
try {
CAGCCompressorRust compressor;
bool ok = compressor.CreateWithRustSplitters(
std::string(params->out_archive_name),
params->pack_cardinality,
params->kmer_length,
std::string(params->reference_file),
params->segment_size,
params->min_match_length,
params->concatenated_genomes,
params->adaptive_compression,
params->verbosity,
params->no_threads,
params->fallback_frac
);
if (!ok) {
return false;
}
std::vector<std::pair<std::string, std::string>> v_sample_files;
v_sample_files.reserve(n_samples);
for (size_t i = 0; i < n_samples; ++i) {
v_sample_files.emplace_back(
std::string(samples[i].sample_name),
std::string(samples[i].file_path)
);
}
ok = compressor.AddSampleFiles(v_sample_files, params->no_threads);
if (!ok) {
return false;
}
ok = compressor.Close(params->no_threads);
return ok;
} catch (const std::exception& e) {
if (params->verbosity > 0) {
fprintf(stderr, "[RAGC FORK] C++ AGC compression error: %s\n", e.what());
}
return false;
} catch (...) {
if (params->verbosity > 0) {
fprintf(stderr, "[RAGC FORK] C++ AGC compression error: unknown exception\n");
}
return false;
}
}
uint32_t agc_lzdiff_v2_estimate(
const uint8_t* ref, size_t ref_len,
const uint8_t* text, size_t text_len,
uint32_t min_match_len,
uint32_t bound
) {
if (!ref || !text || ref_len == 0 || text_len == 0) {
return UINT32_MAX;
}
CLZDiff_V2 lz(min_match_len);
contig_t reference_contig(ref, ref + ref_len);
lz.Prepare(reference_contig);
lz.AssureIndex();
contig_t text_contig(text, text + text_len);
size_t result = lz.Estimate(text_contig, bound);
return (uint32_t)result;
}
uint32_t agc_lzdiff_v2_encode(
const uint8_t* ref, size_t ref_len,
const uint8_t* text, size_t text_len,
uint32_t min_match_len,
uint8_t* out_buf, size_t out_buf_len
) {
if (!ref || !text || !out_buf || ref_len == 0 || text_len == 0) {
return UINT32_MAX;
}
CLZDiff_V2 lz(min_match_len);
contig_t reference_contig(ref, ref + ref_len);
lz.Prepare(reference_contig);
contig_t text_contig(text, text + text_len);
contig_t encoded;
lz.Encode(text_contig, encoded);
if (encoded.size() > out_buf_len) {
return UINT32_MAX; }
std::memcpy(out_buf, encoded.data(), encoded.size());
return (uint32_t)encoded.size();
}
}