void changeRoot(Graph *graph, int index) { bool is_root = graph->nodes.items[index].root; if(is_root) removeRootNode(graph, index); else addRootNode(graph, index); graph->nodes.items[index].root = !is_root; }
//-------------------------------------------------------------------------- // MG_CN_MODIFY Bool District::load(const Char16* districtListFileName/* = L"MapData\\DistrictList.csv"*/, const Char16* districtTreeFileName/* = L"MapData\\DistrictTree.csv"*/, IMGExternalPackManager* packManager/* = NULL*/) { // MG_CN_MODIFY mDistrictList.loadCsv(districtListFileName, packManager); mDistrictTree.loadCsv(districtTreeFileName, packManager); DYNAMIC_ASSERT(false == mDistrictList.getDistrictList()->empty() && false == mDistrictTree.getDistrictTreeList()->empty()); //首先搜索【根政区】 std::map<DistrictTreeIdType, DistrictTreeInfo*>* allTree = mDistrictTree.getDistrictTreeList(); for (std::map<DistrictTreeIdType, DistrictTreeInfo*>::iterator iter = allTree->begin(); iter != allTree->end(); ++iter) { DistrictTreeInfo* tempTreeInfo = iter->second; if (NULL == tempTreeInfo) { DYNAMIC_ASSERT(0); continue; } DistrictListCsvInfo* master = mDistrictList.getDistrictInfo(tempTreeInfo->masterDistrictId); DistrictListCsvInfo* slave = mDistrictList.getDistrictInfo(tempTreeInfo->slaveDistrictId); if (NULL != slave) { slave->setMaster(master); } if (NULL != master) { master->addNewSlave(slave); } } //把所有的根节点找出来 std::map<DistrictIdType, DistrictTreeInfo*>* districtList = mDistrictTree.getDistrictTreeList(); for (std::map<DistrictIdType, DistrictTreeInfo*>::iterator iter = districtList->begin(); iter != districtList->end(); ++iter) { DistrictTreeInfo* tempTreeInfo = iter->second; if (NULL != tempTreeInfo && RT_ROOT == tempTreeInfo->rootType) { DistrictListCsvInfo* rootNode = mDistrictList.getDistrictInfo(tempTreeInfo->masterDistrictId); if (NULL != rootNode && NULL != rootNode->getMaster()) { DYNAMIC_ASSERT(0); //表示 根节点有他的父亲节点, csv表填写错误 continue; } addRootNode(rootNode); } } DYNAMIC_ASSERT(false == mTree.empty()); print(); return true; }
int addNode(Graph *graph, bool root, HostLabel label) { Node node; node.root = root; node.label = label; node.first_out_edge = -1; node.second_out_edge = -1; node.first_in_edge = -1; node.second_in_edge = -1; node.out_edges = makeIntArray(0); node.in_edges = makeIntArray(0); node.outdegree = 0; node.indegree = 0; node.matched = false; int index = addToNodeArray(&(graph->nodes), node); if(root) addRootNode(graph, index); graph->number_of_nodes++; return index; }
PassRefPtr<InspectorObject> HeapGraphSerializer::finish() { addRootNode(); pushUpdate(); String metaString = "{" "\"node_fields\":[" "\"type\"," "\"name\"," "\"id\"," "\"self_size\"," "\"edge_count\"" "]," "\"node_types\":[" "[]," // FIXME: It is a fallback for Heap Snapshot parser. In case of Native Heap Snapshot it is a plain string id. "\"string\"," "\"number\"," "\"number\"," "\"number\"" "]," "\"edge_fields\":[" "\"type\"," "\"name_or_index\"," "\"to_node\"" "]," "\"edge_types\":[" "[]," "\"string_or_number\"," "\"node\"" "]" "}"; RefPtr<InspectorValue> metaValue = InspectorValue::parseJSON(metaString); RefPtr<InspectorObject> meta; metaValue->asObject(&meta); ASSERT(meta); meta->setObject("type_strings", m_typeStrings); return meta.release(); }
//增加某号码 BOOL addCallNumber(Tree *pTree, NodeType *callNum, int len) { int i; TreeNode *ptempNode = pTree->root; if (callNum == NULL || pTree == NULL) return FALSE; if (ptempNode == NULL) { ptempNode = addRootNode(pTree, callNum[0]);//增加头节点 if (ptempNode == NULL) return FALSE; } for (i=1; i<len; i++) { if (ptempNode == NULL) return FALSE; if (ptempNode->child == NULL || ptempNode->child->val > callNum[i]) { ptempNode = addChildNode(ptempNode, callNum[i]); continue; } //找出增加节点的位置 ptempNode = findNearBrotherNode(ptempNode, callNum[i]); if (ptempNode != NULL) { if (ptempNode->val != callNum[i]) ptempNode = addBortherNode(ptempNode, callNum[i]); } } return TRUE; }
// parse the heap to find valid objects and initialize metadata, then // add edges for every known root pointer and every known obj->obj ptr. HeapGraph makeHeapGraph(bool include_free) { HeapGraph g; PtrMap blocks; // parse the heap once to create a PtrMap for pointer filtering. Create // one node for every parsed block, including NativeData and AsyncFuncFrame // blocks. Only include free blocks if requested. MM().forEachHeader([&](Header* h, size_t alloc_size) { if (h->kind() != HeaderKind::Free || include_free) { blocks.insert(h, alloc_size); // adds interval [h, h+alloc_size[ } }); blocks.prepare(); // initialize nodes by iterating over PtrMap's regions g.nodes.reserve(blocks.size()); blocks.iterate([&](const Header* h, size_t size) { type_scan::Index ty; switch (h->kind()) { case HeaderKind::NativeData: ty = h->native_.typeIndex(); break; case HeaderKind::Resource: ty = h->res_.typeIndex(); break; case HeaderKind::SmallMalloc: case HeaderKind::BigMalloc: ty = h->malloc_.typeIndex(); break; default: ty = type_scan::kIndexUnknown; break; } g.nodes.push_back( HeapGraph::Node{h, size, false, ty, -1, -1} ); }); // find root nodes type_scan::Scanner scanner; iterateRoots([&](const void* h, size_t size, type_scan::Index tyindex) { // it's important that we actually scan each root node before // returning, since at least one will be the C++ stack, and some // nodes will only exist for the duration of the call to this lambda, // for example EphemeralPtrWrapper<T>. addRootNode(g, blocks, scanner, h, size, tyindex); }); // find heap->heap pointers for (size_t i = 0, n = g.nodes.size(); i < n; i++) { if (g.nodes[i].is_root) continue; auto h = g.nodes[i].h; scanHeader(h, scanner); auto from = blocks.index(h); assert(from == i); scanner.finish( [&](const void* p) { // definitely a ptr, but maybe interior, and maybe not counted if (auto r = blocks.region(p)) { addPtr(g, from, blocks.index(r), HeapGraph::Implicit, UnknownOffset); } }, [&](const void* p, std::size_t size) { conservativeScan(p, size, [&](const void** addr, const void* ptr) { if (auto r = blocks.region(ptr)) { auto to = blocks.index(r); auto offset = uintptr_t(addr) - uintptr_t(h); addPtr(g, from, to, HeapGraph::Ambiguous, offset); } }); }, [&](const void** addr) { if (auto r = blocks.region(*addr)) { auto to = blocks.index(r); auto offset = uintptr_t(addr) - uintptr_t(h); addPtr(g, from, to, HeapGraph::Counted, offset); } } ); } g.nodes.shrink_to_fit(); g.ptrs.shrink_to_fit(); g.root_ptrs.shrink_to_fit(); g.root_nodes.shrink_to_fit(); return g; }
void HeapGraphSerializer::finish() { addRootNode(); pushUpdate(); }