nx_asset_search.nx source
↩ module page · 98 lines · 3811 B
1// nx_asset_search.nx -- UNIVERSAL ORGANIZATION TOOLING arc: FACETED FINDABILITY over the catalog.
2//
3// org_research.tsv faceted-findability: assets you can't FIND are lost. Filter the content-addressed
4// catalog by an attribute facet -- type / provenance / classification / date (exact match) or a tag
5// token (the comma-joined `tags` facet) -- and get back the matching record CIDs. PURE COMPOSITION
6// over R1 catalog + R0 record decode (cat_list -> cat_get -> canon_decode -> ar_get); ZERO new storage.
7//
8// HONEST GRADE = PARITY: incumbent DAM (Adobe AEM / Bynder) have mature faceted search; this is the
9// sovereign equivalent over the SAME unified content-addressed records (not an exceed claim).
10// No hardware/persistent-firmware writes (Rule 26). license_tier: ORIGINAL
11import "nx_syscalls.nx"
12import "nx_uxf_decode.nx"
13import "nx_asset_record.nx"
14import "nx_asset_catalog.nx"
15const K_MAGIC_4096: i64 = 4096
16
17func as_streq(a: *u8, b: *u8) -> i64 {
18 var i: i64 = 0
19 while 1 == 1 {
20 if a[i] != b[i] { return 0 }
21 if a[i] == (0 as u8) { return 1 }
22 i = i + 1
23 }
24 return 1
25}
26
27// does s[a,b) equal the NUL-terminated `want` exactly?
28func as_tok_eq(s: *u8, a: i64, b: i64, want: *u8) -> i64 {
29 var i: i64 = a
30 var j: i64 = 0
31 while i < b { if s[i] != want[j] { return 0 } i = i + 1; j = j + 1 }
32 if want[j] != (0 as u8) { return 0 }
33 return 1
34}
35
36// does the comma-joined `tags` list contain the exact token `want`?
37func as_tag_has(tags: *u8, want: *u8) -> i64 {
38 if (tags as i64) == 0 { return 0 }
39 var i: i64 = 0
40 var ts: i64 = 0
41 while 1 == 1 {
42 let c: i64 = tags[i]
43 if c == 44 { // ',' -> end of a token
44 if as_tok_eq(tags, ts, i, want) == 1 { return 1 }
45 ts = i + 1
46 }
47 if c == 0 { // NUL -> last token
48 if as_tok_eq(tags, ts, i, want) == 1 { return 1 }
49 return 0
50 }
51 i = i + 1
52 }
53 return 0
54}
55
56// EXACT-MATCH facet: CIDs of records whose field `key` == `val`. Returns the match count.
57func as_by_field(prefix: *u8, key: *u8, val: *u8, out_cids: *i64, cap: i64) -> i64 {
58 let lst: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
59 let n: i64 = cat_list(prefix, lst, K_MAGIC_4096)
60 let gp: *i64 = sys_mmap(16) as *i64
61 let gl: *i64 = sys_mmap(16) as *i64
62 let dk: *i64 = sys_mmap(8 * 32) as *i64
63 let dv: *i64 = sys_mmap(8 * 32) as *i64
64 var cnt: i64 = 0
65 var i: i64 = 0
66 while i < n {
67 let cid: *u8 = lst[i] as *u8
68 if cat_get(prefix, cid, gp, gl) == 1 {
69 let nf: i64 = canon_decode(gp[0] as *u8, gl[0], dk, dv, 32)
70 let fv: *u8 = ar_get(dk, dv, nf, key)
71 if (fv as i64) != 0 { if as_streq(fv, val) == 1 { if cnt < cap { out_cids[cnt] = cid as i64; cnt = cnt + 1 } } }
72 }
73 i = i + 1
74 }
75 return cnt
76}
77
78// TAG facet: CIDs of records whose `tags` field contains the token `want`. Returns the match count.
79func as_by_tag(prefix: *u8, want: *u8, out_cids: *i64, cap: i64) -> i64 {
80 let lst: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
81 let n: i64 = cat_list(prefix, lst, K_MAGIC_4096)
82 let gp: *i64 = sys_mmap(16) as *i64
83 let gl: *i64 = sys_mmap(16) as *i64
84 let dk: *i64 = sys_mmap(8 * 32) as *i64
85 let dv: *i64 = sys_mmap(8 * 32) as *i64
86 var cnt: i64 = 0
87 var i: i64 = 0
88 while i < n {
89 let cid: *u8 = lst[i] as *u8
90 if cat_get(prefix, cid, gp, gl) == 1 {
91 let nf: i64 = canon_decode(gp[0] as *u8, gl[0], dk, dv, 32)
92 let tv: *u8 = ar_get(dk, dv, nf, "tags\x00" as *u8)
93 if as_tag_has(tv, want) == 1 { if cnt < cap { out_cids[cnt] = cid as i64; cnt = cnt + 1 } }
94 }
95 i = i + 1
96 }
97 return cnt
98}