summaryrefslogtreecommitdiffstats
path: root/examples/lib-dfscq-log/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/lib-dfscq-log/src/main.rs')
-rw-r--r--examples/lib-dfscq-log/src/main.rs642
1 files changed, 642 insertions, 0 deletions
diff --git a/examples/lib-dfscq-log/src/main.rs b/examples/lib-dfscq-log/src/main.rs
new file mode 100644
index 0000000..fe5db9a
--- /dev/null
+++ b/examples/lib-dfscq-log/src/main.rs
@@ -0,0 +1,642 @@
1mod block_list;
2mod blocks;
3mod bracket;
4mod explode;
5mod labeled_delimiter;
6mod layer;
7mod spacer;
8
9//mod labeled;
10//use labeled::Labeled;
11
12use block_list::BlockList;
13use blocks::*;
14use explode::*;
15use labeled_delimiter::*;
16use layer::*;
17use spacer::*;
18
19use diaphragm_cairo_renderer::CairoRenderer;
20use diaphragm_core::{
21 colors::Color,
22 core_shapes::{Text},
23 styles::*,
24 text::FontDescription,
25 types::*,
26 *,
27};
28use diaphragm_z3_solver::{z3, Z3Context};
29
30fn main() {
31 let z3_cfg = z3::Config::new();
32 let z3_ctx = z3::Context::new(&z3_cfg);
33 let ctx = Z3Context::new(&z3_ctx);
34
35 let cairo_renderer = CairoRenderer::new();
36
37 let mut runtime = Runtime::new(Box::new(ctx), Box::new(cairo_renderer));
38
39 let solver = runtime.solver_ctx();
40
41 let blue = Color::from_rgb(0.35, 0.35, 1.);
42 let light_grey = Color::from_rgb(0.8, 0.8, 0.8);
43 let dark_grey = Color::from_rgb(0.5, 0.5, 0.5);
44
45 // ----------------8<----------------
46
47 /*
48 let mut make_blocks = |grows: &[u8]| {
49 grows
50 .iter()
51 .map(|&grow| {
52 Drawable::builder(Block { grow })
53 .fill(FillStyle::solid(blue))
54 .build(solver)
55 })
56 .collect()
57 };
58
59 let blocks = Drawable::builder(Blocks {
60 blocks: make_blocks(&[1, 2, 1, 1, 4, 1, 1]),
61 unit_width: solver.new_free_float(),
62 })
63 .bounds(
64 Bounds::builder()
65 .top(Float::Fixed(20.))
66 .left(Float::Fixed(20.))
67 .width(Float::Fixed(150.))
68 .height(Float::Fixed(50.))
69 .build(solver),
70 )
71 .build(solver);
72
73 runtime.add_drawable(blocks);
74 */
75
76 // ----------------8<----------------
77
78 /*
79 let block_unit_width = solver.new_fixed_float(10.);
80
81 fn color_block(grow: u8, color: Color, solver: &mut dyn SolverContext) -> Drawable<Block> {
82 Drawable::builder(Block { grow })
83 .fill(FillStyle::solid(color))
84 .build(solver)
85 };
86
87 fn blocks(block_descs: &[(u8, Color)], solver: &mut dyn SolverContext) -> Drawable<Blocks> {
88 let mut blocks = Vec::new();
89
90 for &(grow, color) in block_descs {
91 blocks.push(color_block(grow, color, solver));
92 }
93
94 Drawable::builder(Blocks {
95 blocks,
96 unit_width: solver.new_free_float(),
97 })
98 .build(solver)
99 }
100
101 let block_list = Drawable::builder(BlockList {
102 block_list: vec![
103 blocks(&[(1, light_grey), (1, light_grey), (1, light_grey)], solver),
104 blocks(
105 &[
106 (1, light_grey),
107 (2, blue),
108 (1, light_grey),
109 (1, light_grey),
110 (1, light_grey),
111 ],
112 solver,
113 ),
114 blocks(&[(3, light_grey), (2, blue)], solver),
115 ],
116 block_unit_width,
117 bracket_width: block_unit_width,
118 blocks_vert_padding: block_unit_width,
119 })
120 .bounds(
121 Bounds::builder()
122 .top(Float::Fixed(10.))
123 .left(Float::Fixed(10.))
124 .height(Float::Fixed(40.))
125 .build(solver),
126 )
127 .build(solver);
128
129 runtime.add_drawable(block_list);
130 */
131
132 // ----------------8<----------------
133
134 /*
135 let label_font = FontDescription {
136 family: String::from("mono"),
137 style: Default::default(),
138 weight: Default::default(),
139 size: Float::Fixed(15.),
140 };
141
142 let layer = Drawable::builder(Layer {
143 name: String::from("Hello"),
144 name_font: FontDescription {
145 family: Default::default(),
146 style: Default::default(),
147 weight: Default::default(),
148 size: Float::Fixed(10.),
149 },
150 entries: vec![],
151 padding: Float::Fixed(5.),
152 entries_width: Float::Fixed(50.),
153 label_font,
154 })
155 .bounds(Bounds::builder()
156 .top(Float::Fixed(10.))
157 .left(Float::Fixed(10.))
158 .width(Float::Fixed(100.))
159 .height(Float::Fixed(40.))
160 .build(solver))
161 .build(solver);
162
163 runtime.add_drawable(layer);
164 */
165
166 // ----------------8<----------------
167
168 let title_font = FontDescription {
169 family: String::from("Fanwood"),
170 style: Default::default(),
171 weight: Default::default(),
172 size: Float::Fixed(30.),
173 };
174
175 let label_font = FontDescription {
176 family: String::from("mono"),
177 style: Default::default(),
178 weight: Default::default(),
179 size: Float::Fixed(15.),
180 };
181
182 let layer_padding = Float::Fixed(15.);
183 let layer_margin = Float::Fixed(15.);
184 //let layer_height = Float::Fixed(40.);
185 let layer_left_content_padding = Float::Fixed(240.);
186 //let layer_width = solver.new_free_float();
187 //let layer_width_constraint = solver.float_eq(layer_width, Float::Fixed(100.));
188 //solver.constrain(layer_width_constraint);
189
190 let mut layer_top = Float::Fixed(15.);
191
192 let entries_width = solver.new_free_float();
193 let mut all_entry_content_widths = vec![];
194
195 let layer_width = solver.float_add(&[
196 layer_left_content_padding,
197 entries_width,
198 layer_padding,
199 layer_padding,
200 ]);
201
202 let blocks_vert_padding = Float::Fixed(10.);
203
204 let block_unit_width = Float::Fixed(20.);
205
206 let blocks_height = Float::Fixed(26.);
207 let block_list_height =
208 solver.float_add(&[blocks_height, blocks_vert_padding, blocks_vert_padding]);
209
210 let blue_transaction_len = 5;
211
212 let blocks = |grows: &[u8], color, solver: &mut dyn SolverContext| {
213 let mut blocks = Vec::new();
214
215 for &grow in grows {
216 blocks.push(
217 Drawable::builder(Block { grow })
218 .fill(FillStyle::solid(color))
219 .build(solver),
220 );
221 }
222
223 Drawable::builder(Blocks {
224 blocks,
225 unit_width: block_unit_width,
226 })
227 .bounds(Bounds::builder().height(blocks_height).build(solver))
228 .build(solver)
229 };
230
231 let blocks_by_len =
232 |len, color, solver: &mut dyn SolverContext| blocks(&vec![1; len], color, solver);
233
234 // Log API
235 {
236 let blocks = blocks_by_len(blue_transaction_len, blue, solver);
237 let blocks_width = blocks.bounds().width(solver);
238
239 let layer = Drawable::builder(Layer {
240 name: String::from("LogAPI"),
241 name_font: title_font.clone(),
242 label_font: label_font.clone(),
243 padding: layer_padding,
244 entries: vec![Entry {
245 label: Some(String::from("activeTxn: ")),
246 label_vert_center_offset: None,
247 content: blocks.into(),
248 }],
249 entries_width,
250 })
251 .bounds(
252 Bounds::builder()
253 // TODO: Replace that with a "distributeHorizontally" that applies to all layer
254 .top(layer_top)
255 .left(Float::Fixed(10.))
256 .width(layer_width)
257 .build(solver),
258 )
259 .build(solver);
260
261 all_entry_content_widths.push(blocks_width);
262
263 let layer_height = layer.bounds().height(solver);
264 layer_top = solver.float_add(&[layer_top, layer_height, layer_margin]);
265
266 runtime.add_drawable(layer);
267 }
268
269 let solver = runtime.solver_ctx();
270
271 let other_transactions = [2, 7, 4];
272
273 let group_commit_left;
274 let group_commit_right;
275 let group_commit_bottom;
276
277 // Group Commit
278 {
279 let mut block_list = Vec::new();
280 for &blocks_count in other_transactions.iter() {
281 block_list.push(blocks_by_len(blocks_count, dark_grey, solver));
282 }
283
284 block_list.push(blocks_by_len(blue_transaction_len, blue, solver));
285
286 let block_list = Drawable::builder(BlockList {
287 block_list,
288 block_unit_width,
289 blocks_vert_padding: Float::Fixed(10.),
290 bracket_width: Float::Fixed(10.),
291 })
292 .bounds(Bounds::builder().height(block_list_height).build(solver))
293 .build(solver);
294
295 let content_width = block_list.bounds().width(solver);
296
297 group_commit_left = block_list.bounds().left(solver);
298 group_commit_right = block_list.bounds().right(solver);
299 group_commit_bottom = block_list.bounds().bottom(solver);
300
301 let layer = Drawable::builder(Layer {
302 name: String::from("GroupCommit"),
303 name_font: title_font.clone(),
304 label_font: label_font.clone(),
305 padding: layer_padding,
306 entries: vec![Entry {
307 label: Some(String::from("commitedTxns: ")),
308 label_vert_center_offset: None,
309 content: block_list.into(),
310 }],
311 entries_width,
312 })
313 .bounds(
314 Bounds::builder()
315 .top(layer_top)
316 .left(Float::Fixed(10.))
317 .width(layer_width)
318 .build(solver),
319 )
320 .build(solver);
321
322 all_entry_content_widths.push(content_width);
323
324 let layer_height = layer.bounds().height(solver);
325 layer_top = solver.float_add(&[layer_top, layer_height, layer_margin]);
326
327 runtime.add_drawable(layer);
328 }
329
330 let solver = runtime.solver_ctx();
331
332 let commit_in_log_left;
333 let commit_in_log_right;
334 let commit_in_log_top;
335 let big_block_grow;
336 let small_block_unit_width;
337 let data_in_log_left;
338 let data_in_log_right;
339 let data_in_log_bottom;
340
341 // Disk log
342 {
343 big_block_grow = (blue_transaction_len + other_transactions.iter().sum::<usize>()) as u8;
344
345 let make_block = |grow, color, solver: &mut dyn SolverContext| {
346 Drawable::builder(Block { grow })
347 .bounds(Bounds::builder().height(blocks_height).build(solver))
348 .fill(FillStyle::solid(color))
349 .build(solver)
350 };
351
352 let make_blocks = |block_descs: &[_], solver: &mut dyn SolverContext| {
353 let mut blocks = Vec::new();
354
355 for &(grow, color) in block_descs {
356 blocks.push(make_block(grow, color, solver));
357 }
358
359 blocks
360 };
361
362 let header_block = make_block(big_block_grow, Color::black(), solver);
363 let header_block_width = header_block.bounds().width(solver);
364
365 let mut blocks = vec![header_block];
366
367 blocks.append(&mut make_blocks(
368 &[(big_block_grow, light_grey), (big_block_grow, light_grey)],
369 solver,
370 ));
371
372 let sample_commit_start_id = blocks.len();
373
374 for &txn_block_count in other_transactions.iter() {
375 for _i in 0..txn_block_count {
376 blocks.push(make_block(1, dark_grey, solver));
377 }
378 }
379
380 for _ in 0..blue_transaction_len {
381 blocks.push(make_block(1, blue, solver));
382 }
383
384 let sample_commit_end_id = blocks.len() - 1;
385
386 commit_in_log_left = blocks[sample_commit_start_id].bounds().left(solver);
387 commit_in_log_right = blocks[sample_commit_end_id].bounds().right(solver);
388 commit_in_log_top = blocks[sample_commit_end_id].bounds().top(solver);
389
390 let log_data_blocks_widths: Vec<_> = blocks[1..]
391 .iter()
392 .map(|block| block.bounds().width(solver))
393 .collect();
394 let log_data_blocks_width = solver.float_add(&log_data_blocks_widths);
395
396 let log_space_block = make_block(big_block_grow, Color::white(), solver);
397 let log_space_width = log_space_block.bounds().width(solver);
398 blocks.push(log_space_block);
399
400 // Make it so that it takes as much space as the bigger one
401 small_block_unit_width = solver.new_free_float();
402
403 let disk_log_layout = Drawable::builder(Blocks {
404 blocks,
405 unit_width: small_block_unit_width,
406 })
407 .bounds(Bounds::builder().width(entries_width).build(solver))
408 .build(solver);
409
410 let mut make_delimiter_label = |content| {
411 Drawable::builder(Text {
412 content: String::from(content),
413 font: FontDescription {
414 family: String::from("Fanwood"),
415 size: Float::Fixed(15.),
416 style: Default::default(),
417 weight: Default::default(),
418 },
419 })
420 .build(solver)
421 };
422
423 let delimiters = vec![
424 Delimiter {
425 label: make_delimiter_label("header"),
426 width: header_block_width,
427 },
428 Delimiter {
429 label: make_delimiter_label("data"),
430 width: log_data_blocks_width,
431 },
432 Delimiter {
433 label: make_delimiter_label("available"),
434 width: log_space_width,
435 },
436 ];
437
438 let disk_log_label = Drawable::builder(LabeledDelimiter {
439 delimiters,
440 tick_height: Float::Fixed(10.),
441 })
442 .bounds(Bounds::builder().width(entries_width).build(solver))
443 .build(solver);
444
445 let label_left = disk_log_label.bounds().left(solver);
446 data_in_log_left = solver.float_add(&[label_left, header_block_width]);
447 data_in_log_right = solver.float_add(&[data_in_log_left, log_data_blocks_width]);
448 data_in_log_bottom = disk_log_label.bounds().bottom(solver);
449
450 let layer = Drawable::builder(Layer {
451 name: String::from("DiskLog"),
452 name_font: title_font.clone(),
453 label_font: label_font.clone(),
454 padding: layer_padding,
455 entries: vec![
456 Entry {
457 label: Some(String::from("disk log: ")),
458 label_vert_center_offset: None,
459 content: disk_log_layout.into(),
460 },
461 Entry {
462 label: None,
463 label_vert_center_offset: None,
464 content: disk_log_label.into(),
465 },
466 ],
467 entries_width,
468 })
469 .bounds(
470 Bounds::builder()
471 .top(layer_top)
472 .left(Float::Fixed(10.))
473 .width(layer_width)
474 .build(solver),
475 )
476 .build(solver);
477
478 let layer_height = layer.bounds().height(solver);
479 layer_top = solver.float_add(&[layer_top, layer_height, layer_margin]);
480
481 runtime.add_drawable(layer);
482 }
483
484 let solver = runtime.solver_ctx();
485
486 // Explode GroupLog -> DiskLog
487 {
488 let margin = Float::Fixed(6.);
489 let explode_top = solver.float_add(&[group_commit_bottom, margin]);
490 let explode_bottom = solver.float_sub(&[commit_in_log_top, margin]);
491
492 let explode = Drawable::builder(Explode {
493 top_left: Point2D::new(group_commit_left, explode_top),
494 top_right: Point2D::new(group_commit_right, explode_top),
495 bottom_left: Point2D::new(commit_in_log_left, explode_bottom),
496 bottom_right: Point2D::new(commit_in_log_right, explode_bottom),
497
498 arm_length: Float::Fixed(12.),
499 })
500 .stroke(
501 StrokeStyle::builder()
502 .dash(DashStyle::new(vec![Float::Fixed(2.)], Float::Fixed(0.)))
503 .build(),
504 )
505 .build(solver);
506
507 runtime.add_drawable(explode);
508 }
509
510 let solver = runtime.solver_ctx();
511
512 let data_in_applier_top;
513 let data_in_applier_left;
514 let data_in_applier_right;
515
516 // Applier
517 {
518 // TODO: this is exactly the same as before...
519 let make_block = |grow, color, solver: &mut dyn SolverContext| {
520 Drawable::builder(Block { grow })
521 .bounds(Bounds::builder().height(blocks_height).build(solver))
522 .fill(FillStyle::solid(color))
523 .build(solver)
524 };
525
526 let _make_blocks = |block_descs: &[_], solver: &mut dyn SolverContext| {
527 let mut blocks = Vec::new();
528
529 for &(grow, color) in block_descs {
530 blocks.push(make_block(grow, color, solver));
531 }
532
533 blocks
534 };
535
536 let mut blocks = vec![];
537
538 blocks.push(make_block(big_block_grow, light_grey, solver));
539 for &txn_block_count in other_transactions.iter() {
540 for _i in 0..txn_block_count {
541 blocks.push(make_block(1, dark_grey, solver));
542 }
543 }
544
545 for _ in 0..blue_transaction_len {
546 blocks.push(make_block(1, blue, solver));
547 }
548
549 let blocks = Drawable::builder(Blocks {
550 blocks,
551 unit_width: small_block_unit_width,
552 })
553 .build(solver);
554
555 data_in_applier_top = blocks.bounds().top(solver);
556 data_in_applier_left = blocks.bounds().left(solver);
557 data_in_applier_right = blocks.bounds().right(solver);
558
559 let spaced_data = Spacer::builder(blocks)
560 .horizontal_align_center(solver)
561 .vertical_align_center_with(Float::Fixed(10.))
562 .build(solver);
563
564 let spaced_data = Drawable::builder(spaced_data)
565 .bounds(Bounds::builder().width(entries_width).build(solver))
566 .build(solver);
567
568 let disk_data = Drawable::builder(Block { grow: 1 })
569 .bounds(
570 Bounds::builder()
571 .height(blocks_height)
572 .width(entries_width)
573 .build(solver),
574 )
575 .fill(FillStyle::solid(Color::white()))
576 .build(solver);
577
578 let layer = Drawable::builder(Layer {
579 name: String::from("Applier"),
580 name_font: title_font.clone(),
581 label_font: label_font.clone(),
582 padding: layer_padding,
583 entries: vec![
584 Entry {
585 label: None,
586 label_vert_center_offset: None,
587 content: spaced_data.into(),
588 },
589 Entry {
590 label: Some(String::from("disk data:")),
591 label_vert_center_offset: None,
592 content: disk_data.into(),
593 },
594 ],
595 entries_width,
596 })
597 .bounds(
598 Bounds::builder()
599 .top(layer_top)
600 .left(Float::Fixed(10.))
601 .width(layer_width)
602 .build(solver),
603 )
604 .build(solver);
605
606 runtime.add_drawable(layer);
607 }
608
609 let solver = runtime.solver_ctx();
610
611 // Explode DiskLog -> Applier
612 {
613 let margin = Float::Fixed(6.);
614 let explode_top = solver.float_add(&[data_in_log_bottom, margin]);
615 let explode_bottom = solver.float_sub(&[data_in_applier_top, margin]);
616
617 let explode = Drawable::builder(Explode {
618 top_left: Point2D::new(data_in_log_left, explode_top),
619 top_right: Point2D::new(data_in_log_right, explode_top),
620 bottom_left: Point2D::new(data_in_applier_left, explode_bottom),
621 bottom_right: Point2D::new(data_in_applier_right, explode_bottom),
622
623 arm_length: Float::Fixed(12.),
624 })
625 .stroke(
626 StrokeStyle::builder()
627 .dash(DashStyle::new(vec![Float::Fixed(2.)], Float::Fixed(0.)))
628 .build(),
629 )
630 .build(solver);
631
632 runtime.add_drawable(explode);
633 }
634
635 let solver = runtime.solver_ctx();
636
637 let max_entry_content_width = solver.float_max(&all_entry_content_widths);
638 let entries_width_constraint = solver.float_eq(entries_width, max_entry_content_width);
639 solver.constrain(entries_width_constraint);
640
641 runtime.render();
642}