6. Build and update a Boolean table¶
Treat rows as a set of permission assignments. The columns indicate read, write and share permission. Duplicate input rows represent the same assignment.
6.1. Load rows¶
Pass a row-major array of bytes, each 0 or 1. Column IDs specify which variable each position describes.
enum { READ = 1, WRITE, SHARE };
const uint32_t columns[] = {READ, WRITE, SHARE};
const uint8_t rows[][3] = {{1,0,0}, {1,1,0}, {1,0,1}, {1,1,0}};
TididiCircuit *table = NULL;
check(tididi_from_models(vtree, columns, 3, &rows[0][0], 4, &table, NULL));
printf("Distinct rows: %" PRIu64 "\n", count(table));
Output:
Distinct rows: 3
6.2. Change the set¶
Insert the all-permissions row, then remove read-and-write without sharing. An update consumes the old circuit and returns a minimized replacement.
const int64_t add[] = {READ, WRITE, SHARE}, remove[] = {READ, WRITE, -SHARE};
const TididiCube insertions[] = {{add, 3}}, deletions[] = {{remove, 3}};
TididiCircuit *updated = NULL;
check(tididi_update(table, insertions, 1, deletions, 1, &updated, NULL));
printf("After updating: %" PRIu64 "\n", count(updated));
Output:
After updating: 3
The updated table contains read-only, read-and-share, and all three permissions. The count is unchanged, but its rows differ.
6.3. Filter rows¶
Conjunction with the share literal selects rows that permit sharing. Filter a copy so the full table stays available for the next update.
TididiCircuit *share = NULL, *selected = NULL, *table_copy = copy(updated);
check(tididi_literal(vtree, SHARE, &share, NULL));
check(tididi_and(table_copy, share, &selected, NULL));
printf("Rows allowing sharing: %" PRIu64 "\n", count(selected));
Output:
Rows allowing sharing: 2
6.4. Remove a group of rows¶
Suppose sharing is withdrawn entirely. A partial assignment names just the
permissions to match: {SHARE} selects every row where sharing is true,
whatever its read and write values. Pass no insertions and one deletion cube:
const int64_t sharing[] = {SHARE};
const TididiCube matching[] = {{sharing, 1}};
TididiCircuit *without_sharing = NULL;
check(tididi_update(updated, NULL, 0, matching, 1, &without_sharing, NULL));
printf("After withdrawing sharing: %" PRIu64 "\n", count(without_sharing));
Output:
After withdrawing sharing: 1
Only read access without write or share remains. Removing matching rows does not change their share column to false. An empty cube matches all assignments.
6.5. Complete program¶
Download tables.c and the
shared helper. The source includes cleanup
for all handles. Both files are included in the source checkout.