Skip to content

Commit 3d2126e

Browse files
author
a-ok123
committed
Update with create_metadata API
1 parent 8cae7b7 commit 3d2126e

File tree

12 files changed

+170
-56
lines changed

12 files changed

+170
-56
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@ go.work.sum
2525
.env
2626

2727
# IDEs
28-
.idea/
28+
.idea
29+
30+
test-client/main

include/rq-library.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ bool raptorq_free_session(uintptr_t session_id);
5454
* * -5 on invalid session
5555
* * -11 on IO error
5656
* * -12 on File not found
57-
* * -13 on Encoding failed
58-
* * -15 on Memory limit exceeded
59-
* * -16 on Concurrency limit reached
57+
* * -13 on Invalid path
58+
* * -14 on Encoding failed
59+
* * -16 on Memory limit exceeded
60+
* * -17 on Concurrency limit reached
6061
*/
6162
int32_t raptorq_create_metadata(uintptr_t session_id,
6263
const char *input_path,
63-
const char *output_dir,
64+
const char *layout_file,
6465
uintptr_t block_size,
65-
bool return_layout,
6666
char *result_buffer,
6767
uintptr_t result_buffer_len);
6868

@@ -87,9 +87,10 @@ int32_t raptorq_create_metadata(uintptr_t session_id,
8787
* * -5 on invalid session
8888
* * -11 on IO error
8989
* * -12 on File not found
90-
* * -13 on Encoding failed
91-
* * -15 on Memory limit exceeded
92-
* * -16 on Concurrency limit reached
90+
* * -13 on Invalid Path
91+
* * -14 on Encoding failed
92+
* * -16 on Memory limit exceeded
93+
* * -17 on Concurrency limit reached
9394
*/
9495
int32_t raptorq_encode_file(uintptr_t session_id,
9596
const char *input_path,
@@ -133,9 +134,10 @@ int32_t raptorq_get_last_error(uintptr_t session_id,
133134
* * -5 on invalid session
134135
* * -11 on IO error
135136
* * -12 on File not found
136-
* * -14 on Decoding failed
137-
* * -15 on Memory limit exceeded
138-
* * -16 on Concurrency limit reached
137+
* * -13 on Invalid Path
138+
* * -15 on Decoding failed
139+
* * -16 on Memory limit exceeded
140+
* * -17 on Concurrency limit reached
139141
*/
140142
int32_t raptorq_decode_symbols(uintptr_t session_id,
141143
const char *symbols_dir,

lib/darwin/amd64/librq_library.a

10.6 KB
Binary file not shown.

lib/darwin/amd64/librq_library.d

Lines changed: 0 additions & 1 deletion
This file was deleted.
31.7 KB
Binary file not shown.

lib/darwin/arm64/librq_library.a

20.5 MB
Binary file not shown.
549 KB
Binary file not shown.

raptorq.go

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package rq_go
1717
extern uintptr_t raptorq_init_session(uint16_t symbol_size, uint8_t redundancy_factor, uint64_t max_memory_mb, uint64_t concurrency_limit);
1818
extern _Bool raptorq_free_session(uintptr_t session_id);
1919
extern int32_t raptorq_encode_file(uintptr_t session_id, const char *input_path, const char *output_dir, uintptr_t block_size, char *result_buffer, uintptr_t result_buffer_len);
20-
extern int32_t raptorq_create_metadata(uintptr_t session_id, const char *input_path, const char *output_dir, uintptr_t block_size, bool return_layout, char *result_buffer, uintptr_t result_buffer_len);
20+
extern int32_t raptorq_create_metadata(uintptr_t session_id, const char *input_path, const char *layout_file, uintptr_t block_size, char *result_buffer, uintptr_t result_buffer_len);
2121
extern int32_t raptorq_get_last_error(uintptr_t session_id, char *error_buffer, uintptr_t error_buffer_len);
2222
extern int32_t raptorq_decode_symbols(uintptr_t session_id, const char *symbols_dir, const char *output_path, const char *layout_path);
2323
extern uintptr_t raptorq_get_recommended_block_size(uintptr_t session_id, uint64_t file_size);
@@ -210,15 +210,69 @@ func (p *RaptorQProcessor) EncodeFile(inputPath, outputDir string, blockSize int
210210
}
211211

212212
// CreateMetadata creates metadata for RaptorQ encoding without writing symbol data
213-
// If returnLayout is true, the layout content is returned in the result rather than written to a file
214-
//
215-
// This is a temporary implementation calling directly to the Rust library through CGO
216-
func (p *RaptorQProcessor) CreateMetadata(inputPath, outputDir string, blockSize int, returnLayout bool) (*ProcessResult, error) {
217-
// For now, this is a wrapper around EncodeFile
218-
// since we're experiencing CGO integration issues with the raptorq_create_metadata function
219-
//
220-
// TODO: Replace with direct call to raptorq_create_metadata when CGO integration is fixed
221-
return p.EncodeFile(inputPath, outputDir, blockSize)
213+
// It writes the layout information to the specified layout file
214+
func (p *RaptorQProcessor) CreateMetadata(inputPath, layoutFile string, blockSize int) (*ProcessResult, error) {
215+
if p.SessionID == 0 {
216+
return nil, fmt.Errorf("RaptorQ session is closed")
217+
}
218+
219+
cInputPath := C.CString(inputPath)
220+
defer C.free(unsafe.Pointer(cInputPath))
221+
222+
cLayoutFile := C.CString(layoutFile)
223+
defer C.free(unsafe.Pointer(cLayoutFile))
224+
225+
// Buffer for result (16KB should be enough for metadata)
226+
resultBufSize := 16 * 1024
227+
resultBuf := (*C.char)(C.malloc(C.size_t(resultBufSize)))
228+
defer C.free(unsafe.Pointer(resultBuf))
229+
230+
res := C.raptorq_create_metadata(
231+
C.uintptr_t(p.SessionID),
232+
cInputPath,
233+
cLayoutFile,
234+
C.uintptr_t(blockSize),
235+
resultBuf,
236+
C.uintptr_t(resultBufSize),
237+
)
238+
239+
switch res {
240+
case 0:
241+
// Success
242+
case -1:
243+
return nil, fmt.Errorf("generic error")
244+
case -2:
245+
return nil, fmt.Errorf("invalid parameters")
246+
case -3:
247+
return nil, fmt.Errorf("invalid response (JSON serialization error)")
248+
case -4:
249+
return nil, fmt.Errorf("result buffer too small")
250+
case -5:
251+
return nil, fmt.Errorf("invalid session")
252+
case -11:
253+
return nil, fmt.Errorf("IO error: %s", p.getLastError())
254+
case -12:
255+
return nil, fmt.Errorf("file not found: %s", p.getLastError())
256+
case -13:
257+
return nil, fmt.Errorf("invalid path: %s", p.getLastError())
258+
case -14:
259+
return nil, fmt.Errorf("encoding failed: %s", p.getLastError())
260+
case -16:
261+
return nil, fmt.Errorf("memory limit exceeded: %s", p.getLastError())
262+
case -17:
263+
return nil, fmt.Errorf("concurrency limit reached: %s", p.getLastError())
264+
default:
265+
return nil, fmt.Errorf("unknown error code %d: %s", res, p.getLastError())
266+
}
267+
268+
// Parse the JSON result
269+
resultJSON := C.GoString(resultBuf)
270+
var result ProcessResult
271+
if err := json.Unmarshal([]byte(resultJSON), &result); err != nil {
272+
return nil, fmt.Errorf("failed to parse result: %w", err)
273+
}
274+
275+
return &result, nil
222276
}
223277

224278
// DecodeSymbols decodes RaptorQ symbols back to the original file

raptorq_test.go

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ func TestSysErrorHandlingDecode(t *testing.T) {
581581
}
582582
}
583583

584-
// System test for creating metadata (without returning layout content)
584+
// System test for creating metadata
585585
func TestSysCreateMetadata(t *testing.T) {
586586
// Create RaptorQ processor with default settings
587587
processor, err := NewDefaultRaptorQProcessor()
@@ -598,33 +598,28 @@ func TestSysCreateMetadata(t *testing.T) {
598598
ctx := NewTestContext(t, 1024*1024) // 1MB file
599599
defer ctx.Cleanup()
600600

601-
// Create metadata without returning layout (save to file)
602-
res, err := processor.CreateMetadata(ctx.InputFile, ctx.SymbolsDir, 0, false)
601+
// Create layout file path
602+
layoutPath := filepath.Join(ctx.TempDir, "layout.json")
603+
604+
// Create metadata
605+
res, err := processor.CreateMetadata(ctx.InputFile, layoutPath, 0)
603606
if err != nil {
604607
t.Fatalf("Failed to create metadata: %v", err)
605608
}
606609

607610
// Verify the layout file exists
608-
layoutPath := res.LayoutFilePath
609611
if _, err := os.Stat(layoutPath); os.IsNotExist(err) {
610612
t.Fatalf("Layout file not found at %s", layoutPath)
611613
}
612614

613615
// Verify the result contains expected fields
614-
if res.SymbolsDirectory == "" {
615-
t.Fatal("Result should contain symbols_directory")
616-
}
617616
if res.LayoutFilePath == "" {
618617
t.Fatal("Result should contain layout_file_path")
619618
}
620619
}
621620

622-
// System test for creating metadata with layout content returned
623-
func TestSysCreateMetadataReturnLayout(t *testing.T) {
624-
// Note: Since our current implementation is a temporary wrapper around EncodeFile,
625-
// we can't fully test the returnLayout parameter yet. This test will need to be
626-
// updated when the full implementation is complete.
627-
621+
// System test for creating metadata with specific block size
622+
func TestSysCreateMetadataWithBlockSize(t *testing.T) {
628623
// Create RaptorQ processor with default settings
629624
processor, err := NewDefaultRaptorQProcessor()
630625
if err != nil {
@@ -637,22 +632,33 @@ func TestSysCreateMetadataReturnLayout(t *testing.T) {
637632
}()
638633

639634
// Create test context with input file
640-
ctx := NewTestContext(t, 1024*1024) // 1MB file
635+
ctx := NewTestContext(t, 5*1024*1024) // 5MB file
641636
defer ctx.Cleanup()
642637

643-
// Create metadata with returnLayout=true (currently uses the same code path)
644-
res, err := processor.CreateMetadata(ctx.InputFile, ctx.SymbolsDir, 0, true)
638+
// Create layout file path
639+
layoutPath := filepath.Join(ctx.TempDir, "layout_with_blocksize.json")
640+
641+
// Create metadata with specific block size
642+
blockSize := 1024 * 1024 // 1MB blocks
643+
res, err := processor.CreateMetadata(ctx.InputFile, layoutPath, blockSize)
645644
if err != nil {
646-
t.Fatalf("Failed to create metadata with returnLayout=true: %v", err)
645+
t.Fatalf("Failed to create metadata with specific block size: %v", err)
647646
}
648647

649-
// Verify the layout file exists (when full implementation is done, this should be skipped)
650-
layoutPath := res.LayoutFilePath
648+
// Verify the layout file exists
651649
if _, err := os.Stat(layoutPath); os.IsNotExist(err) {
652650
t.Fatalf("Layout file not found at %s", layoutPath)
653651
}
654652

655-
// TODO: When full implementation is complete, verify the result contains layout_content field
653+
// Verify the result contains expected fields
654+
if res.LayoutFilePath == "" {
655+
t.Fatal("Result should contain layout_file_path")
656+
}
657+
658+
// Verify the blocks information is present
659+
if len(res.Blocks) == 0 {
660+
t.Fatal("Result should contain blocks information")
661+
}
656662
}
657663

658664
// Go-specific test for FFI interactions
@@ -1112,20 +1118,22 @@ func BenchmarkCreateMetadata1MB(b *testing.B) {
11121118
ctx := setupBenchmarkEnv(b, SIZE_1MB)
11131119
defer ctx.Cleanup()
11141120

1121+
// Create layout file path
1122+
layoutPath := filepath.Join(ctx.TempDir, "layout.json")
1123+
11151124
// Reset timer before starting the benchmark loop
11161125
b.ResetTimer()
11171126

11181127
// Run the benchmark
11191128
for i := 0; i < b.N; i++ {
1120-
_, err := processor.CreateMetadata(ctx.InputFile, ctx.SymbolsDir, 0, false)
1129+
_, err := processor.CreateMetadata(ctx.InputFile, layoutPath, 0)
11211130
if err != nil {
11221131
b.Fatalf("Failed to create metadata: %v", err)
11231132
}
11241133

1125-
// Clean symbols directory for next iteration
1134+
// Remove layout file for next iteration
11261135
if i < b.N-1 {
1127-
os.RemoveAll(ctx.SymbolsDir)
1128-
os.MkdirAll(ctx.SymbolsDir, 0755)
1136+
os.Remove(layoutPath)
11291137
}
11301138
}
11311139
}
@@ -1147,20 +1155,22 @@ func BenchmarkCreateMetadata10MB(b *testing.B) {
11471155
ctx := setupBenchmarkEnv(b, SIZE_10MB)
11481156
defer ctx.Cleanup()
11491157

1158+
// Create layout file path
1159+
layoutPath := filepath.Join(ctx.TempDir, "layout_10mb.json")
1160+
11501161
// Reset timer before starting the benchmark loop
11511162
b.ResetTimer()
11521163

11531164
// Run the benchmark
11541165
for i := 0; i < b.N; i++ {
1155-
_, err := processor.CreateMetadata(ctx.InputFile, ctx.SymbolsDir, 0, true) // with returnLayout=true
1166+
_, err := processor.CreateMetadata(ctx.InputFile, layoutPath, 0)
11561167
if err != nil {
11571168
b.Fatalf("Failed to create metadata: %v", err)
11581169
}
11591170

1160-
// Clean symbols directory for next iteration
1171+
// Remove layout file for next iteration
11611172
if i < b.N-1 {
1162-
os.RemoveAll(ctx.SymbolsDir)
1163-
os.MkdirAll(ctx.SymbolsDir, 0755)
1173+
os.Remove(layoutPath)
11641174
}
11651175
}
11661176
}
@@ -1185,20 +1195,22 @@ func BenchmarkCreateMetadata100MB(b *testing.B) {
11851195
// Use block size for large file
11861196
blockSize := 5 * 1024 * 1024 // 5MB blocks
11871197

1198+
// Create layout file path
1199+
layoutPath := filepath.Join(ctx.TempDir, "layout_100mb.json")
1200+
11881201
// Reset timer before starting the benchmark loop
11891202
b.ResetTimer()
11901203

11911204
// Run the benchmark
11921205
for i := 0; i < b.N; i++ {
1193-
_, err := processor.CreateMetadata(ctx.InputFile, ctx.SymbolsDir, blockSize, false)
1206+
_, err := processor.CreateMetadata(ctx.InputFile, layoutPath, blockSize)
11941207
if err != nil {
11951208
b.Fatalf("Failed to create metadata: %v", err)
11961209
}
11971210

1198-
// Clean symbols directory for next iteration
1211+
// Remove layout file for next iteration
11991212
if i < b.N-1 {
1200-
os.RemoveAll(ctx.SymbolsDir)
1201-
os.MkdirAll(ctx.SymbolsDir, 0755)
1213+
os.Remove(layoutPath)
12021214
}
12031215
}
12041216
}

test-client/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ module main
22

33
go 1.21
44

5-
require github.com/LumeraProtocol/rq-go v0.1.0
5+
require github.com/LumeraProtocol/rq-go v0.0.0
6+
replace github.com/LumeraProtocol/rq-go => ../

0 commit comments

Comments
 (0)