int rtree_insert_test() { ISpatialIndex *rtree; try { // Create a new storage manager with the provided base name and a 4K page size. //std::string baseName = "rtree"; //IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096); memfile = StorageManager::createNewMemoryStorageManager(); //StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*memfile, 100, false); // applies a main memory random buffer on top of the persistent storage manager // (LRU buffer, etc can be created the same way). // Create a new, empty, RTree with dimensionality 2, minimum load 70%, using "file" as // the StorageManager and the RSTAR splitting policy. id_type indexIdentifier; rtree = RTree::createNewRTree(*memfile, 0.7, 100, 100, MAX_DIM_NUM, SpatialIndex::RTree::RV_RSTAR, indexIdentifier); id_type id; uint32_t op; double x1, x2, y1, y2, z1, z2; double plow[3], phigh[3]; std::ifstream fin("/root/mbj/data/data"); while (fin) { fin >> op >> id >> x1 >> y1 >> z1 >> x2 >> y2 >> z2; if (! fin.good()) continue; // skip newlines, etc. if (op == RTREE_INSERT) { plow[0] = x1; plow[1] = y1; plow[2] = z1; phigh[0] = x2; phigh[1] = y2; phigh[2] = z2; Region r = Region(plow, phigh, 3); std::ostringstream os; os << r; std::string data = os.str(); rtree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id); } } } catch (Tools::Exception& e) { std::cerr << "******ERROR******" << std::endl; std::string s = e.what(); std::cerr << s << std::endl; return FALSE; } return TRUE; }
void process_input(struct partition_op &partop) { // build in memory Tree VecStreamReader vecstream(&vec); IStorageManager* memoryFile = StorageManager::createNewMemoryStorageManager(); id_type indexIdentifier = 0; ISpatialIndex* tree = RTree::createAndBulkLoadNewRTree(RTree::BLM_STR, vecstream, *memoryFile, fillFactor, indexCapacity, partop.bucket_size, 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier); // Traverse through each leaf node which is a partition MyQueryStrategy qs(&partop); tree->queryStrategy(qs); #ifdef DEBUGAREA Rectangle *tmp; double span[2]; double area_total; for (int k = 0; k < 2; k++) { span[k] = partop.high[k] - partop.low[k]; } // Normalize the data for (vector<Rectangle*>::iterator it = list_rec.begin() ; it != list_rec.end(); ++it) { tmp = *it; tmp->low[0] = (tmp->low[0] - partop.low[0]) / span[0]; tmp->low[1] = (tmp->low[1] - partop.low[1]) / span[1]; tmp->high[0] = (tmp->high[0] - partop.low[0]) / span[0]; tmp->high[1] = (tmp->high[1] - partop.low[1]) / span[1]; area_total += (tmp->high[0] - tmp->low[0]) * (tmp->high[1] - tmp->low[1]); } cerr << "Area total: " << area_total << endl; if (list_rec.size() > 0) { cerr << "Area covered: " << findarea(list_rec) << endl; } for (vector<Rectangle*>::iterator it = list_rec.begin() ; it != list_rec.end(); ++it) { delete *it; } list_rec.clear(); #endif /* This will fail the code the Data is already removed by VecStreamReader for (vector<RTree::Data*>::iterator it = vec.begin() ; it != vec.end(); ++it) { delete *it; }*/ vec.clear(); delete tree; delete memoryFile; }
void TestSpatialIndexSpeed(string& wayDBFilePath) { IStorageManager* diskfile = new CachedDiskStorageManager(wayDBFilePath); ISpatialIndex* tree = loadRTree(*diskfile, 1); high_resolution_clock::time_point t1 = high_resolution_clock::now(); GetAllWaysWithKey getAllWays("highway"); double min[3]{ 4.0, 52.0, 0.004 }; double max[3]{ 5.0, 53.0, 500.0 }; //double min[3]{ -180.0, -90.0, 0.0 }; //double max[3]{ 180.0, 90.0, 500.0 }; Region queryAABB(min, max, 3); tree->intersectsWithQuery(queryAABB, getAllWays); cout << "Num Ways returned: " << getAllWays.ways.size() << " " << endl; high_resolution_clock::time_point t2 = high_resolution_clock::now(); duration<double> time_span = duration_cast<duration<double>>(t2 - t1); cout << "Num Query took seconds: " << time_span.count() << " " << endl; }
// performs spatial join on the current tile (bucket) int join_bucket_spjoin(struct query_op &stop, struct query_temp &sttemp) { IStorageManager *storage = NULL; ISpatialIndex *spidx = NULL; bool selfjoin = stop.join_cardinality == 1 ? true : false; /* Indicates where original data is mapped to */ int idx1 = SID_1; int idx2 = selfjoin ? SID_1 : SID_2; int pairs = 0; // number of satisfied results double low[2], high[2]; // Temporary value placeholders for MBB try { vector<Geometry*> & poly_set_one = sttemp.polydata[idx1]; vector<Geometry*> & poly_set_two = sttemp.polydata[idx2]; int len1 = poly_set_one.size(); int len2 = poly_set_two.size(); #ifdef DEBUG cerr << "Bucket size: " << len1 << " joining with " << len2 << endl; #endif cerr << "Bucket size: " << len1 << " joining with " << len2 << endl; if (len1 <= 0 || len2 <= 0) { return 0; } /* Build index on the "second data set */ map<int, Geometry*> geom_polygons2; geom_polygons2.clear(); // Make a copy of the vector to map to build index (API restriction) for (int j = 0; j < len2; j++) { geom_polygons2[j] = poly_set_two[j]; } /* Handling for special nearest neighbor query */ // build the actual spatial index for input polygons from idx2 if (! build_index_geoms(geom_polygons2, spidx, storage)) { #ifdef DEBUG cerr << "Building index on geometries from set 2 has failed" << endl; #endif return -1; } for (int i = 0; i < len1; i++) { /* Extract minimum bounding box */ const Geometry* geom1 = poly_set_one[i]; const Envelope * env1 = geom1->getEnvelopeInternal(); low[0] = env1->getMinX(); low[1] = env1->getMinY(); high[0] = env1->getMaxX(); high[1] = env1->getMaxY(); if (stop.join_predicate == ST_DWITHIN) { low[0] -= stop.expansion_distance; low[1] -= stop.expansion_distance; high[0] += stop.expansion_distance; high[1] += stop.expansion_distance; } /* Regular handling */ Region r(low, high, 2); MyVisitor vis; vis.matches.clear(); /* R-tree intersection check */ spidx->intersectsWithQuery(r, vis); for (uint32_t j = 0; j < vis.matches.size(); j++) { /* Skip results that have been seen before (self-join case) */ if (selfjoin && ((vis.matches[j] == i) || // same objects in self-join (!stop.result_pair_duplicate && vis.matches[j] <= i))) { // duplicate pairs #ifdef DEBUG cerr << "skipping (selfjoin): " << j << " " << vis.matches[j] << endl; #endif continue; } const Geometry* geom2 = poly_set_two[vis.matches[j]]; const Envelope * env2 = geom2->getEnvelopeInternal(); if (join_with_predicate(stop, sttemp, geom1, geom2, env1, env2, stop.join_predicate)) { report_result(stop, sttemp, i, vis.matches[j]); pairs++; } } } } // end of try catch (Tools::Exception& e) { //catch (...) { std::cerr << "******ERROR******" << std::endl; #ifdef DEBUG cerr << e.what() << std::endl; #endif return -1; } // end of catch cerr << "Done with tile" << endl; delete spidx; delete storage; return pairs ; }
int main(int argc, const char* argv[]) { /* * Build 48 Index with Links */ // Load Circuit Experiment experiment; experiment.open(blue_config_filename); Microcircuit & microcircuit = experiment.microcircuit(); const Targets & targets = experiment.targets(); const Cell_Target target = targets.cell_target("Column"); microcircuit.load(target, NEURONS | MORPHOLOGIES); //Make Neuron Rtrees ISpatialIndex *neuronTrees[MORPHOLOGIES_COUNT]; string *morphologyLabels[MORPHOLOGIES_COUNT]; int cm=0; Morphologies & myMorphologies = microcircuit.morphologies(); Morphologies::iterator myMorphologiesEnd = myMorphologies.end(); for (Morphologies::iterator i = myMorphologies.begin(); i != myMorphologiesEnd; ++i) { morphologyLabels[cm] = i->label(); neuronTrees[cm] = RTree::createNewRTree (createNewMemoryStorageManager(), 0.7, 127, 127, 3,RTree::RV_RSTAR,indexIdentifier); cm++; } Neurons & myNeurons = microcircuit.neurons(); Neurons::iterator myNeuronsEnd = myNeurons.end(); for (Neurons::iterator i = myNeurons.begin(); i != myNeuronsEnd; ++i) { cm=0; for (cm=0;cm<MORPHOLOGIES_COUNT;cm++) if (strcmp(i->morphology().label(),morphologyLabels[cm])==0) break; Transform_3D<Micron> trafo = i->global_transform(); Sections mySections = i->morphology().all_sections(); Sections::iterator mySectionsEnd = mySections.end(); for (Sections::iterator s = mySections.begin(); s != mySectionsEnd; ++s) { Segments segments = s->segments(); Segments::const_iterator segments_end = segments.end(); for (Segments::const_iterator j = segments.begin(); j != segments_end ; ++j) { vect plow, phigh; get_segment_mbr (*j, trafo, &plow, &phigh); SpatialIndex::Region mbr = SpatialIndex::Region(plow.data(),phigh.data(),3); std::stringstream strStream; strStream << i->gid() <<"-"<< s->id()<< "-" << j->id(); neuronTrees[cm]->insertData (strStream.str().length(), (byte*)(strStream.str().c_str()), mbr, segmentid); } } } // Make Morphology Rtrees Morphologies & myMorphologies = microcircuit.morphologies(); Morphologies::iterator myMorphologiesEnd = myMorphologies.end(); for (Morphologies::iterator i = myMorphologies.begin(); i != myMorphologiesEnd; ++i) { cout << "Indexing Morphology: " << i->label(); string baseName = i->label(); IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096); ISpatialIndex *tree = RTree::createNewRTree (*diskfile, 0.7, 127, 127, 3,RTree::RV_RSTAR,indexIdentifier); indexIdentifier++; segmentid=0; Sections mySections = i->all_sections(); Sections::iterator mySectionsEnd = mySections.end(); for (Sections::iterator s = mySections.begin(); s != mySectionsEnd; ++s) { Segments segments = s->segments(); Segments::const_iterator segments_end = segments.end(); for (Segments::const_iterator j = segments.begin(); j != segments_end ; ++j) { Box<bbp::Micron> Mbr = AABBCylinder::calculateAABBForCylinder(j->begin().center(), j->begin().radius(),j->end().center(),j->begin().radius()); vect plow, phigh; plow[0] = Mbr.center().x() - Mbr.dimensions().x() / 2; phigh[0] = Mbr.center().x() + Mbr.dimensions().x() / 2; plow[1] = Mbr.center().y() - Mbr.dimensions().y() / 2; phigh[1] = Mbr.center().y() + Mbr.dimensions().y() / 2; plow[2] = Mbr.center().z() - Mbr.dimensions().z() / 2; phigh[2] = Mbr.center().z() + Mbr.dimensions().z() / 2; SpatialIndex::Region mbr = SpatialIndex::Region(plow.data(),phigh.data(),3); std::stringstream strStream; strStream << s->id()<< "-" << j->id(); tree->insertData (strStream.str().length(), (byte*)(strStream.str().c_str()), mbr, segmentid); segmentid++; } } cout << ".. Total Segments: " << segmentid << "\n"; tree->~ISpatialIndex(); diskfile->~IStorageManager(); } // PRELOAD the Trees amd Neuron Morphology Mapping ISpatialIndex *neurons[NEURONS_COUNT]; global_transformer *transforms[NEURONS_COUNT]; int cm=0; int cn=0; string baseName = ""; Morphologies & myMorphologies = microcircuit.morphologies(); Neurons & myNeurons = microcircuit.neurons(); cout << "PreLoading Mappings \n"; Morphologies::iterator myMorphologiesEnd = myMorphologies.end(); for (Morphologies::iterator m = myMorphologies.begin(); m != myMorphologiesEnd; ++m) { baseName = m->label(); m-> IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName); trees[cm] = RTree::loadRTree(*diskfile, 1); std::cout << "Checking R-tree structure... "; if (!trees[cm]->isIndexValid()) std::cerr << "R-tree internal checks failed!\n"; else std::cout << "OK\n"; IStatistics * tree_stats; trees[cm]->getStatistics (&tree_stats); cout << *tree_stats; Neurons::iterator myNeuronsEnd = myNeurons.end(); for (Neurons::iterator n = myNeurons.begin(); n != myNeuronsEnd; ++n) { if (strcmp(n->morphology().label().c_str(),m->label().c_str())==0) { transforms[cn] = n->global_transform().inverse(); neurons[cn] = trees[cm]; } cn++; if (cn>=NEURONS_COUNT) break; } cn=0;cm++; } /* * Query the Index */ }
int main(int argc, char** argv) { if (argc != 4) { cerr << "Usage: " << argv[0] << " dim n area." << endl; return -1; } int dim = atol(argv[1]); int n = atol(argv[2]); double area = atof(argv[3]); if(dim <= 0) { cerr << "Dimension should be larger than 0." << endl; return -1; } if(n <= 0) { cerr << "The number of query points should be larger than 0." << endl; return -1; } if(area <= 0 || area > 1) { cerr << "the area of query points should be in (0, 1]." << endl; return -1; } /*read static data set*/ vector <Point> P; ifstream in("../data.ini"); if(!in) { cerr << "Cannot open file data.ini.\n"; return -1; } P = readPoints(in, dim); uint32_t N = P.size(); try { IStorageManager* memfile = StorageManager::createNewMemoryStorageManager(); StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*memfile, 10, false); id_type indexIdentifier; ISpatialIndex* tree = RTree::createNewRTree(*file, 0.7, CAPACITY, CAPACITY, dim, SpatialIndex::RTree::RV_RSTAR, indexIdentifier); id_type id = 0; for(uint32_t i = 0; i < N; ++i) { std::ostringstream os; os << P[i]; std::string data = os.str(); tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), P[i], id); id++; } //for(uint32_t loop = 1; loop <= LOOPNUM; ++loop) for(uint32_t loop = 55; loop <= LOOPNUM; ++loop) { cout << "/**************** BEGIN " << loop << " ***************/" << endl; /*generate query set*/ vector <Point> Q; //Q = genPoints(dim, n, area, loop); stringstream ss; ss << "../query/n" << n << "M" << area << "/loop" << loop; cout << ss.str().c_str() << endl; ifstream qin(ss.str().c_str()); if(!qin) { cerr << "Cannot open query file"; return -1; } Q = readPoints(qin, dim); /*************** BEGIN MQM method ******************/ //double err_arr[] = {0, 0.001, 0.005, 0.01, 0.05, 0.1}; double err_arr[] = {0, 0.01, 0.1}; for (uint32_t i = 0; i < sizeof(err_arr) / sizeof(double); ++i) { MQM(tree, Q, n, FUN, err_arr[i]); // MQM method for finding ANN of Q } /*************** END MQM method *******************/ /*************** BEGIN BF MBM method ******************/ /* MBM method for finding ANN of Q */ /*CATCH mbmcost; mbmcost.catch_time(); Region M = getMBR(Q, dim, n); MyQueryStrategy qs(M, Q, FUN); tree->queryStrategy(qs); mbmcost.catch_time(); cout << "MBM: cpu cost is " << mbmcost.get_cost(2) << " millisecond(s)" << endl; cout << "MBM: best_dist is " << qs.best_dist << endl; cout << "MBM: best_NN is "; displayCoordinates(qs.best_NN); cout << "MBM: leafIO = " << qs.mbm_leafIO << "; indexIO = " << qs.mbm_indexIO << endl << endl; */ /*************** END BF MBM method *******************/ /*************** BEGIN brute method ******************/ /* brute method for finding ANN of Q*/ /*CATCH brute_cost; brute_cost.catch_time(); uint32_t ANNid = brute_ANN(Q, n, P, N, FUN); brute_cost.catch_time(); cout << "brute method: cpu cost is " << brute_cost.get_cost(2) << " millisecond(s)" << endl; double adist = getAdist(P[ANNid], Q, n, FUN); cout << "brute method: best_dist is " << adist << endl; cout << "brute method: best_NN is "; displayCoordinates(P[ANNid]); */ /*************** END brute method *******************/ cout << "/**************** END " << loop << " ****************/" << endl << endl; } // end loop delete tree; delete file; delete memfile; } catch(Tools::Exception& e) { cerr << "*********ERROR**********" << endl; std::string s = e.what(); cerr << s << endl; return -1; } catch(...) { cerr << "**********ERROR********" << endl; return -1; } return 1; }
int main(int argc, char** argv) { uint32_t dim = 2; uint32_t n = 8; uint32_t N = 100; /*read static data set*/ vector <Point> P; P = genPoints(dim, N, 1, 0); // displayPset(P); try { IStorageManager* memfile = StorageManager::createNewMemoryStorageManager(); StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*memfile, 10, false); id_type indexIdentifier; ISpatialIndex* tree = RTree::createNewRTree(*file, 0.7, CAPACITY, CAPACITY, dim, SpatialIndex::RTree::RV_RSTAR, indexIdentifier); id_type id = 0; for(uint32_t i = 0; i < N; ++i) { std::ostringstream os; os << P[i]; std::string data = os.str(); tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), P[i], id); id++; } for(uint32_t loop = 1; loop <= LOOPNUM; ++loop) { cout << "/**************** BEGIN " << loop << " ***************/" << endl; /*generate query set*/ vector <Point> Q; Q = genPoints(dim, n, 1, loop); /*double pdata1[] = {0, 0}; double pdata2[] = {0, 1}; double pdata3[] = {1, 1}; Point q1(pdata1, dim), q2(pdata2, dim), q3(pdata3, dim); Q.push_back(q1); Q.push_back(q2); Q.push_back(q3); displayPset(Q); */ /*************** BEGIN BF MBM method ******************/ /* MBM method for finding ANN of Q */ CATCH mbmcost; mbmcost.catch_time(); Region M = getMBR(Q, dim, n); MyQueryStrategy qs(M, Q, FUN); tree->queryStrategy(qs); mbmcost.catch_time(); cout << "MBM: cpu cost is " << mbmcost.get_cost(2) << " millisecond(s)" << endl; cout << "MBM: best_dist is " << qs.best_dist << endl; cout << "MBM: best_NN is "; displayCoordinates(qs.best_NN); cout << "MBM: leafIO = " << qs.mbm_leafIO << "; indexIO = " << qs.mbm_indexIO << endl << endl; /*************** END BF MBM method *******************/ cout << "/**************** END " << loop << " ****************/" << endl << endl; } // end loop delete tree; delete file; delete memfile; } catch(Tools::Exception& e) { cerr << "*********ERROR**********" << endl; std::string s = e.what(); cerr << s << endl; return -1; } catch(...) { cerr << "**********ERROR********" << endl; return -1; } return 1; }
int main(int argc, char** argv) { if (argc != 4) { cerr << "Usage: " << argv[0] << " dim n area." << endl; return -1; } int dim = atol(argv[1]); int n = atol(argv[2]); double area = atof(argv[3]); if(dim <= 0) { cerr << "Dimension should be larger than 0." << endl; return -1; } if(n <= 0) { cerr << "The number of query points should be larger than 0." << endl; return -1; } if(area <= 0 || area > 1) { cerr << "the area of query points should be in (0, 1]." << endl; return -1; } /*read static data set*/ vector <Point> P; ifstream in("../data.ini"); if(!in) { cerr << "Cannot open file data.ini.\n"; return -1; } P = readPoints(in, dim); uint32_t N = P.size(); try { IStorageManager* memfile = StorageManager::createNewMemoryStorageManager(); StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*memfile, 10, false); id_type indexIdentifier; ISpatialIndex* tree = RTree::createNewRTree(*file, 0.7, CAPACITY, CAPACITY, dim, SpatialIndex::RTree::RV_RSTAR, indexIdentifier); id_type id = 0; for(uint32_t i = 0; i < N; ++i) { std::ostringstream os; os << P[i]; std::string data = os.str(); tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), P[i], id); id++; } /*std::cerr << "Operations: " << N << std::endl; std::cerr << *tree; std::cerr << "Buffer hits: " << file->getHits() << std::endl; std::cerr << "Index ID: " << indexIdentifier << std::endl; bool ret = tree->isIndexValid(); if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl; else std::cerr << "The stucture seems O.K." << std::endl; */ for(uint32_t loop = 1; loop <= LOOPNUM; ++loop) { cout << "/**************** BEGIN " << loop << " ***************/" << endl; /*generate query set*/ vector <Point> Q; //Q = genPoints(dim, n, area, loop); stringstream ss; ss << "../query/n" << n << "M" << area << "/loop" << loop; cout << ss.str().c_str() << endl; ifstream qin(ss.str().c_str()); if(!qin) { cerr << "Cannot open query file"; return -1; } Q = readPoints(qin, dim); /*************** BEGIN MQM method ******************/ MQM(tree, Q, n, FUN); // MQM method for finding ANN of Q /*************** END MQM method *******************/ /*************** BEGIN ADM method ******************/ CATCH cost1; cost1.catch_time(); vector <uint32_t> nnIDs = nearestNeighborSet(tree, Q, n); // find the NN for every qi in Q as qi' vector <Point> newQ; for(uint32_t i = 0; i < n; ++i) { newQ.push_back(P[nnIDs[i]]); } cost1.catch_time(); cout << "proposal method: cpu cost for finding NNs of Q as Q' is " << cost1.get_cost(2) << " millisecond(s)" << endl; /***** read dist-matrix index for Q' ********/ uint32_t maxK = P.size() / RATIO; // the length of dist-matrix index uint32_t * dmindex[n]; for(uint32_t i = 0; i < n; ++i) { // read the dist-matrix index of qi' dmindex[i] = readDMIndex(nnIDs[i], maxK); if (dmindex[i] == NULL) { cerr << "error for loading Dist-Matrix Index." << endl; return -1; } } double minadist = 0; /* ADM method for finding approxiamte ANN */ Point adm_ANN = ADM(newQ, n, P, N, dmindex, maxK, FUN, minadist, ERROR_RATE); cout << "ADM: best_dist is " << getAdist(adm_ANN, Q, n, FUN) << endl << endl; /*************** END ADM method *******************/ /*************** BEGIN approxiamte vp-ANN method ******************/ /* approximate vp-ANN method for finding ANN of Q'*/ CATCH cost2; cost2.catch_time(); Point centroid = findCentroid(Q, dim, n); minadist = getAdist(centroid, Q, n, FUN); uint32_t vpID = nearestNeighbor(tree, centroid); uint32_t best_id_Q = epsilonANN(Q, n, P, N, vpID, dmindex, maxK, FUN); cost2.catch_time(); cout << "approxiamte vp-ANN method: cpu cost is " << cost2.get_cost(2) << " millisecond(s)" << endl; cout << "approximate vp-ANN method: best_dist is " << getAdist(P[best_id_Q], Q, n, FUN) << endl; cout << "approxiamte vp-ANN method: best_NN is "; displayCoordinates(P[best_id_Q]); cout << endl; /*************** END approxiamte vp-ANN method *******************/ /*************** BEGIN BF MBM method ******************/ /* MBM method for finding ANN of Q */ CATCH mbmcost; mbmcost.catch_time(); Region M = getMBR(Q, dim, n); MyQueryStrategy qs = MyQueryStrategy(M, Q, FUN); tree->queryStrategy(qs); mbmcost.catch_time(); cout << "MBM: cpu cost is " << mbmcost.get_cost(2) << " millisecond(s)" << endl; cout << "MBM: best_dist is " << qs.best_dist << endl; cout << "MBM: best_NN is "; displayCoordinates(qs.best_NN); cout << "MBM: leafIO = " << qs.mbm_leafIO << "; indexIO = " << qs.mbm_indexIO << endl << endl; /*************** END BF MBM method *******************/ /*************** BEGIN brute method ******************/ /* brute method for finding ANN of Q*/ CATCH brute_cost; brute_cost.catch_time(); uint32_t ANNid = brute_ANN(Q, n, P, N, FUN); brute_cost.catch_time(); cout << "brute method: cpu cost is " << brute_cost.get_cost(2) << " millisecond(s)" << endl; double adist = getAdist(P[ANNid], Q, n, FUN); cout << "brute method: best_dist is " << adist << endl; cout << "brute method: best_NN is "; displayCoordinates(P[ANNid]); /*************** END brute method *******************/ cout << "/**************** END " << loop << " ****************/" << endl << endl; } // end loop delete tree; delete file; delete memfile; } catch(Tools::Exception& e) { cerr << "*********ERROR**********" << endl; std::string s = e.what(); cerr << s << endl; return -1; } catch(...) { cerr << "**********ERROR********" << endl; return -1; } return 1; }
// Returns the number of satisfied pairs int join_bucket_knn(struct query_op &stop, struct query_temp &sttemp) { IStorageManager *storage = NULL; ISpatialIndex *spidx = NULL; bool selfjoin = stop.join_cardinality == 1 ? true : false; /* Indicates where original data is mapped to */ int idx1 = SID_1; int idx2 = selfjoin ? SID_1 : SID_2; int pairs = 0; // number of satisfied results double low[2], high[2]; // Temporary value placeholders for MBB double tmp_distance; // Temporary distance for nearest neighbor query double def_search_radius = -1; // Default search radius //for nearest neighbor (NN) with unknown bounds double max_search_radius; // max_radius to search for NN try { vector<Geometry*> & poly_set_one = sttemp.polydata[idx1]; vector<Geometry*> & poly_set_two = sttemp.polydata[idx2]; int len1 = poly_set_one.size(); int len2 = poly_set_two.size(); #ifdef DEBUG cerr << "Bucket size: " << len1 << " joining with " << len2 << endl; #endif cerr << "Bucket size: " << len1 << " joining with " << len2 << endl; if (len1 <= 0 || len2 <= 0) { return 0; } /* Build index on the "second data set */ map<int, Geometry*> geom_polygons2; geom_polygons2.clear(); // Make a copy of the vector to map to build index (API restriction) for (int j = 0; j < len2; j++) { geom_polygons2[j] = poly_set_two[j]; } /* Handling for special nearest neighbor query */ if (stop.join_predicate == ST_NEAREST_2) { // Updating bucket information if (len2 > 0) { const Envelope * envtmp = poly_set_two[0]->getEnvelopeInternal(); sttemp.bucket_min_x = envtmp->getMinX(); sttemp.bucket_min_y = envtmp->getMinY(); sttemp.bucket_max_x = envtmp->getMaxX(); sttemp.bucket_max_y = envtmp->getMaxY(); } for (int j = 0; j < len1; j++) { update_bucket_dimension(stop, sttemp, poly_set_one[j]->getEnvelopeInternal()); } if (!selfjoin) { for (int j = 0; j < len2; j++) { update_bucket_dimension(stop, sttemp, poly_set_two[j]->getEnvelopeInternal()); } } max_search_radius = max(sttemp.bucket_max_x - sttemp.bucket_min_x, sttemp.bucket_max_y - sttemp.bucket_min_y); def_search_radius = min(sqrt((sttemp.bucket_max_x - sttemp.bucket_min_x) * (sttemp.bucket_max_y - sttemp.bucket_min_y) * stop.k_neighbors / len2), max_search_radius); if (def_search_radius == 0) { def_search_radius = DistanceOp::distance(poly_set_one[0], poly_set_two[0]); } #ifdef DEBUG cerr << "Bucket dimension min-max: " << sttemp.bucket_min_x << TAB << sttemp.bucket_min_y << TAB << sttemp.bucket_max_x << TAB << sttemp.bucket_max_y << endl; cerr << "Width and height (x-y span) " << sttemp.bucket_max_x - sttemp.bucket_min_x << TAB << sttemp.bucket_max_y - sttemp.bucket_min_y << endl; #endif } // build the actual spatial index for input polygons from idx2 if (! build_index_geoms(geom_polygons2, spidx, storage)) { #ifdef DEBUG cerr << "Building index on geometries from set 2 has failed" << endl; #endif return -1; } cerr << "done building indices" << endl; for (int i = 0; i < len1; i++) { /* Extract minimum bounding box */ const Geometry* geom1 = poly_set_one[i]; const Envelope * env1 = geom1->getEnvelopeInternal(); low[0] = env1->getMinX(); low[1] = env1->getMinY(); high[0] = env1->getMaxX(); high[1] = env1->getMaxY(); /* Handle the buffer expansion for R-tree in the case of Dwithin and nearest neighbor predicate */ if (stop.join_predicate == ST_NEAREST_2) { /* Nearest neighbor when max search radius is not determined */ stop.expansion_distance = def_search_radius; // Initial value } if (stop.join_predicate == ST_DWITHIN || stop.join_predicate == ST_NEAREST) { low[0] -= stop.expansion_distance; low[1] -= stop.expansion_distance; high[0] += stop.expansion_distance; high[1] += stop.expansion_distance; } /* Regular handling */ Region r(low, high, 2); MyVisitor vis; vis.matches.clear(); /* R-tree intersection check */ spidx->intersectsWithQuery(r, vis); /* Retrieve enough candidate neighbors */ if (stop.join_predicate == ST_NEAREST_2) { double search_radius = def_search_radius; while (vis.matches.size() <= stop.k_neighbors + 1 && vis.matches.size() <= len2 // there can't be more neighbors than number of objects in the bucket && search_radius <= sqrt(2) * max_search_radius) { // Increase the radius to find more neighbors // Stopping criteria when there are not enough neighbors in a tile low[0] = env1->getMinX() - search_radius; low[1] = env1->getMinY() - search_radius; high[0] = env1->getMaxX() + search_radius; high[1] = env1->getMaxY() + search_radius; Region r2(low, high, 2); vis.matches.clear(); spidx->intersectsWithQuery(r2, vis); #ifdef DEBUG cerr << "Search radius:" << search_radius << " hits: " << vis.matches.size() << endl; #endif search_radius *= sqrt(2); } sttemp.nearest_distances.clear(); /* Handle the special case of rectangular/circle expansion -sqrt(2) expansion */ vis.matches.clear(); low[0] = env1->getMinX() - search_radius; low[1] = env1->getMinY() - search_radius; high[0] = env1->getMaxX() + search_radius; high[1] = env1->getMaxY() + search_radius; Region r3(low, high, 2); spidx->intersectsWithQuery(r3, vis); } for (uint32_t j = 0; j < vis.matches.size(); j++) { const Geometry* geom2 = poly_set_two[vis.matches[j]]; const Envelope * env2 = geom2->getEnvelopeInternal(); if (stop.join_predicate == ST_NEAREST && (!selfjoin || vis.matches[j] != i)) { // remove selfjoin candidates /* Handle nearest neighbor candidate */ tmp_distance = DistanceOp::distance(geom1, geom2); if (tmp_distance < stop.expansion_distance) { update_nn(stop, sttemp, vis.matches[j], tmp_distance); } } else if (stop.join_predicate == ST_NEAREST_2 && (!selfjoin || vis.matches[j] != i)) { tmp_distance = DistanceOp::distance(geom1, geom2); update_nn(stop, sttemp, vis.matches[j], tmp_distance); // cerr << "updating: " << vis.matches[j] << " " << tmp_distance << endl; } } /* Nearest neighbor outputting */ for (std::list<struct query_nn_dist *>::iterator it = sttemp.nearest_distances.begin(); it != sttemp.nearest_distances.end(); it++) { sttemp.distance = (*it)->distance; report_result(stop, sttemp, i, (*it)->object_id); pairs++; /* Cleaning up memory */ delete *it; } sttemp.nearest_distances.clear(); } } // end of try catch (Tools::Exception& e) { //catch (...) { std::cerr << "******ERROR******" << std::endl; #ifdef DEBUG cerr << e.what() << std::endl; #endif return -1; } // end of catch cerr << "Done with tile" << endl; delete spidx; delete storage; return pairs ; }
int main(int argc, const char * argv[]) { ParsePointFile(); try { string basename("RTREE.DATA"); IStorageManager *diskfile = StorageManager::loadDiskStorageManager(basename); StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false); ISpatialIndex* tree = RTree::loadRTree(*file, 1); if (!tree->isIndexValid()) { cout << "Bad Tree" <<endl; return -1; } IStatistics *sts; tree->getStatistics(&sts); int MAX_LEVEL = dynamic_cast<RTree::Statistics*>(sts)->getTreeHeight(); //Operation on MBR in RTree level by level for (int m_level = 0; m_level < MAX_LEVEL; ++m_level) { LevelStrategy ls(m_level); tree->queryStrategy(ls); } delete sts; #ifdef DEBUG_TEST CheckStrategy cs; tree->queryStrategy(cs); #endif ////========== Start Multi-Treads ========================================= ////if the number of trajectories(points) is small, thread may be suspended boost::thread_group threads; for (int i=0; i<QUERY_SIZE; ++i) { threads.create_thread(boost::bind(&NN_RST::Put, rst_vector[i], dynamic_cast<RTree::RTree*>(tree))); } Taxi_Point p; double time; for (int i=0; i< QUERY_SIZE; ++i) { p = point_set[rst_vector[i]->Get()]; time = p.getMinimumDistance(*rst_vector[i]->query) / p.m_speed; Q.push(QEntry(i, p.traj_id, time)); } // No need to invoke AllCoverTest in every loop, so check_flag is set int check_flag=0; while(true) { QEntry entry = Q.top(); Q.pop(); p = point_set[rst_vector[entry.q_id]->Get()]; time = ComputePTime(p, *dynamic_cast<Point*>(rst_vector[entry.q_id]->query)); Q.push(QEntry(entry.q_id, p.traj_id, time)); if (!CTestHelper[entry.t_id].test(entry.q_id)) { if (Candidates.count(entry.t_id) == 0) Candidates[entry.t_id] = time; else Candidates[entry.t_id] += time; } // C.push_back(entry.t_id); if (CTestHelper.count(entry.t_id) == 0) { bitset<QUERY_SIZE> bt; bt.set(entry.q_id); CTestHelper[entry.t_id] = bt; } else { CTestHelper[entry.t_id].set(entry.q_id); } ++check_flag; if (check_flag > QUERY_K*100) { if (AllCoverTest()) break; else check_flag = 0; } } // set continued to false to stop all the other threads { boost::mutex::scoped_lock lock(bool_mutex); continued = false; } for (int i=0; i<QUERY_SIZE; ++i) rst_vector[i]->cond.notify_one(); threads.join_all(); //======= Multi-Threads are stopped ================================== // cout << Q.size() <<endl; // while (!Q.empty()) { // cout << Q.top().time<<endl; // Q.pop(); // } //===== Refine && Verification ===================================== double LargestK = -1.0; int LargestPos = -1; ComputeLargestK(LargestK, LargestPos); for (int traj_id : partial_covering) { double time = LowBound(traj_id); if (time < LargestK) { Candidates[LargestPos] = traj_id; ComputeLargestK(LargestK, LargestPos); } } // now all_covering is the final correct answer for(int traj_id : all_covering) cout << traj_id << endl; delete tree; delete file; delete diskfile; return 0; } catch (Tools::Exception& e) { cerr << "******ERROR******" << endl; std::string s = e.what(); cerr << s << endl; return -1; } catch (...) { cerr << "******ERROR******" << endl; cerr << "other exception" << endl; return -1; } }