Skip to content

Commit 9382127

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 09fd41f commit 9382127

File tree

1 file changed

+100
-37
lines changed

1 file changed

+100
-37
lines changed

xls/modules/zstd/buffer.x

Lines changed: 100 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import std
2626

2727
// Structure to hold the buffered data
2828
pub struct Buffer<CAPACITY: u32> {
29-
contents: bits[CAPACITY],
29+
content: bits[CAPACITY],
3030
length: u32
3131
}
3232

@@ -50,19 +50,19 @@ pub fn buffer_can_fit<CAPACITY: u32, DSIZE: u32>(buffer: Buffer<CAPACITY>, data:
5050

5151
#[test]
5252
fn test_buffer_can_fit() {
53-
let buffer = Buffer<u32:32> { contents: u32:0, length: u32:0 };
53+
let buffer = Buffer<u32:32> { content: u32:0, length: u32:0 };
5454
assert_eq(buffer_can_fit(buffer, bits[0]:0), true);
5555
assert_eq(buffer_can_fit(buffer, u16:0), true);
5656
assert_eq(buffer_can_fit(buffer, u32:0), true);
5757
assert_eq(buffer_can_fit(buffer, u33:0), false);
5858

59-
let buffer = Buffer<u32:32> { contents: u32:0, length: u32:16 };
59+
let buffer = Buffer<u32:32> { content: u32:0, length: u32:16 };
6060
assert_eq(buffer_can_fit(buffer, bits[0]:0), true);
6161
assert_eq(buffer_can_fit(buffer, u16:0), true);
6262
assert_eq(buffer_can_fit(buffer, u17:0), false);
6363
assert_eq(buffer_can_fit(buffer, u32:0), false);
6464

65-
let buffer = Buffer<u32:32> { contents: u32:0, length: u32:32 };
65+
let buffer = Buffer<u32:32> { content: u32:0, length: u32:32 };
6666
assert_eq(buffer_can_fit(buffer, bits[0]:0), true);
6767
assert_eq(buffer_can_fit(buffer, u1:0), false);
6868
assert_eq(buffer_can_fit(buffer, u16:0), false);
@@ -76,19 +76,19 @@ pub fn buffer_has_at_least<CAPACITY: u32>(buffer: Buffer<CAPACITY>, length: u32)
7676

7777
#[test]
7878
fn test_buffer_has_at_least() {
79-
let buffer = Buffer { contents: u32:0, length: u32:0 };
79+
let buffer = Buffer { content: u32:0, length: u32:0 };
8080
assert_eq(buffer_has_at_least(buffer, u32:0), true);
8181
assert_eq(buffer_has_at_least(buffer, u32:16), false);
8282
assert_eq(buffer_has_at_least(buffer, u32:32), false);
8383
assert_eq(buffer_has_at_least(buffer, u32:33), false);
8484

85-
let buffer = Buffer { contents: u32:0, length: u32:16 };
85+
let buffer = Buffer { content: u32:0, length: u32:16 };
8686
assert_eq(buffer_has_at_least(buffer, u32:0), true);
8787
assert_eq(buffer_has_at_least(buffer, u32:16), true);
8888
assert_eq(buffer_has_at_least(buffer, u32:32), false);
8989
assert_eq(buffer_has_at_least(buffer, u32:33), false);
9090

91-
let buffer = Buffer { contents: u32:0, length: u32:32 };
91+
let buffer = Buffer { content: u32:0, length: u32:32 };
9292
assert_eq(buffer_has_at_least(buffer, u32:0), true);
9393
assert_eq(buffer_has_at_least(buffer, u32:16), true);
9494
assert_eq(buffer_has_at_least(buffer, u32:32), true);
@@ -104,19 +104,19 @@ pub fn buffer_append<CAPACITY: u32, DSIZE: u32> (buffer: Buffer<CAPACITY>, data:
104104
fail!("not_enough_space", buffer)
105105
} else {
106106
Buffer {
107-
contents: (data as bits[CAPACITY] << buffer.length) | buffer.contents,
107+
content: (data as bits[CAPACITY] << buffer.length) | buffer.content,
108108
length: DSIZE + buffer.length
109109
}
110110
}
111111
}
112112

113113
#[test]
114114
fn test_buffer_append() {
115-
let buffer = Buffer { contents: u32:0, length: u32:0 };
115+
let buffer = Buffer { content: u32:0, length: u32:0 };
116116
let buffer = buffer_append(buffer, u16:0xBEEF);
117-
assert_eq(buffer, Buffer { contents: u32:0xBEEF, length: u32:16 });
117+
assert_eq(buffer, Buffer { content: u32:0xBEEF, length: u32:16 });
118118
let buffer = buffer_append(buffer, u16:0xDEAD);
119-
assert_eq(buffer, Buffer { contents: u32:0xDEADBEEF, length: u32:32 });
119+
assert_eq(buffer, Buffer { content: u32:0xDEADBEEF, length: u32:32 });
120120
}
121121

122122
// Returns a new buffer with the `data` appended to the original `buffer` if
@@ -129,7 +129,7 @@ pub fn buffer_append_checked<CAPACITY: u32, DSIZE: u32> (buffer: Buffer<CAPACITY
129129
BufferResult {
130130
status: BufferStatus::OK,
131131
buffer: Buffer {
132-
contents: (data as bits[CAPACITY] << buffer.length) | buffer.contents,
132+
content: (data as bits[CAPACITY] << buffer.length) | buffer.content,
133133
length: DSIZE + buffer.length
134134
}
135135
}
@@ -138,18 +138,18 @@ pub fn buffer_append_checked<CAPACITY: u32, DSIZE: u32> (buffer: Buffer<CAPACITY
138138

139139
#[test]
140140
fn test_buffer_append_checked() {
141-
let buffer = Buffer { contents: u32:0, length: u32:0 };
141+
let buffer = Buffer { content: u32:0, length: u32:0 };
142142

143143
let result1 = buffer_append_checked(buffer, u16:0xBEEF);
144144
assert_eq(result1, BufferResult {
145145
status: BufferStatus::OK,
146-
buffer: Buffer { contents: u32:0xBEEF, length: u32:16 }
146+
buffer: Buffer { content: u32:0xBEEF, length: u32:16 }
147147
});
148148

149149
let result2 = buffer_append_checked(result1.buffer, u16:0xDEAD);
150150
assert_eq(result2, BufferResult {
151151
status: BufferStatus::OK,
152-
buffer: Buffer { contents: u32:0xDEADBEEF, length: u32:32 }
152+
buffer: Buffer { content: u32:0xDEADBEEF, length: u32:32 }
153153
});
154154

155155
let result3 = buffer_append_checked(result2.buffer, u16:0xCAFE);
@@ -173,23 +173,23 @@ pub fn buffer_pop<CAPACITY: u32>(buffer: Buffer<CAPACITY>, length: u32) -> (Buff
173173
let mask = (bits[CAPACITY]:1 << length) - bits[CAPACITY]:1;
174174
(
175175
Buffer {
176-
contents: buffer.contents >> length,
176+
content: buffer.content >> length,
177177
length: buffer.length - length
178178
},
179-
buffer.contents & mask
179+
buffer.content & mask
180180
)
181181
}
182182
}
183183

184184
#[test]
185185
fn test_buffer_pop() {
186-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
186+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
187187
let (buffer, data) = buffer_pop(buffer, u32:16);
188188
assert_eq(data, u32:0xBEEF);
189-
assert_eq(buffer, Buffer { contents: u32:0xDEAD, length: u32:16 });
189+
assert_eq(buffer, Buffer { content: u32:0xDEAD, length: u32:16 });
190190
let (buffer, data) = buffer_pop(buffer, u32:16);
191191
assert_eq(data, u32:0xDEAD);
192-
assert_eq(buffer, Buffer { contents: u32:0, length: u32:0 });
192+
assert_eq(buffer, Buffer { content: u32:0, length: u32:0 });
193193
}
194194

195195
// Returns `length` amount of data from a `buffer`, a new buffer with
@@ -210,30 +210,30 @@ pub fn buffer_pop_checked<CAPACITY: u32> (buffer: Buffer<CAPACITY>, length: u32)
210210
BufferResult {
211211
status: BufferStatus::OK,
212212
buffer: Buffer {
213-
contents: buffer.contents >> length,
213+
content: buffer.content >> length,
214214
length: buffer.length - length
215215
}
216216
},
217-
buffer.contents & mask
217+
buffer.content & mask
218218
)
219219
}
220220
}
221221

222222
#[test]
223223
fn test_buffer_pop_checked() {
224-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
224+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
225225

226226
let (result1, data1) = buffer_pop_checked(buffer, u32:16);
227227
assert_eq(result1, BufferResult {
228228
status: BufferStatus::OK,
229-
buffer: Buffer { contents: u32:0xDEAD, length: u32:16 }
229+
buffer: Buffer { content: u32:0xDEAD, length: u32:16 }
230230
});
231231
assert_eq(data1, u32:0xBEEF);
232232

233233
let (result2, data2) = buffer_pop_checked(result1.buffer, u32:16);
234234
assert_eq(result2, BufferResult {
235235
status: BufferStatus::OK,
236-
buffer: Buffer { contents: u32:0, length: u32:0 }
236+
buffer: Buffer { content: u32:0, length: u32:0 }
237237
});
238238
assert_eq(data2, u32:0xDEAD);
239239

@@ -255,13 +255,13 @@ pub fn buffer_fixed_pop<CAPACITY: u32, DSIZE: u32> (buffer: Buffer<CAPACITY>) ->
255255

256256
#[test]
257257
fn test_buffer_fixed_pop() {
258-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
258+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
259259
let (buffer, data) = buffer_fixed_pop<u32:32, u32:16>(buffer);
260260
assert_eq(data, u16:0xBEEF);
261-
assert_eq(buffer, Buffer { contents: u32:0xDEAD, length: u32:16 });
261+
assert_eq(buffer, Buffer { content: u32:0xDEAD, length: u32:16 });
262262
let (buffer, data) = buffer_fixed_pop<u32:32, u32:16>(buffer);
263263
assert_eq(data, u16:0xDEAD);
264-
assert_eq(buffer, Buffer { contents: u32:0, length: u32:0 });
264+
assert_eq(buffer, Buffer { content: u32:0, length: u32:0 });
265265
}
266266

267267
// Behaves like `buffer_pop_checked` except that the length of the popped data
@@ -273,18 +273,18 @@ pub fn buffer_fixed_pop_checked<CAPACITY: u32, DSIZE: u32> (buffer: Buffer<CAPAC
273273

274274
#[test]
275275
fn test_buffer_fixed_pop_checked() {
276-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
276+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
277277
let (result1, data1) = buffer_fixed_pop_checked<u32:32, u32:16>(buffer);
278278
assert_eq(result1, BufferResult {
279279
status: BufferStatus::OK,
280-
buffer: Buffer { contents: u32:0xDEAD, length: u32:16 }
280+
buffer: Buffer { content: u32:0xDEAD, length: u32:16 }
281281
});
282282
assert_eq(data1, u16:0xBEEF);
283283

284284
let (result2, data2) = buffer_fixed_pop_checked<u32:32, u32:16>(result1.buffer);
285285
assert_eq(result2, BufferResult {
286286
status: BufferStatus::OK,
287-
buffer: Buffer { contents: u32:0, length: u32:0 }
287+
buffer: Buffer { content: u32:0, length: u32:0 }
288288
});
289289
assert_eq(data2, u16:0xDEAD);
290290

@@ -305,13 +305,13 @@ pub fn buffer_peek<CAPACITY: u32>(buffer: Buffer<CAPACITY>, length: u32) -> bits
305305
fail!("not_enough_data", bits[CAPACITY]:0)
306306
} else {
307307
let mask = (bits[CAPACITY]:1 << length) - bits[CAPACITY]:1;
308-
buffer.contents & mask
308+
buffer.content & mask
309309
}
310310
}
311311

312312
#[test]
313313
fn test_buffer_peek() {
314-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
314+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
315315
assert_eq(buffer_peek(buffer, u32:0), u32:0);
316316
assert_eq(buffer_peek(buffer, u32:16), u32:0xBEEF);
317317
assert_eq(buffer_peek(buffer, u32:32), u32:0xDEADBEEF);
@@ -325,13 +325,13 @@ pub fn buffer_peek_checked<CAPACITY: u32> (buffer: Buffer<CAPACITY>, length: u32
325325
(BufferStatus::NO_ENOUGH_DATA, bits[CAPACITY]:0)
326326
} else {
327327
let mask = (bits[CAPACITY]:1 << length) - bits[CAPACITY]:1;
328-
(BufferStatus::OK, buffer.contents & mask)
328+
(BufferStatus::OK, buffer.content & mask)
329329
}
330330
}
331331

332332
#[test]
333333
fn test_buffer_peek_checked() {
334-
let buffer = Buffer { contents: u32:0xDEADBEEF, length: u32:32 };
334+
let buffer = Buffer { content: u32:0xDEADBEEF, length: u32:32 };
335335

336336
let (status1, data1) = buffer_peek_checked(buffer, u32:0);
337337
assert_eq(status1, BufferStatus::OK);
@@ -352,10 +352,73 @@ fn test_buffer_peek_checked() {
352352

353353
// Creates a new buffer
354354
pub fn buffer_new<CAPACITY: u32>() -> Buffer<CAPACITY> {
355-
Buffer { contents: bits[CAPACITY]:0, length: u32:0 }
355+
Buffer { content: bits[CAPACITY]:0, length: u32:0 }
356356
}
357357

358358
#[test]
359359
fn test_buffer_new() {
360-
assert_eq(buffer_new<u32:32>(), Buffer { contents: u32:0, length: u32:0 });
360+
assert_eq(buffer_new<u32:32>(), Buffer { content: u32:0, length: u32:0 });
361+
}
362+
363+
// Example use case
364+
//
365+
// The Buffer structure is meant to aggregate data received from the Proc's
366+
// channels. This data may be collected in multiple evaluations of the next
367+
// functions. Once the required amount of data is collected, it can be poped-out
368+
// in chanks of any length. A simple example that shows how the Buffer structure
369+
// can be used is presented below. It uses the structure to combine several
370+
// smaller transactions into bigger ones.
371+
372+
proc BufferExampleUsage {
373+
input_r: chan<u32> in;
374+
output_s: chan<u48> out;
375+
376+
config(
377+
input_r: chan<u32> in,
378+
output_s: chan<u48> out
379+
) { (input_r, output_s) }
380+
381+
init { buffer_new<u32:64>() }
382+
383+
next(tok: token, buffer: Buffer<u32:64>) {
384+
let (tok, recv_data) = recv(tok, input_r);
385+
let buffer = buffer_append<u32:64>(buffer, recv_data);
386+
387+
if buffer.length >= u32:48 {
388+
let (buffer, data_to_send) = buffer_fixed_pop<u32:64, u32:48>(buffer);
389+
let tok = send(tok, output_s, data_to_send);
390+
buffer
391+
} else {
392+
buffer
393+
}
394+
}
395+
}
396+
397+
#[test_proc]
398+
proc BufferExampleUsageTest {
399+
terminator: chan<bool> out;
400+
data32_s: chan<u32> out;
401+
data48_r: chan<u48> in;
402+
403+
config(terminator: chan<bool> out) {
404+
let (data32_s, data32_r) = chan<u32>;
405+
let (data48_s, data48_r) = chan<u48>;
406+
spawn BufferExampleUsage(data32_r, data48_s);
407+
(terminator, data32_s, data48_r)
408+
}
409+
410+
init {}
411+
412+
next(tok: token, state: ()) {
413+
let tok = send(tok, data32_s, u32:0xDEADBEEF);
414+
let tok = send(tok, data32_s, u32:0xBEEFCAFE);
415+
let tok = send(tok, data32_s, u32:0xCAFEDEAD);
416+
417+
let (tok, received_data) = recv(tok, data48_r);
418+
assert_eq(received_data, u48:0xCAFE_DEAD_BEEF);
419+
let (tok, received_data) = recv(tok, data48_r);
420+
assert_eq(received_data, u48:0xCAFE_DEAD_BEEF);
421+
422+
send(tok, terminator, true);
423+
}
361424
}

0 commit comments

Comments
 (0)