void qspn_reset_counters(u_char levels) { /* Reset the qspn counters */ qspn_time_reset(0, levels, levels); qspn_reset_gcount(qspn_gnode_count, GCOUNT_LEVELS, 1); qspn_reset_gcount(qspn_old_gcount, GCOUNT_LEVELS, 1); }
/* * radar_remove_old_rnodes * * It removes all the old rnodes ^_- It store in rnode_delete[level] the number * of deleted rnodes. This function is used by radar_update_map */ int radar_remove_old_rnodes(char *rnode_deleted) { map_node *node, *root_node, *broot_node; map_gnode *gnode; map_bnode *bnode; ext_rnode *e_rnode = 0; ext_rnode_cache *erc; struct qspn_buffer *qb; struct rnode_list *rnl; int i, e, node_pos, bm, rnode_pos, bnode_rnode_pos, root_node_pos; int broot_node_pos; int level, blevel, external_node, total_levels, first_level; void *void_map, *void_gnode; if (!me.cur_node->links) return 0; for (i = 0; i < me.cur_node->links; i++) { node = (map_node *) me.cur_node->r_node[i].r_node; if (!(node->flags & MAP_VOID)) /* The rnode is not really dead! */ continue; if (node->flags & MAP_ERNODE) { e_rnode = (ext_rnode *) node; external_node = 1; total_levels = e_rnode->quadg.levels; first_level = 1; quadg_setflags(&e_rnode->quadg, MAP_VOID); } else { external_node = 0; total_levels = 1; first_level = 0; } for (level = first_level; level < total_levels; level++) { qspn_set_map_vars(level, 0, &root_node, &root_node_pos, 0); blevel = level - 1; /* delete the rnode from the rnode_list */ rnl = rnl_find_node(rlist, node); rnl_del(&rlist, &rlist_counter, rnl, 1); /* * Just delete it from all the maps. */ if (!level && !external_node) { void_map = me.int_map; node_pos = pos_from_node(node, me.int_map); rnode_pos = i; debug(DBG_NORMAL, "radar: The node %d is dead", node_pos); /* delete it from the int_map and update the gcount */ map_node_del(node); qspn_dec_gcount((int *) qspn_gnode_count, level + 1, 1); /* delete the route */ rt_update_node(0, node, 0, 0, 0, level); send_qspn_now[level] = 1; } else { void_map = me.ext_map; gnode = e_rnode->quadg.gnode[_EL(level)]; /** delete the direct route to the ext_node */ if (level == 1) rt_update_node(&e_rnode->quadg.ipstart[0], e_rnode, 0, 0, 0, /*level=0 */ 0); /**/ void_gnode = (void *) gnode; if (!void_gnode) continue; node_pos = pos_from_gnode(gnode, me.ext_map[_EL(level)]); rnode_pos = g_rnode_find((map_gnode *) root_node, gnode); debug(DBG_NORMAL, "The ext_node (gid %d, lvl %d) is" " dead", e_rnode->quadg.gid[level], level); /* bnode_map update */ for (e = 0; blevel >= 0; blevel--) { qspn_set_map_vars(blevel, 0, &broot_node, &broot_node_pos, 0); bm = map_find_bnode(me.bnode_map[blevel], me.bmap_nodes[blevel], broot_node_pos); if (bm == -1) continue; bnode = &me.bnode_map[blevel][bm]; bnode_rnode_pos = rnode_find(bnode, (map_node *) e_rnode-> quadg.gnode[_EL(level)]); if (bnode_rnode_pos != -1) rnode_del(bnode, bnode_rnode_pos); if (!bnode->links) { me.bnode_map[blevel] = map_bnode_del(me.bnode_map[blevel], &me.bmap_nodes[blevel], bnode); broot_node->flags &= ~MAP_BNODE; } else e = 1; } if (!e) /* We are no more a bnode */ me.cur_node->flags &= ~MAP_BNODE; /* If we were the only bnode which bordered on * `gnode', delete it from the map */ if (map_find_bnode_rnode (me.bnode_map[level - 1], me.bmap_nodes[level - 1], gnode) == -1) { qspn_dec_gcount((int *) qspn_gnode_count, level + 1, gnode->gcount); gmap_node_del(gnode); gnode_dec_seeds(&me.cur_quadg, level); /* update the seeds */ } /* Delete the entries from the routing table */ rt_update_node(0, 0, &e_rnode->quadg, 0, 0, level); send_qspn_now[level] = 1; } if (rnode_pos >= 0 && root_node->links > 0) rnode_del(root_node, rnode_pos); if (!root_node->links) { /* We are alone in the dark. Sigh. */ qspn_time_reset(level, level, FAMILY_LVLS); } else if (!external_node) erc_update_rnodepos(me.cur_erc, root_node, rnode_pos); /* Now we delete it from the qspn_buffer */ if (qspn_b[level]) { qb = qspn_b[level]; qb = qspn_b_find_rnode(qb, node); if (qb) qspn_b[level] = list_del(qspn_b[level], qb); } SET_BIT(rnode_deleted, level); } /* * Kick out the external_node from the root_node and destroy it * from the ext_rnode_cache */ if (external_node) { /* external rnode cache update */ erc = erc_find(me.cur_erc, e_rnode); if (erc) e_rnode_del(&me.cur_erc, &me.cur_erc_counter, erc); rnode_del(me.cur_node, i); } /* If the rnode we deleted from the root_node was swapped with * the last rnodes, we have to inspect again the same * root_node->r_node[ `i' ] rnode, because now it is another * rnode */ if (i != (me.cur_node->links + 1) - 1) i--; } if (!me.cur_node->links) { /* - Diary - * Tue Mar 14 07:29:58 CET 2006 * Damn! All my rnodes died, I am the last survivor in this * great lone land... I have to reset my memory... farewell! */ qspn_reset_counters(FAMILY_LVLS); } return 0; }