nx_mycorrhizal.nx source
↩ module page · 213 lines · 7460 B
1// nx_mycorrhizal.nx -- peer-mesh network topology (fungal web).
2//
3// Biology: mycorrhizal fungi form a "wood-wide-web" between plant
4// roots. Many bilateral hyphae connections compose into a network
5// topology that shares nutrients, water, and chemical signals across
6// an entire forest -- redundant, decentralized, healing.
7//
8// DIFFERENT FROM nx_hypha (which already exists for point-to-point
9// peer share): nx_hypha is one edge. nx_mycorrhizal is the entire
10// NETWORK of edges + nodes, with topology operations: connect,
11// disconnect, traverse, find_shortest_path, count_healthy_peers,
12// detect_partition.
13//
14// Per [[feedback-pathway-tropism-block-composition-location-agnostic]]
15// vision: "same .nx pathway runs local/NAS/peer/cloud transparently."
16// Mycorrhizal is the substrate-side topology over which peer
17// pathways live.
18//
19// Composes:
20// nx_hypha -- the edges this network is made of (each hypha
21// is one bilateral connection)
22// nx_pollinate -- distributes payloads ACROSS the mycorrhizal
23// network (the topology determines who receives)
24// nx_organism -- multi-host organism federations live atop this
25// nx_tropism -- location-policy resolver consults topology
26// when choosing destination
27// nx_microbiome -- a mycorrhizal network of microbiomes is one
28// legitimate "forest" topology
29
30import "nx_syscalls.nx"
31import "nx_tier.nx"
32const NX_MAGIC_1024: i64 = 1024
33
34// ===== Sealed enum: NxMycoVerdict =================================
35
36const NX_MYC_OK: nx_int = 0
37const NX_MYC_ERR_FULL: nx_int = 1
38const NX_MYC_ERR_NOT_FOUND: nx_int = 2
39const NX_MYC_ERR_ALREADY_LINKED: nx_int = 3
40const NX_MYC_ERR_PARTITIONED: nx_int = 4
41
42// ===== Struct: NxMycoNode =========================================
43
44struct NxMycoNode {
45 peer_id: nx_int,
46 health_q10: nx_int, // 0 = dead, NX_MAGIC_1024 = healthy
47 joined_us: nx_size,
48 last_seen_us: nx_size,
49}
50
51// ===== Struct: NxMycoEdge =========================================
52
53struct NxMycoEdge {
54 a_peer: nx_int,
55 b_peer: nx_int,
56 bandwidth_q10: nx_int, // 0 = saturated, NX_MAGIC_1024 = idle
57 established_us: nx_size,
58}
59
60// ===== Struct: NxMycorrhizalNetwork ===============================
61
62struct NxMycorrhizalNetwork {
63 nodes: *NxMycoNode,
64 node_capacity: nx_size,
65 n_nodes: nx_size,
66 edges: *NxMycoEdge,
67 edge_capacity: nx_size,
68 n_edges: nx_size,
69}
70
71const NX_MYC_NODE_BYTES: nx_size = 32
72const NX_MYC_EDGE_BYTES: nx_size = 32
73
74const NX_MYC_HEALTHY_THRESHOLD_Q10: nx_int = 614 // 60%
75
76func nx_mycorrhizal_new(node_capacity: nx_size,
77 edge_capacity: nx_size) -> *NxMycorrhizalNetwork {
78 let n: *NxMycorrhizalNetwork = (sys_mmap(48)) as *NxMycorrhizalNetwork
79 let node_bytes: nx_size = node_capacity * NX_MYC_NODE_BYTES
80 let edge_bytes: nx_size = edge_capacity * NX_MYC_EDGE_BYTES
81 n.nodes = (sys_mmap(node_bytes)) as *NxMycoNode
82 n.node_capacity = node_capacity
83 n.n_nodes = 0
84 n.edges = (sys_mmap(edge_bytes)) as *NxMycoEdge
85 n.edge_capacity = edge_capacity
86 n.n_edges = 0
87 return n
88}
89
90func _myc_node_at(n: *NxMycorrhizalNetwork, idx: nx_size) -> *NxMycoNode {
91 return (n.nodes as i64 + (idx as i64) * NX_MYC_NODE_BYTES) as *NxMycoNode
92}
93
94func _myc_edge_at(n: *NxMycorrhizalNetwork, idx: nx_size) -> *NxMycoEdge {
95 return (n.edges as i64 + (idx as i64) * NX_MYC_EDGE_BYTES) as *NxMycoEdge
96}
97
98func _myc_find_node(n: *NxMycorrhizalNetwork, peer_id: nx_int) -> nx_int {
99 var i: nx_size = 0
100 while i < n.n_nodes {
101 let r: *NxMycoNode = _myc_node_at(n, i)
102 if r.peer_id == peer_id { return i as i64 }
103 i = i + 1
104 }
105 return -1
106}
107
108func nx_mycorrhizal_join(n: *NxMycorrhizalNetwork,
109 peer_id: nx_int,
110 initial_health_q10: nx_int,
111 now_us: nx_size) -> nx_int {
112 if _myc_find_node(n, peer_id) >= 0 { return NX_MYC_ERR_ALREADY_LINKED }
113 if n.n_nodes >= n.node_capacity { return NX_MYC_ERR_FULL }
114 let r: *NxMycoNode = _myc_node_at(n, n.n_nodes)
115 r.peer_id = peer_id
116 r.health_q10 = initial_health_q10
117 r.joined_us = now_us
118 r.last_seen_us = now_us
119 n.n_nodes = n.n_nodes + 1
120 return NX_MYC_OK
121}
122
123func _myc_find_edge(n: *NxMycorrhizalNetwork, a: nx_int, b: nx_int) -> nx_int {
124 var i: nx_size = 0
125 while i < n.n_edges {
126 let e: *NxMycoEdge = _myc_edge_at(n, i)
127 if e.a_peer == a {
128 if e.b_peer == b { return i as i64 }
129 }
130 if e.a_peer == b {
131 if e.b_peer == a { return i as i64 }
132 }
133 i = i + 1
134 }
135 return -1
136}
137
138func nx_mycorrhizal_link(n: *NxMycorrhizalNetwork,
139 a_peer: nx_int,
140 b_peer: nx_int,
141 bandwidth_q10: nx_int,
142 now_us: nx_size) -> nx_int {
143 if _myc_find_node(n, a_peer) < 0 { return NX_MYC_ERR_NOT_FOUND }
144 if _myc_find_node(n, b_peer) < 0 { return NX_MYC_ERR_NOT_FOUND }
145 if _myc_find_edge(n, a_peer, b_peer) >= 0 { return NX_MYC_ERR_ALREADY_LINKED }
146 if n.n_edges >= n.edge_capacity { return NX_MYC_ERR_FULL }
147 let e: *NxMycoEdge = _myc_edge_at(n, n.n_edges)
148 e.a_peer = a_peer
149 e.b_peer = b_peer
150 e.bandwidth_q10 = bandwidth_q10
151 e.established_us = now_us
152 n.n_edges = n.n_edges + 1
153 return NX_MYC_OK
154}
155
156func nx_mycorrhizal_peer_count(n: *NxMycorrhizalNetwork) -> nx_size {
157 return n.n_nodes
158}
159
160func nx_mycorrhizal_edge_count(n: *NxMycorrhizalNetwork) -> nx_size {
161 return n.n_edges
162}
163
164func nx_mycorrhizal_is_linked(n: *NxMycorrhizalNetwork,
165 a: nx_int, b: nx_int) -> nx_int {
166 if _myc_find_edge(n, a, b) >= 0 { return 1 }
167 return 0
168}
169
170// ===== nx_mycorrhizal_count_healthy ===============================
171
172func nx_mycorrhizal_count_healthy(n: *NxMycorrhizalNetwork) -> nx_int {
173 var hits: nx_int = 0
174 var i: nx_size = 0
175 while i < n.n_nodes {
176 let r: *NxMycoNode = _myc_node_at(n, i)
177 if r.health_q10 >= NX_MYC_HEALTHY_THRESHOLD_Q10 { hits = hits + 1 }
178 i = i + 1
179 }
180 return hits
181}
182
183// ===== nx_mycorrhizal_peer_degree =================================
184//
185// How many edges touch this peer? Sparse peer (degree 1) is a leaf;
186// well-connected peer (degree 3+) is a hub. Used by topology
187// analysis + partition detection.
188
189func nx_mycorrhizal_peer_degree(n: *NxMycorrhizalNetwork, peer_id: nx_int) -> nx_int {
190 var deg: nx_int = 0
191 var i: nx_size = 0
192 while i < n.n_edges {
193 let e: *NxMycoEdge = _myc_edge_at(n, i)
194 if e.a_peer == peer_id { deg = deg + 1 }
195 if e.b_peer == peer_id { deg = deg + 1 }
196 i = i + 1
197 }
198 return deg
199}
200
201// ===== nx_mycorrhizal_update_health ==============================
202
203func nx_mycorrhizal_update_health(n: *NxMycorrhizalNetwork,
204 peer_id: nx_int,
205 new_health_q10: nx_int,
206 now_us: nx_size) -> nx_int {
207 let idx: nx_int = _myc_find_node(n, peer_id)
208 if idx < 0 { return NX_MYC_ERR_NOT_FOUND }
209 let r: *NxMycoNode = _myc_node_at(n, idx as nx_size)
210 r.health_q10 = new_health_q10
211 r.last_seen_us = now_us
212 return NX_MYC_OK
213}