1#![allow(non_camel_case_types)]
22#![allow(non_snake_case)]
23#![allow(non_upper_case_globals)]
24#![allow(dead_code)]
25
26use crate::common::errcode;
27use crate::common::TsIdAllocator;
28use std::collections::HashMap;
30use std::mem;
31use std::alloc;
32use super::*;
33
34type T_NODE_INDEX=u16;
35
36
37const INVALID_NODE_ID:u16 = u16::MAX;
38pub const METRIC_INFINITY:u16 = u16::MAX;
39const SPF_MAX_LINK_PER_PAIR:u16 = 4; #[derive(Clone)]
43pub struct port_pair_t {
44 src_port_id:u32,
45 dst_port_id:u32,
46 metric:u32,
47}
48
49#[derive(Clone)]
51pub struct path_edge_t {
52 dst_node_id:u32,
53 src_port_id:u32,
54 dst_port_id:u32,
55 metric:u32,
56}
57
58#[derive(Clone)]
60pub struct path_node_t {
61 src_node_id:u32,
62 edges:Vec<path_edge_t>,
63}
64
65#[derive(Clone)]
68pub struct edge_t {
69 src_node_id:T_NODE_INDEX,
70 dst_node_id:T_NODE_INDEX,
71 link_count:u16,
72 metric:u32,
73 best_link:u16,
74 links:[port_pair_t;SPF_MAX_LINK_PER_PAIR as usize],
75}
76
77#[derive(Clone)]
78pub struct edge_info_t {
79 edge:edge_t,
80 changed:bool,
81}
82
83type path_t=Vec<path_node_t>;
84
85pub struct spf_matrix_t {
87 node_count:usize,
88 max_node_idx:i32,
89 idx_alloc:TsIdAllocator,
90 idx2id:HashMap<i32,u32>, id2idx:HashMap<u32,i32>, cost_matrix:* mut [[edge_info_t;SPF_MAX_NODE_NUM];SPF_MAX_NODE_NUM],
93 path_vector: * mut [[Vec<T_NODE_INDEX>;SPF_MAX_NODE_NUM];SPF_MAX_NODE_NUM],
95}
96
97impl spf_matrix_t {
99
100pub fn new()->Self {
101
102 let cm = unsafe {
103 alloc::alloc(alloc::Layout::from_size_align_unchecked(SPF_MAX_NODE_NUM*SPF_MAX_NODE_NUM*mem::size_of::<edge_info_t>(), 1))
104 as * mut [[edge_info_t;SPF_MAX_NODE_NUM];SPF_MAX_NODE_NUM]
105 };
106 let pv = unsafe {
107 alloc::alloc(alloc::Layout::from_size_align_unchecked(SPF_MAX_NODE_NUM*SPF_MAX_NODE_NUM*mem::size_of::<path_t>(), 1))
108 as * mut [[Vec<T_NODE_INDEX>;SPF_MAX_NODE_NUM];SPF_MAX_NODE_NUM]
109 };
110
111 let pcm=unsafe {&mut *cm};
112 let ppv=unsafe {&mut *pv};
113
114 for i in 0..SPF_MAX_NODE_NUM {
115 for j in 0..SPF_MAX_NODE_NUM {
116 pcm[i][j].changed = false;
117 pcm[i][j].edge.src_node_id = i as u16;
118 pcm[i][j].edge.dst_node_id = j as u16;
119 if i == j {
120 pcm[i][j].edge.metric = 0;
121 } else {
122 pcm[i][j].edge.metric = METRIC_INFINITY as u32;
123 }
124 let path=Vec::new();
125 ppv[i][j]=path;
126
127 }
128 }
129
130 return spf_matrix_t {
131 node_count:0,
132 idx_alloc:TsIdAllocator::new(0, SPF_MAX_NODE_NUM as i32),
133 idx2id:HashMap::with_capacity(SPF_MAX_NODE_NUM),
134 id2idx:HashMap::with_capacity(SPF_MAX_NODE_NUM),
135 cost_matrix:cm,
136 path_vector:pv,
137 max_node_idx:-1,
138 }
139}
140
141pub fn add_node(&mut self,node_id:u32)->errcode::RESULT {
143
144 if self.node_count >= SPF_MAX_NODE_NUM {
145 return errcode::ERROR_OUTOF_MEM;
146 }
147
148 if self.id2idx.contains_key(&node_id) {
149 return errcode::ERROR_ALREADY_EXIST
150 }
151
152 let idx = self.idx_alloc.allocate_id();
154 self.id2idx.insert(node_id.clone(), idx.clone());
156 self.idx2id.insert(idx,node_id);
157 self.node_count+=1;
158 if idx>self.max_node_idx {
159 self.max_node_idx = idx;
160 }
161 println!("add node success,node_id={},idx={}",node_id,idx);
162 return errcode::RESULT_SUCCESS
163}
164
165pub fn delete_node(&mut self,node_id:u32)->errcode::RESULT {
167 let idx = match self.id2idx.get(&node_id) {
168 None=> {
169 return errcode::ERROR_NOT_FOUND
170 },
171 Some(v)=>v.clone(),
172 };
173 self.idx_alloc.release_id(idx);
174 self.node_count-=1;
175 if idx==self.max_node_idx {
176 self.max_node_idx-=1;
177 }
178 return errcode::RESULT_SUCCESS
179}
180
181fn getIndexById(&self,node_id:u32)->Option<i32> {
183 match self.id2idx.get(&node_id) {
184 None=> {
185 return None
186 },
187 Some(v)=>Some(v.clone()),
188 }
189}
190
191fn get_nodeid_by_idx(&self,idx:u16)->Option<u32> {
193 let new_idx=idx as i32;
194 match self.idx2id.get(&new_idx) {
195 None=> {
196 return None
197 },
198 Some(v)=>Some(v.clone()),
199 }
200}
201
202fn find_link_from_node(&self,edge:&edge_t, src_port_id:u32, dst_port:u32)->u16 {
204 for i in 0..edge.link_count as usize {
205 if edge.links[i].src_port_id == src_port_id && edge.links[i].dst_port_id == dst_port {
206 return i as u16
207 }
208 }
209
210 return u16::MAX
211}
212
213fn addLinkForNode(&mut self,edge:&mut edge_t, srcPort:u32, dstPort:u32, metric:u16)->bool {
215 let idx = self.find_link_from_node(edge, srcPort, dstPort);
216 let uMetric=metric as u32;
217 if edge.link_count >= SPF_MAX_LINK_PER_PAIR || idx != u16::MAX {
218 return false
219 }
220
221 edge.links[edge.link_count as usize].src_port_id = srcPort;
222 edge.links[edge.link_count as usize].dst_port_id = dstPort;
223 edge.links[edge.link_count as usize].metric = uMetric;
224
225 let mut ret = false;
226 if uMetric < edge.metric {
227 edge.metric = uMetric;
228 edge.best_link = edge.link_count;
229 ret = true
230 }
231 edge.link_count+=1;
232
233 return ret
234
235}
236
237fn update_best_link(&mut self,edge:&mut edge_t)->bool {
239
240 let mut idx=u16::MAX;
241 let mut m = METRIC_INFINITY as u32;
242 for i in 0..edge.link_count {
243 if edge.links[i as usize].metric < m {
244 m = edge.links[i as usize].metric;
245 idx = i
246 }
247 }
248
249 if edge.metric == m {
250 return false
251 }
252 edge.best_link = idx;
253 edge.metric = m;
254
255 return true
256}
257
258fn deleteLinkForNode(&mut self,edge:&mut edge_t, srcPort:u32, dstPort:u32)->bool {
260 let idx = self.find_link_from_node(edge, srcPort, dstPort);
261
262 if idx == u16::MAX {
263 return false
264 }
265
266 for i in idx..edge.link_count-1 {
268 edge.links[i as usize] = edge.links[i as usize+1].clone();
269 }
270
271 edge.link_count-=1;
272
273 return self.update_best_link(edge)
274}
275
276fn updateLinkForNode(&mut self,edge:&mut edge_t, srcPort:u32, dstPort:u32, metric:u16)->bool {
278 let idx = self.find_link_from_node(edge, srcPort, dstPort);
279
280 if idx == u16::MAX {
281 return false
282 }
283
284 if edge.links[idx as usize].metric == metric as u32 {
285 return false
286 }
287 edge.links[idx as usize].metric = metric as u32;
288
289 return self.update_best_link(edge)
290}
291
292pub fn AddEdge(&mut self,src_node_id:u32,srcPort:u32, dst_node_id:u32, dstPort:u32, metric:u16)->errcode::RESULT {
294
295 let idxSrc = match self.getIndexById(src_node_id) {
296 None=>return errcode::ERROR_NOT_FOUND,
297 Some(v)=>v as usize,
298 };
299 let idxDst = match self.getIndexById(dst_node_id) {
300 None=>return errcode::ERROR_NOT_FOUND,
301 Some(v)=>v as usize,
302 };
303
304 let cm=unsafe {&mut *self.cost_matrix};
306 cm[idxSrc][idxDst].changed = self.addLinkForNode(&mut cm[idxSrc][idxDst].edge, srcPort, dstPort, metric);
307
308 return errcode::RESULT_SUCCESS
311}
312
313pub fn DeleteEdge(&mut self,src_node_id:u32, srcPort:u32, dst_node_id:u32, dstPort:u32)->errcode::RESULT {
315
316 let idxSrc = match self.getIndexById(src_node_id) {
317 None=>return errcode::ERROR_NOT_FOUND,
318 Some(v)=>v as usize,
319 };
320 let idxDst = match self.getIndexById(dst_node_id) {
321 None=>return errcode::ERROR_NOT_FOUND,
322 Some(v)=>v as usize,
323 };
324
325 let cm=unsafe {&mut *self.cost_matrix};
326 cm[idxSrc][idxDst].changed = self.deleteLinkForNode(&mut cm[idxSrc][idxDst].edge, srcPort, dstPort);
327 return errcode::RESULT_SUCCESS
328}
329
330pub fn UpdateEdge(&mut self,src_node_id:u32, srcPort:u32, dst_node_id:u32, dstPort:u32, metric:u16)->errcode::RESULT {
332 let idxSrc = match self.getIndexById(src_node_id) {
333 None=>return errcode::ERROR_NOT_FOUND,
334 Some(v)=>v as usize,
335 };
336 let idxDst = match self.getIndexById(dst_node_id) {
337 None=>return errcode::ERROR_NOT_FOUND,
338 Some(v)=>v as usize,
339 };
340
341 let cm=unsafe {&mut *self.cost_matrix};
342 cm[idxSrc][idxDst].changed = self.updateLinkForNode(&mut cm[idxSrc][idxDst].edge, srcPort, dstPort, metric);
343
344
345 return errcode::RESULT_SUCCESS
346}
347
348pub fn CalcOneSrcPath(&mut self,src_node_id:u32)->errcode::RESULT {
350
351 let idxSrc = match self.getIndexById(src_node_id) {
352 None=>return errcode::ERROR_NOT_FOUND,
353 Some(v)=>v as usize,
354 };
355 let mut dist:Vec<u32>=Vec::with_capacity(SPF_MAX_NODE_NUM);
357 let mut c=0u32;
358 let mut alt=0u32;
359 let mut pq=priority_queue_t::new();
360
361
362 let cm=unsafe {&mut *self.cost_matrix};
363 let max_node_idx=(self.max_node_idx+1) as usize;
364 let prev = unsafe { &mut (&mut *self.path_vector)[idxSrc][0..max_node_idx]};
366 for n in 0..max_node_idx {
367 let k=n as usize;
368 if k == idxSrc {
369 c = 0;
370 } else {
371 c = METRIC_INFINITY as u32;}
373 dist.push(c);
374 prev[k].clear();
375 prev[k].push(u16::MAX);
376
377 pq.push_nosort(k as usize,cm[idxSrc][k].edge.metric);
380 }
381 pq.sort();
382 while pq.len()>0 {
387 let u= match pq.pop_min() { None=>break,
389 Some(v)=>v,
390 };
391
392 for idx in 0..pq.len() {
393 let v = match pq.get_item_by_index(idx) {
394 None=>continue,
395 Some(v)=>v,
396 };
397
398 let metric = unsafe { cm.get_unchecked(u.node_idx).get_unchecked(v.node_idx).edge.metric};
399 if metric >= METRIC_INFINITY as u32 {
401 continue
402 }
403 alt = unsafe { dist.get_unchecked(u.node_idx as usize)} + metric;
404 if alt>=METRIC_INFINITY as u32 {
405 continue
406 }
407 if alt < dist[v.node_idx as usize] {
408 dist[v.node_idx as usize] = alt;
409 prev[v.node_idx as usize][0] = u.node_idx as u16;
410 pq.decrease_priority(idx, alt);
411 }
412 }
413
414 }
415
416 return errcode::RESULT_SUCCESS
417}
418
419pub fn get_spf_path(&mut self,src_node_id:u32, dst_node_id:u32)->Option<path_t> {
421 let idxSrc = match self.getIndexById(src_node_id) {
422 None=>return None,
423 Some(v)=>v as u16,
424 };
425 let idxDst = match self.getIndexById(dst_node_id) {
426 None=>return None,
427 Some(v)=>v as u16,
428 };
429
430 let tPath = self.constructPath(idxSrc as u16, idxDst);
432
433 return tPath
434}
435
436pub fn calc_all_path(&mut self)->errcode::RESULT {
440 let mut ids=Vec::new();
441 for (node_id,_) in self.id2idx.iter() {
442 ids.push(node_id.clone());
443 }
444 for id in ids {
447 self.CalcOneSrcPath(id);
448 }
449
450 return errcode::RESULT_SUCCESS
451}
452
453#[inline(always)]
454fn get_edge_metric(&self,src_node_idx:u16,dst_node_idx:u16)->u32 {
455 if src_node_idx>=SPF_MAX_NODE_NUM as u16 || dst_node_idx>=SPF_MAX_NODE_NUM as u16 {
456 return METRIC_INFINITY as u32
457 }
458 let cm=unsafe {&mut *self.cost_matrix};
459 return cm[src_node_idx as usize][dst_node_idx as usize].edge.metric;
460}
461
462fn constructPath(&mut self, src:u16, dst:u16)->Option<path_t> {
464
465 if src==dst || src>=SPF_MAX_NODE_NUM as u16 || dst>=SPF_MAX_NODE_NUM as u16 {
466 return None;
467 }
468 let max_node_idx=(self.max_node_idx+1) as usize;
469 let prev=&mut unsafe {&mut *self.path_vector}[src as usize][0..max_node_idx];
470 if prev.len()==0 {
471 return None;
472 }
473 let mut rPath=path_t::new();
475
476 let mut cur = dst;
477 let mut next=dst;
478 let cm=unsafe {&mut *self.cost_matrix};
479 while cur != u16::MAX {
480 let dst_node = match self.get_nodeid_by_idx(cur) {
481 None=> {
482 next=cur;
483 cur = prev[cur as usize][0];
484 continue
485 },
486 Some(i)=>i,
487 };
488 let src_node = match self.get_nodeid_by_idx(prev[cur as usize][0]) {
489 None=>{
490 break;
491 },
492 Some(i)=>i,
493 };
494 let edge = vec![path_edge_t {
495 dst_node_id:dst_node,
496 src_port_id:0,
497 dst_port_id:0,
498 metric:self.get_edge_metric(cur,next),
499 }];
500 let mut e = path_node_t{src_node_id: src_node, edges:edge};
501
502 if cur == src {
503 break
504 }
505
506 if cur < max_node_idx as u16 && prev[cur as usize][0] != u16::MAX {
507 let pEdge = &cm[prev[cur as usize][0] as usize][cur as usize].edge;
508 e.edges[0].metric = pEdge.metric;
509 e.edges[0].src_port_id = pEdge.links[pEdge.best_link as usize].src_port_id;
510 e.edges[0].dst_port_id = pEdge.links[pEdge.best_link as usize].dst_port_id;
511 rPath.push(e);
512 } else {
513 break
514 }
515 next=cur;
516 cur = prev[cur as usize][0];
517
518 }
519
520 if rPath.len()==0 {
521 return None;
522 }
523 rPath.reverse();
524
525 return Some(rPath)
526
527}
528
529pub fn print_stats(&self) {
530 println!("Total Node={}, idToIdxMap={}, idxToIdMap={}\n",
531 self.node_count, self.id2idx.len(), self.idx2id.len());
532 for i in 0..self.node_count {
534 let idx = i as i32;
535 let id = match self.idx2id.get(&idx) {
536 None=>u32::MAX,
537 Some(v)=>*v,
538 };
539
540 println!("Idx={},IdxToId[{}]={}\n", i, idx, id);
541 }
542}
543
544
545}
546
547impl Drop for spf_matrix_t {
548 fn drop(&mut self) {
549 unsafe {
550 alloc::dealloc(self.cost_matrix as * mut u8,
551 alloc::Layout::from_size_align_unchecked(SPF_MAX_NODE_NUM*SPF_MAX_NODE_NUM*mem::size_of::<edge_info_t>(), 1));
552
553 alloc::dealloc(self.path_vector as * mut _,
554 alloc::Layout::from_size_align_unchecked(SPF_MAX_NODE_NUM*SPF_MAX_NODE_NUM*mem::size_of::<path_t>(), 1));
555 }
556 }
557}
558
559pub fn print_path(tPath:&path_t) {
561
562 let pl = tPath.len();
563 let mut sPath = String::default();
564 for i in 0..pl{
565 sPath = format!("{}:[{}:{}-->{}:{},Metric={}]", sPath, tPath[i].src_node_id, tPath[i].edges[0].src_port_id,
566 tPath[i].edges[0].dst_node_id, tPath[i].edges[0].dst_port_id, tPath[i].edges[0].metric)
567 }
568 if pl>0 {
569 println!("Path_len={}, from {} to {}, path:{}\n", pl, tPath[0].src_node_id, tPath[pl-1].edges[0].dst_node_id, sPath);
570 } else {
571 println!("path length is zero!");
572 }
573
574
575}
576