Skip to content

Commit 0c17a99

Browse files
committed
modules/zstd: Add Buffer use-case example
This commit adds a simple test that shows, how one can use the Buffer struct inside a Proc. Internal-tag: [#50221] Signed-off-by: Robert Winkler <[email protected]>
1 parent 815eb8d commit 0c17a99

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

xls/modules/zstd/buffer.x

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,94 @@ pub fn buffer_new<BSIZE: u32>() -> Buffer<BSIZE> {
358358
fn test_buffer_new() {
359359
assert_eq(buffer_new<u32:32>(), Buffer { contents: u32:0, length: u32:0 });
360360
}
361+
362+
// Example use case
363+
//
364+
// The Buffer structure can be used to collect enough data that is required
365+
// for the next steps to proceed. The next steps may consume variable or
366+
// constant amount of data. In the simplest use-case scenario, one can use
367+
// it to combine smaller transactions into bigger ones.
368+
369+
type Buffer64 = Buffer<64>;
370+
371+
proc BufferExampleUsage {
372+
input_r: chan<u32> in;
373+
output_s: chan<u48> out;
374+
375+
config(
376+
input_r: chan<u32> in,
377+
output_s: chan<u48> out
378+
) { (input_r, output_s) }
379+
380+
init { Buffer64 { contents: u64:0, length: u32:0 } }
381+
382+
next(tok: token, buffer: Buffer64) {
383+
let (tok, recv_data) = recv(tok, input_r);
384+
let buffer = buffer_append<u32:64>(buffer, recv_data);
385+
386+
if buffer.length >= u32:48 {
387+
let (buffer, data_to_send) = buffer_sized_pop<u32:64, u32:48>(buffer);
388+
let tok = send(tok, output_s, data_to_send);
389+
buffer
390+
} else {
391+
buffer
392+
}
393+
}
394+
}
395+
396+
const NUMBER_OF_TESTED_TRANSACTIONS = u32:30;
397+
398+
struct BufferExampleUsageTestState {
399+
recv_count: u32,
400+
send_count: u32
401+
}
402+
403+
#[test_proc]
404+
proc BufferExampleUsageTest {
405+
terminator: chan<bool> out;
406+
data32_s: chan<u32> out;
407+
data48_r: chan<u48> in;
408+
409+
config(terminator: chan<bool> out) {
410+
let (data32_s, data32_r) = chan<u32>;
411+
let (data48_s, data48_r) = chan<u48>;
412+
spawn BufferExampleUsage(data32_r, data48_s);
413+
(terminator, data32_s, data48_r)
414+
}
415+
416+
init {
417+
BufferExampleUsageTestState {
418+
recv_count: u32:0,
419+
send_count: u32:0
420+
}
421+
}
422+
423+
next(tok: token, state: BufferExampleUsageTestState) {
424+
let data_to_send = match state.send_count % u32:3 {
425+
u32:0 => u32:0xDEADBEEF,
426+
u32:1 => u32:0xBEEFCAFE,
427+
u32:2 => u32:0xCAFEDEAD,
428+
_ => fail!("impossible_case", u32:0),
429+
};
430+
let tok = send(tok, data32_s, data_to_send);
431+
let send_count = state.send_count + u32:1;
432+
433+
let (tok, received_data, valid) = recv_non_blocking(tok, data48_r, u48:0);
434+
let recv_count = if valid {
435+
let recv_count = state.recv_count + u32:1;
436+
trace_fmt!("received data: {:#x}, recv_count {}, send_count {}",
437+
received_data, recv_count, send_count);
438+
assert_eq(received_data, u48:0xCAFE_DEAD_BEEF);
439+
recv_count
440+
} else {
441+
state.recv_count
442+
};
443+
444+
assert_eq(u32:32 * (send_count - u32:1) / u32:48, recv_count);
445+
446+
let do_send = (state.send_count == NUMBER_OF_TESTED_TRANSACTIONS - u32:1);
447+
send_if(tok, terminator, do_send, true);
448+
449+
BufferExampleUsageTestState { recv_count, send_count }
450+
}
451+
}

0 commit comments

Comments
 (0)