void radix_tree_clear_tag(struct radix_tree *t, uint64_t idx, radix_tree_tagid_t tagid) { struct radix_tree_path path; const unsigned int tagmask = tagid_to_mask(tagid); void **vpp; int i; vpp = radix_tree_lookup_ptr(t, idx, &path, false, 0); KASSERT(vpp != NULL); KASSERT(*vpp != NULL); KASSERT(path.p_lastidx == t->t_height); KASSERT(vpp == path_pptr(t, &path, path.p_lastidx)); /* * if already cleared, nothing to do */ if ((entry_tagmask(*vpp) & tagmask) == 0) { return; } /* * clear the tag only if no children have the tag. */ for (i = t->t_height; i >= 0; i--) { void ** const pptr = (void **)path_pptr(t, &path, i); void *entry; KASSERT(pptr != NULL); entry = *pptr; KASSERT((entry_tagmask(entry) & tagmask) != 0); *pptr = entry_compose(entry_ptr(entry), entry_tagmask(entry) & ~tagmask); /* * check if we should proceed to process the next level. */ if (0 < i) { struct radix_tree_node *n = path_node(t, &path, i - 1); if ((any_children_tagmask(n) & tagmask) != 0) { break; } } } }
gang_lookup_scan(struct radix_tree *t, struct radix_tree_path *path, void **results, unsigned int maxresults, const unsigned int tagmask, bool reverse) { /* * we keep the path updated only for lastidx-1. * vpp is what path_pptr(t, path, lastidx) would be. */ void **vpp; unsigned int nfound; unsigned int lastidx; /* * set up scan direction dependant constants so that we can iterate * n_ptrs as the following. * * for (i = first; i != guard; i += step) * visit n->n_ptrs[i]; */ const int step = reverse ? -1 : 1; const unsigned int first = reverse ? RADIX_TREE_PTR_PER_NODE - 1 : 0; const unsigned int last = reverse ? 0 : RADIX_TREE_PTR_PER_NODE - 1; const unsigned int guard = last + step; KASSERT(maxresults > 0); KASSERT(&t->t_root == path_pptr(t, path, 0)); lastidx = path->p_lastidx; KASSERT(lastidx == RADIX_TREE_INVALID_HEIGHT || lastidx == t->t_height || !entry_match_p(*path_pptr(t, path, lastidx), tagmask)); nfound = 0; if (lastidx == RADIX_TREE_INVALID_HEIGHT) { if (reverse) { lastidx = 0; vpp = path_pptr(t, path, lastidx); goto descend; } return 0; } vpp = path_pptr(t, path, lastidx); while (/*CONSTCOND*/true) { struct radix_tree_node *n; unsigned int i; if (entry_match_p(*vpp, tagmask)) { KASSERT(lastidx == t->t_height); /* * record the matching non-NULL leaf. */ results[nfound] = entry_ptr(*vpp); nfound++; if (nfound == maxresults) { return nfound; } } scan_siblings: /* * try to find the next matching non-NULL sibling. */ if (lastidx == 0) { /* * the root has no siblings. * we've done. */ KASSERT(vpp == &t->t_root); break; } n = path_node(t, path, lastidx - 1); if (*vpp != NULL && n->n_nptrs == 1) { /* * optimization; if the node has only a single pointer * and we've already visited it, there's no point to * keep scanning in this node. */ goto no_siblings; } for (i = vpp - n->n_ptrs + step; i != guard; i += step) { KASSERT(i < RADIX_TREE_PTR_PER_NODE); if (entry_match_p(n->n_ptrs[i], tagmask)) { vpp = &n->n_ptrs[i]; break; } } if (i == guard) { no_siblings: /* * not found. go to parent. */ lastidx--; vpp = path_pptr(t, path, lastidx); goto scan_siblings; } descend: /* * following the left-most (or right-most in the case of * reverse scan) child node, decend until reaching the leaf or * an non-matching entry. */ while (entry_match_p(*vpp, tagmask) && lastidx < t->t_height) { /* * save vpp in the path so that we can come back to this * node after finishing visiting children. */ path->p_refs[lastidx].pptr = vpp; n = entry_ptr(*vpp); vpp = &n->n_ptrs[first]; lastidx++; } } return nfound; }
bool FindCandidateBackup(GraphTopo *p_graph, Request * p_request, vector<int> &T) { typedef pair<int, int> P; vector<int> dist((*p_graph).nodeNum, (-1)); vector<int> hop((*p_graph).nodeNum, (-1)); vector<int> path_node((*p_graph).nodeNum, (-1)); vector<int> path_edge((*p_graph).nodeNum, (-1)); priority_queue<P, vector<P>, greater<P> > que; dist[(*p_graph).source] = 0; hop[(*p_graph).source] = 0; que.push(P(0, (*p_graph).source)); while (!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if (dist[v] < p.first) continue; for (unsigned int i = 0; i < (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList.size(); i++) { EdgeClass &e = p_graph->getithEdge( (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList[i]); // if (!A.at(e.id)) //p_request->APMustNotPassEdges[e.id]) // continue; if (!p_request->BPMustNotPassEdges4AP[e.id]) continue; int addcost; if (!p_request->BPMustNotPassEdgesRLAP[e.id]) { addcost = M; } else addcost = e.cost; if (-1 == dist[e.to]) { dist[e.to] = dist[v] + addcost; //e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] > (dist[v] + addcost)) { dist[e.to] = dist[v] + addcost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] == (dist[v] + addcost)) { if (hop[e.to] > (hop[v] + 1)) { dist[e.to] = dist[v] + addcost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } } } } } } if (-1 == dist[(*p_graph).destination]) { return false; } else { int now; int next; now = (*p_graph).destination; vector<int> midnode; vector<int> midedge; next = path_node[now]; midnode.push_back(now); while (next != -1) { midnode.push_back(next); midedge.push_back(path_edge[now]); if (!p_request->BPMustNotPassEdgesRLAP[path_edge[now]]) T.push_back(p_graph->getithEdge(path_edge[now]).ithsrlg); (*p_request).BPCostSum += p_graph->getithEdge(path_edge[now]).cost; now = next; next = path_node[now]; } for (int k = (midnode.size() - 1); k >= 0; k--) { p_request->BP_PathNode.push_back(midnode[k]); } for (int k = (midedge.size() - 1); k >= 0; k--) { p_request->BP_PathEdge.push_back(midedge[k]); } return true; } return false; }
bool ShortestPath(GraphTopo *p_graph, Request * p_request, vector<bool>&A) { typedef pair<int, int> P; vector<int> dist((*p_graph).nodeNum, (-1)); vector<int> hop((*p_graph).nodeNum, (-1)); vector<int> path_node((*p_graph).nodeNum, (-1)); vector<int> path_edge((*p_graph).nodeNum, (-1)); priority_queue<P, vector<P>, greater<P> > que; dist[(*p_graph).source] = 0; hop[(*p_graph).source] = 0; que.push(P(0, (*p_graph).source)); while (!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if (dist[v] < p.first) continue; for (unsigned int i = 0; i < (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList.size(); i++) { EdgeClass &e = p_graph->getithEdge( (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList[i]); if (!A.at(e.id)) //p_request->APMustNotPassEdges[e.id]) continue; if (-1 == dist[e.to]) { dist[e.to] = dist[v] + e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] > (dist[v] + e.cost)) { dist[e.to] = dist[v] + e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] == (dist[v] + e.cost)) { if (hop[e.to] > (hop[v] + 1)) { dist[e.to] = dist[v] + e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } } } } } } if (-1 == dist[(*p_graph).destination]) { return false; } else { int now; int next; now = (*p_graph).destination; vector<int> midnode; vector<int> midedge; next = path_node[now]; midnode.push_back(now); p_request->APSrlgs.clear(); // while (next != -1) { // (*p_request).AP_PathNode.push_back(next); // (*p_request).AP_PathEdge.push_back(path_edge[now]); midnode.push_back(next); midedge.push_back(path_edge[now]); (*p_request).BPMustNotPassEdges4AP[path_edge[now]] = false; if (-1 != p_graph->getithEdge(path_edge[now]).ithsrlg) (*p_request).APSrlgs.push_back( p_graph->getithEdge(path_edge[now]).ithsrlg); now = next; next = path_node[now]; } for (int k = (midnode.size() - 1); k >= 0; k--) { p_request->AP_PathNode.push_back(midnode[k]); } for (int k = (midedge.size() - 1); k >= 0; k--) { p_request->AP_PathEdge.push_back(midedge[k]); } (*p_request).APCostSum = dist[(*p_graph).destination]; (*p_request).APHopSum = hop[(*p_graph).destination]; sort(p_request->APSrlgs.begin(), p_request->APSrlgs.end()); vector<int>::iterator pos; pos = unique(p_request->APSrlgs.begin(), p_request->APSrlgs.end()); p_request->APSrlgs.erase(pos, p_request->APSrlgs.end()); for (unsigned int i = 0; i < (*p_request).APSrlgs.size(); i++) { int srlg = (*p_request).APSrlgs[i]; for (unsigned int j = 0; j < (*p_graph).srlgGroups[srlg].srlgMember.size(); j++) { int srlgmem = (*p_graph).srlgGroups[srlg].srlgMember[j]; if ((*p_request).BPMustNotPassEdges4AP[srlgmem] && (*p_request).BPMustNotPassEdgesRLAP[srlgmem]) { (*p_request).BPMustNotPassEdgesRLAP[srlgmem] = false; p_request->RLAP_PathEdge.push_back(srlgmem); } } } return true; } }
bool findAP_orderedegde_dijastra(GraphTopo *p_graph, Request *p_request, int source, int destination, vector<int>& node_vis, vector<int>& edge_vis) { typedef pair<int, int> P; vector<int> dist((*p_graph).nodeNum, (-1)); vector<int> hop((*p_graph).nodeNum, (-1)); vector<int> path_node((*p_graph).nodeNum, (-1)); vector<int> path_edge((*p_graph).nodeNum, (-1)); priority_queue<P, vector<P>, greater<P> > que; unsigned int len; dist[source] = 0; hop[source] = 0; que.push(P(0, source)); while (!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if (dist[v] < p.first) continue; len = (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList.size(); for (unsigned int i = 0; i < len; i++) { EdgeClass &e = p_graph->getithEdge( (*p_graph).ftopo_r_Node_c_EdgeList[v].edgeList[i]); if (!p_request->APMustNotPassEdges[e.id]) continue; if (-1 == dist[e.to]) { dist[e.to] = dist[v] + e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] > (dist[v] + e.cost)) { dist[e.to] = dist[v] + e.cost; hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } else { if (dist[e.to] == (dist[v] + e.cost)) { if (hop[e.to] > (hop[v] + 1)) { hop[e.to] = hop[v] + 1; path_node[e.to] = v; path_edge[e.to] = e.id; que.push(P(dist[e.to], e.to)); } } } } } } if (-1 == dist[destination]) { return false; } else { int next = destination; while (source != next) { if ((-1 != node_vis[next])) { //erase all edge whose out-edge is initial source node; return false; } else { node_vis[next] = path_node[next]; edge_vis[next] = path_edge[next]; } next = path_node[next]; } } return true; }