void CacheResultsTest::computeCLLRetrivingPerfor(int queryGraphId, std::vector<std::vector<CacheEmbeddingNode *>> * cachedLinkedLists, double * linkedListRetriTime) { AdjacenceListsGRAPH * queryGraph = &(*queryGraphVector)[queryGraphId]; comboVertexMapping = new CacheEmbeddingNode*[queryGraph->getComboGraph()->size()]; for (int i = 0; i < queryGraph->getComboGraph()->size(); i++) { comboVertexMapping[i] = NULL; } TimeUtility llTime; llTime.StartCounterMill(); CacheEmbeddingNode * comboVertexStarting = (*cachedLinkedLists)[queryGraphId][queryGraph->getDFSComboVertexOrder()->at(0)]; while (comboVertexStarting != NULL) { comboVertexMapping[queryGraph->getDFSComboVertexOrder()->at(0)] = comboVertexStarting; recursiveEnumLinkedLists(1, queryGraph); comboVertexStarting = comboVertexStarting->adj; } (*linkedListRetriTime) += llTime.GetCounterMill(); delete[] comboVertexMapping; }
/* * With the partial embeddings ready for this query graph, we are ready to process the joining process * The joining process is also a recursively enumeration process */ void RecurParEmbConstruct::recursiveComputePartialEmbedding(int matchedToOrderIndex, int selfJoinOrderIndex) { if ((*numberOfEmbeddings)[queryGraph->graphId] >= GlobalConstant::G_SUFFICIENT_NUMBER_EMBEDDINGS || (*numberOfEmbeddings)[queryGraph->graphId]==-1) { return; } /***************************************** * Terminate conditions * *****************************************/ if (mappedDataVertexSet.size() == queryGraph->getNumberOfVertexes()) { if (checkPartialEmbeddingUncoveredEdge()) { /* * We got a full embedding by only use the caches. Add it. */ (*numberOfEmbeddings)[queryGraph->graphId] ++; /* * We cache the results if and only if it has some children */ if ((*patternContainmentMap)[queryGraph->graphId].children.size() != 0) { cachedResultLists->addEmbeddingToCache(queryGraph, partialEmbedding); } } return; } if (matchedToOrderIndex == joiningOrder->size()) { /* * we iterate to the end of all its minimum query cover parents */ if (matchedToOrderIndex > 0 && mappedDataVertexSet.size() == 0) { /* * it has parents, however, we cannot get any partial embedding from its parent caches, that means, the query graph wouldn't have any embeddings */ return; } else { /* * @subgraph isomorphism. pass it * We only save the cache results if and only if this graph has pcm children */ if (checkPartialEmbeddingUncoveredEdge()) { // Call subgraph isomorphism algorithm runSubgraphIsomorphismSearch(); } return; } } /***************************************** * Set the parent graph in this round *****************************************/ int parentQueryGraphId = joiningOrder->at(matchedToOrderIndex); AdjacenceListsGRAPH * parentQueryGraph = NULL; if (parentQueryGraphId < queryGraphVector->size()) { parentQueryGraph = &(*queryGraphVector)[parentQueryGraphId]; } else { parentQueryGraph = &(*newlyGeneratedGraphVector)[parentQueryGraphId - queryGraphVector->size()]; } std::vector<int> * parentDFSComboVertexOrder = parentQueryGraph->getDFSComboVertexOrder(); std::vector<ComboNODE> * parentComboGraph = parentQueryGraph->getComboGraph(); /* * Find the mappings of this parent graph */ std::map<int, std::vector<std::vector<int>>>::iterator vertexMappingMapIterator = (*patternContainmentMap)[parentQueryGraphId].containmentRelationshipMappingLists.find(queryGraph->graphId); /* * The mapping from the parent graph to this graph: (0->? 1->? 2->?) */ std::vector<int> * vertexMappingList = &vertexMappingMapIterator->second[selfJoinOrderIndex]; std::vector<EmbeddingNode *> parentComboEmbedding; for (int i = 0; i<parentComboGraph->size(); i++) { parentComboEmbedding.push_back(NULL); } /***************************************** * Prepare for Next recursieve query round *****************************************/ if (selfJoinOrderIndex == vertexMappingMapIterator->second.size() - 1) { matchedToOrderIndex++; selfJoinOrderIndex = 0; } else { selfJoinOrderIndex++; } /***************************************** * enumerate and compose the cached embeddings *****************************************/ EmbeddingNode * rootsMatchedVertices = (*comboLinkedLists)[parentQueryGraphId][0]; int * updatedVertexId = new int[5]; for (int i = 0; i<5; i++) { updatedVertexId[i] = -1; } while (rootsMatchedVertices != NULL) { if ((*numberOfEmbeddings)[queryGraph->graphId] >= GlobalConstant::G_SUFFICIENT_NUMBER_EMBEDDINGS || (*numberOfEmbeddings)[queryGraph->graphId]==-1) { return; } //1. Make sure no data vertices can be used multiple times AND the same data vertex to each query vertex bool isJoinable = true; for (int i = 0; i<(*parentComboGraph)[0].queryVertices.size(); i++) { int mappedQueryVertex = (*vertexMappingList)[(*parentComboGraph)[0].queryVertices[i]]; if (partialEmbedding[mappedQueryVertex] != -1) { // same data vertex to each query vertex if (partialEmbedding[mappedQueryVertex] != rootsMatchedVertices->comboMappingVertices[i]) { isJoinable = false; break; } } else { if (mappedDataVertexSet.find(rootsMatchedVertices->comboMappingVertices[i]) == mappedDataVertexSet.end()) { // no data vertices can be used multiple times partialEmbedding[mappedQueryVertex] = rootsMatchedVertices->comboMappingVertices[i]; mappedDataVertexSet.insert(rootsMatchedVertices->comboMappingVertices[i]); updatedVertexId[i] = mappedQueryVertex; } else { isJoinable = false; break; } } } if (isJoinable) { //2. start iteratiing inner embeddings parentComboEmbedding[(*parentDFSComboVertexOrder)[0]] = rootsMatchedVertices; enumberateEmbeddingLinkedList(1, matchedToOrderIndex, selfJoinOrderIndex, parentComboGraph, parentDFSComboVertexOrder, vertexMappingList, &parentComboEmbedding); } //3. restore to initial status for (int i = 0; i<5; i++) { if (updatedVertexId[i] != -1) { mappedDataVertexSet.erase(partialEmbedding[updatedVertexId[i]]); partialEmbedding[updatedVertexId[i]] = -1; updatedVertexId[i] = -1; } } //4. next root trial rootsMatchedVertices = rootsMatchedVertices->adj; } //5. release memory delete[] updatedVertexId; }