// Copyright (c) 1998 ETH Zurich (Switzerland). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $Source$ // $Revision$ $Date$ // $Name$ // // Author(s) : Gabriele Neyer #ifndef __R_TREE_index_implementations_H__ #define __R_TREE_index_implementations_H__ #ifdef CGAL_D_DOGN_Index #define CGAL_DOGN_Index(cmd) cmd #else #define CGAL_DOGN_Index(cmd) #endif #include #include #include #include #include CGAL_BEGIN_NAMESPACE // Guttman quadratic split template struct quadratic_split_leaf { void operator()(Container *first, Container *last, std::back_insert_iterator > left, std::back_insert_iterator > right, int minEntries, int pagesize) { Container *seed1, *seed2, *I1, *I2, *ele, *Itmp; double max = -100000; double tmp; int M, left_nr, right_nr;; I_F i_f; M = last - first; if (M%2) M++; // Search the two points with maximal insertion Cost for (I1 = first; I1 != last; I1++) { Itmp = I1; for (I2 = ++Itmp; I2 != last; I2++) { tmp = i_f.cost((*I1).key, (*I2).key); if (tmp > max) { max = tmp; seed1 = I1; seed2 = I2; } } } *left++ = *seed1; *right++ = *seed2; left_nr = 1; right_nr = 1; int to_left_size=i_f.written_size((*seed1).ele); int to_right_size=i_f.written_size((*seed2).ele); int elements= 0; std::list is_deleted; for (I1 = first; I1 != last; I1++) { elements++; if (I1 != seed1 && I1 != seed2) is_deleted.push_back(false); else is_deleted.push_back(true); } typename I_F::Key s1=(*seed1).key; typename I_F::Key s2=(*seed2).key; bool to_left=false; bool to_right=false; int act_size; double a,b; double Min=-10000; typename std::list::iterator del_ele, del_pos; int k; // insert the element with minimum inefficiency cost for (k=1; k< elements-1; k++){ I1 = first; del_ele = is_deleted.begin(); while(I1 != last && del_ele!=is_deleted.end()) { // for (I1 = first, del_ele = is_deleted.begin(); // I1 != last, del_ele!=is_deleted.end(); I1++, del_ele++) { if (I1 != seed1 && I1 != seed2 && !(*del_ele)) { a = i_f.cost(s1,(*I1).key) ; b = i_f.cost(s2, (*I1).key); if(Min==-10000 || a struct quadratic_split_node { void operator()(Container *first, Container *last, Container *left, Container *right, int minEntries, int maxEntries) { Container *seed1, *seed2, *I1, *I2, *ele, *Itmp; double max = -100000; double tmp; int left_nr, right_nr;; I_F i_f; // Search the two points with maximal insertion Cost for (I1 = first; I1 != last; I1++) { Itmp = I1; for (I2 = ++Itmp; I2 != last; I2++) { tmp = i_f.cost((*I1).key, (*I2).key); if (tmp > max) { max = tmp; seed1 = I1; seed2 = I2; } } } *left++ = *seed1; *right++ = *seed2; left_nr = 1; right_nr = 1; int elements= 0; std::list is_deleted; for (I1 = first; I1 != last; I1++) { elements++; if (I1 != seed1 && I1 != seed2) is_deleted.push_back(false); else is_deleted.push_back(true); } typename I_F::Key s1=(*seed1).key; typename I_F::Key s2=(*seed2).key; bool to_left=false; bool to_right=false; double a,b; double Min=-10000; typename std::list::iterator del_ele, del_pos; int k; for (k=1; k< elements-1; k++){ I1 = first; del_ele = is_deleted.begin(); while(I1 != last && del_ele!=is_deleted.end()) { // for (I1 = first, del_ele = is_deleted.begin(); // I1 != last, del_ele!=is_deleted.end(); ++I1, ++del_ele ) { if (I1 != seed1 && I1 != seed2 && *del_ele==false) { a = i_f.cost(s1,(*I1).key) ; b = i_f.cost(s2, (*I1).key); if(Min==-10000 || a struct star_split_leaf { void operator()(Container *first, Container *last, std::back_insert_iterator > left, std::back_insert_iterator > right, int IO_min_cap, int pagesize) { I_F i_f; // sort_axis_data_2_dim sorting_routine; Sort_axis sorting_routine; typedef typename I_F::Key Key; Key first_group, second_group, best_key_first, best_key_second; double max = -100000; double tmp,best_dist; int best_axis, split_axis=0; Container *it_cont; int i,j, minEntries, maxEntries,absEntries=0; int abs_size=0; CGAL_DOGN_Index( std::cerr << "DATA ENTRY SPLIT\n"; std::cerr << "Elements that have to be split:"; ) for(it_cont=first;it_cont!=last;it_cont++) { absEntries++; CGAL_DOGN_Index( i_f.dump((*it_cont).key); std::cerr << "size:" << (*it_cont).ele.size() << std::endl; ) abs_size+= (*it_cont).ele.size(); } CGAL_DOGN_Index( std::cerr << "pagesize is " << pagesize << "abs size is " << abs_size; std::cerr << " end\n"; ) while(sorting_routine(split_axis, first, last)) { CGAL_DOGN_Index( std::cerr << "The new sorting sequence is:\n"; for(it_cont=first;it_cont!=last;it_cont++) { i_f.dump((*it_cont).key); } std::cerr << std::endl; ) //compute minEntries, maxEntries minEntries=absEntries; maxEntries=0; int maxSize1=0, maxSize2=0; it_cont= first; while(maxSize1pagesize) maxEntries--; it_cont=last; it_cont--; while(maxSize2pagesize) minEntries++; if((minEntries < IO_min_cap)&& (absEntries>=2*minEntries)) minEntries=IO_min_cap; CGAL_DOGN_Index( std::cerr << "MinEntries, MaxEntries, AbsEntries are : " << minEntries; std::cerr << " " << maxEntries << " " << absEntries << std::endl; ) //compute the values for each solution //for(i=minEntries;i<=maxEntries-minEntries;i++) for(i=minEntries;i<=maxEntries;i++) { j=0; for(it_cont=first;it_cont!=last;it_cont++) { if(j i_f.cost(first_group)+i_f.cost(second_group)) { best_dist = i; best_axis=split_axis; best_key_first=first_group; best_key_second=second_group; } } } split_axis++; } //distribute the entries into two groups sorting_routine(best_axis, first, last); it_cont=first; CGAL_DOGN_Index( std::cerr << "output in left list\n"; ) for(i=0;i struct star_split_node { void operator()(Container *first, Container *last, Container *left, Container *right, int minEntries, int maxEntries) { // sort_axis_key_2_dim sorting_routine; Sort_axis sorting_routine; I_F i_f; Container *it_cont; typedef typename I_F::Key Key; Key first_group, second_group, best_key_first, best_key_second; double max = -100000; double best_dist,tmp; int i,j,best_axis,split_axis=0; while(sorting_routine(split_axis, first, last)) { CGAL_DOGN_Index( std::cerr << "The new INNER sorting sequence is:\n"; for(it_cont=first;it_cont!=last;it_cont++) { i_f.dump((*it_cont).key); } std::cerr << std::endl; ) //compute the values for each solution // for(i=minEntries;i<=maxEntries-minEntries;i++) for(i=minEntries;i<=maxEntries;i++) { j=0; for(it_cont=first;it_cont!=last;it_cont++) { if(j i_f.cost(first_group)+i_f.cost(second_group)) { best_dist = i; best_axis=split_axis; best_key_first=first_group; best_key_second=second_group; } } } split_axis++; } //distribute the entries into two groups sorting_routine(best_axis, first, last); it_cont=first; for(i=0;i struct choose_subtree{ typedef typename I_F::Key Key; Container* operator()(Key& k, Container *first, Container *last, int level){ I_F traits; std::list ties; std::list::iterator ti; bool ties_true=false; double cost = 0, best_cost = 111111, min; Container *start_pos = first ,*best_pos; while(start_pos!=last && (*start_pos).deleted) start_pos++; best_cost=traits.cost(k,(*start_pos).key); best_pos=start_pos; start_pos++; while(start_pos!=last) { if(!(*start_pos).deleted) { cost = traits.cost(k,(*start_pos).key); if(cost < best_cost) { best_pos=start_pos; best_cost = cost; ties_true=false; } else if(best_cost==cost){ if(ties.back()!=best_pos) { //empty ties first! while(!ties.empty()) ties.pop_front(); ties.push_back(best_pos); } ties.push_back(start_pos); ties_true=true; best_cost = cost; best_pos=start_pos; CGAL_DOGN_Index( std::cerr << "Best pos changed to "; traits.dump((*best_pos).key,0); std::cerr << std::endl; ) } } start_pos++; } CGAL_DOGN_Index( std::cerr << "vor ties true "; ) if(ties_true) { ti=ties.begin(); Container * do_it=*(ti); min = traits.cost((*do_it).key); best_pos=do_it; ti++; while(ti!=ties.end()) { do_it=*(ti); cost=traits.cost((*do_it).key); if(cost struct star_choose_subtree{ typedef typename I_F::Key Key; Container* operator()(Key& k, Container *first, Container *last, int level){ I_F traits; std::list ties; std::list::iterator ti; bool ties_true=false; double cost = 0, best_cost = 111111, min, overlap; double best_overlap=-10001; Container *i, *start_pos = first ,*best_pos, *act_pos; Key act_union, key_inter; while(start_pos!=last && (*start_pos).deleted) start_pos++; best_pos=act_pos=start_pos; if(level>1) //child pointers do not point to leaves { best_cost=traits.cost(k,(*start_pos).key); start_pos++; while(start_pos!=last) { if(!(*start_pos).deleted) { cost = traits.cost(k,(*start_pos).key); if(cost < best_cost) { best_pos=start_pos; best_cost = cost; ties_true=false; } else if(best_cost==cost){ if(ties.back()!=best_pos) { //empty ties first! while(!ties.empty()) ties.pop_front(); ties.push_back(best_pos); } ties.push_back(start_pos); ties_true=true; best_cost = cost; best_pos=start_pos; CGAL_DOGN_Index( std::cerr << "Best pos changed to "; traits.dump((*best_pos).key,0); std::cerr << std::endl; ) } } start_pos++; } CGAL_DOGN_Index( std::cerr << "vor ties true"; ) if(ties_true) { ti=ties.begin(); Container * do_it=*(ti); min = traits.cost((*do_it).key); best_pos=do_it; ti++; while(ti!=ties.end()) { do_it=*(ti); cost=traits.cost((*do_it).key); if(cost overlap || best_overlap<-10000){ best_overlap = overlap; best_pos=start_pos; ties_true=false; CGAL_DOGN_Index( std::cerr << "Best pos changed to "; traits.dump((*start_pos).key,0); std::cerr << std::endl; ) } else if(best_overlap==overlap){ if(ties.back()!=best_pos) { //empty ties first! while(!ties.empty()) ties.pop_front(); ties.push_back(best_pos); } ties.push_back(start_pos); ties_true=true; best_overlap = overlap; best_pos=start_pos; CGAL_DOGN_Index( std::cerr << "Best pos changed to "; traits.dump((*best_pos).key,0); std::cerr << std::endl; ) } } } CGAL_DOGN_Index( std::cerr << "vor ties true 2 "; ) if(ties_true) //choose the position with minimum area { ti=ties.begin(); Container * do_it=*(ti); min = traits.cost((*do_it).key,k); best_pos=do_it; ti++; while(ti!=ties.end()) { do_it=*(ti); cost=traits.cost((*do_it).key,k); if(cost struct reinsertion_node { typedef typename I_F::Key Key; void operator()(Container *first, Container *last, std::back_insert_iterator > new_elements, std::back_insert_iterator > to_reinsert, int minEntries, int maxEntries) { I_F traits; std::multimap > to_split; std::multimap >::iterator splitIt; double dist; std::pair p; Container *act; Container element; Key bound=first->key; for(act=first;act!=last;act++) bound=traits.unify(bound, act->key); for(act=first;act!=last;act++) { dist=traits.center_dist((*act).key,bound); p.first=dist; p.second=*act; to_split.insert(p); } //put the first 1-100/reinsertion_part% of the entries in YY, //the rest should be reinserted //we perform close reinsert since it outperformed far reinsert int max; int reinsertion_part = 30; if(0 struct reinsertion_leaf { typedef typename I_F::Key Key; void operator()(Container *first, Container *last, std::back_insert_iterator > new_elements, std::back_insert_iterator > to_reinsert, int IO_min_cap, int pagesize) { I_F traits; std::multimap > to_split; Container *act; Container element; double dist; std::pair p; Key bound=first->key; for(act=first;act!=last;act++) bound=traits.unify(bound, act->key); for(act=first;act!=last;act++) { dist=traits.center_dist((*act).key,bound); p.first=dist; p.second=*act; to_split.insert(p); } std::multimap >::iterator splitIt; //put the first (1-100/reinsertion_part)% of the entries in YY, //the rest should be reinserted //we perform close reinsert since it outperformed far reinsert double max; int reinsertion_part = 30; if(0 struct dummy_reinsertion_node { typedef typename I_F::Key Key; void operator()(Container *first, Container *last, std::back_insert_iterator > new_elements, std::back_insert_iterator > to_reinsert, int minEntries, int maxEntries) { } }; template struct dummy_reinsertion_leaf { typedef typename I_F::Key Key; void operator()(Container *first, Container *last, std::back_insert_iterator > new_elements, std::back_insert_iterator > to_reinsert, int minEntries, int pagesize) { } }; CGAL_END_NAMESPACE #endif