|
Space-efficient geometric algorithms and data structuresBy Ilya Katz and Hervé Brönnimann |
00001 //#define DEBUG 00002 //TODO: break insert_into_block into smaller functions!!!!! 00003 //TODO:account for block size 1 00004 //TODO: in order to adjust PQ, need to have KeyOfValuePQ 00005 /* 00006 * Copyright © Ilya Katz and Hervé Brönnimann, 2006. 00007 * 00008 * This is the definition of space efficient tree/heap that employs Red-Black tree 00009 * from the STL and a block that refers to several line segments 00010 * 00011 * This file was creted by adopting stl_set.h of 00012 * the SGI STL library 00013 */ 00014 00019 // Set implementation -*- C++ -*- 00020 00021 // Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. 00022 // 00023 // This file is part of the GNU ISO C++ Library. This library is free 00024 // software; you can redistribute it and/or modify it under the 00025 // terms of the GNU General Public License as published by the 00026 // Free Software Foundation; either version 2, or (at your option) 00027 // any later version. 00028 00029 // This library is distributed in the hope that it will be useful, 00030 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00031 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00032 // GNU General Public License for more details. 00033 00034 // You should have received a copy of the GNU General Public License along 00035 // with this library; see the file COPYING. If not, write to the Free 00036 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00037 // USA. 00038 00039 // As a special exception, you may use this file as part of a free software 00040 // library without restriction. Specifically, if other files instantiate 00041 // templates or use macros or inline functions from this file, or you compile 00042 // this file and link it with other files to produce an executable, this 00043 // file does not by itself cause the resulting executable to be covered by 00044 // the GNU General Public License. This exception does not however 00045 // invalidate any other reasons why the executable file might be covered by 00046 // the GNU General Public License. 00047 00048 /* 00049 * 00050 * Copyright (c) 1994 00051 * Hewlett-Packard Company 00052 * 00053 * Permission to use, copy, modify, distribute and sell this software 00054 * and its documentation for any purpose is hereby granted without fee, 00055 * provided that the above copyright notice appear in all copies and 00056 * that both that copyright notice and this permission notice appear 00057 * in supporting documentation. Hewlett-Packard Company makes no 00058 * representations about the suitability of this software for any 00059 * purpose. It is provided "as is" without express or implied warranty. 00060 * 00061 * 00062 * Copyright (c) 1996,1997 00063 * Silicon Graphics Computer Systems, Inc. 00064 * 00065 * Permission to use, copy, modify, distribute and sell this software 00066 * and its documentation for any purpose is hereby granted without fee, 00067 * provided that the above copyright notice appear in all copies and 00068 * that both that copyright notice and this permission notice appear 00069 * in supporting documentation. Silicon Graphics makes no 00070 * representations about the suitability of this software for any 00071 * purpose. It is provided "as is" without express or implied warranty. 00072 */ 00073 00074 #include "block_tree_heap/tree.h" 00075 #include "functions.hpp" 00076 #include <iterator> 00077 #include <utility> 00078 00079 #ifndef _BLOCK_TREE_HEAP_H 00080 #define _BLOCK_TREE_HEAP_H 1 00081 00082 namespace inplaceds 00083 { 00129 /* 00130 * Distinction between different iterators 00131 * 00132 * \li \c iterator is the iterator that refences to \b blocks 00133 * \li \c SequenceIterator is the iterator that references elements 00134 * in the original sequence. It is basically the \c value_type for this 00135 * data stucture 00136 * \li \c tree_iterator is the iterator that is used in the underlying 00137 * red-black tree, it references DataNodes. 00138 * 00139 */ 00140 00141 00142 template<class SequenceIterator, class Geometry, 00143 class _Compare = std::less<typename SequenceIterator::value_type>, 00144 class _Compare_PQ = std::less<typename SequenceIterator::value_type>, 00145 class _Alloc = std::allocator<typename SequenceIterator::value_type> > 00146 class block_tree_heap 00147 { 00148 // typedefs: 00152 00153 typedef typename SequenceIterator::value_type _Key; 00154 typedef _Key key_type; 00155 typedef _Key value_type; 00156 typedef _Compare key_compare; 00157 typedef _Compare_PQ key_compare_pq; 00158 typedef key_type* key_ptr; 00159 typedef typename Geometry::point_type priority_type; 00161 00162 public: 00163 00164 00165 #define LEFT_EVENT 0 00166 #define RIGHT_EVENT 1 00167 #define INTERSECTION_EVENT 2 00168 #define INVALID_EVENT 100 00169 00180 struct DataNode 00181 { 00182 typedef SequenceIterator value_type; 00183 typedef typename 00184 std::iterator_traits<SequenceIterator>::difference_type 00185 difference_type; 00186 typedef char event_type; 00187 00188 00193 value_type block_begin; 00197 difference_type line_top_pq; 00199 event_type my_event; 00201 value_type intersecting; 00203 priority_type point; 00208 difference_type gap_begin; 00210 difference_type gap_size; 00211 00212 00220 DataNode(value_type l, event_type event = RIGHT_EVENT) 00221 { 00222 line_top_pq = 0; 00223 //intersecting = NOTHING; 00224 my_event=event; 00225 //point=(*l)[1]; 00226 gap_size = 1; //size of 1 00227 } 00228 00229 ~DataNode(){ 00230 00231 } 00232 00233 /* DataNode(const DataNode& rhs){ 00234 block_begin = rhs.block_begin; 00235 my_event = rhs.my_event; 00236 point = rhs.point; 00237 intersecting = rhs.intersecting; 00238 } 00239 00240 const DataNode& operator=(const DataNode& rhs) 00241 { 00242 if(gap_size!=rhs.gap_size) 00243 { 00244 cout<<"Fatal error: trying to copy nodes with different block sizes\n"; 00245 exit(1); 00246 } 00247 block_begin = rhs.block_begin; 00248 line_top_pq = rhs.line_top_pq; 00249 my_event = rhs.my_event; 00250 intersecting = rhs.intersecting; 00251 point = rhs.point; 00252 gap_begin = rhs.gap_begin; 00253 gap_size = rhs.gap_size; 00254 //next_of_the_same_gap_size is not copied 00255 return *this; 00256 } 00257 */ 00261 // void right_event(){ 00262 // my_event = RIGHT_EVENT; 00263 // point = block_begin[1]; should be KeyOfValuePQ()(*block_begin) 00264 // } 00265 00271 // void intersection_event(priority_type p, DataNode* n ){ 00272 // my_event = INTERSECTION_EVENT; 00273 // point = p; 00274 // intersecting = n; 00275 // } 00276 00280 DataNode(){} 00281 00286 const value_type& top_BST() const 00287 { 00288 return block_begin; 00289 } 00290 00297 value_type top_PQ(value_type my_gap, 00298 difference_type block_size, 00299 bool full_block) 00300 { 00301 00302 if(full_block) 00303 { 00304 return line_top_pq+block_begin; 00305 } 00306 else 00307 { 00308 return (my_gap+line_top_pq)-block_size; 00309 } 00310 } 00311 00312 priority_type get_priority() 00313 { 00314 return point; 00315 } 00316 00317 /* 00318 * \brief Sets line_top_pq offset 00319 * 00320 * @param new_top_pq iterator to the line segment that should 00321 * become the highest priority one in the node 00322 * @param my_gap beginning of the gap of the current node 00323 * @param block_size block size of the node 00324 * @full_block \c true if the current node has a full block 00325 * 00326 * @pre new_top_pq must be in the current node 00327 * either in the full block or the gap 00328 * 00329 * Even if the full block for the node does not exist 00330 * the offset includes the full-block size to simplify calculations 00331 */ 00332 void inline set_top_pq(const value_type& new_top_pq, 00333 const value_type& my_gap, 00334 difference_type block_size, 00335 bool full_block) 00336 { 00337 if(full_block && new_top_pq>=block_begin && new_top_pq<block_begin+block_size) 00338 { 00339 line_top_pq = new_top_pq-block_begin; 00340 } 00341 else 00342 { 00343 line_top_pq = new_top_pq-my_gap+block_size; 00344 //cout<<"NO fulll block top pq "<<line_top_pq<<endl; 00345 } 00346 } 00347 00348 00349 /* 00350 * \brief Returns true if the block 00351 * contains a full block and the gap is one less 00352 * than the full block. 00353 * 00354 * This means that if one more element is added, the block 00355 * needs to be broken up into two blocks 00356 * 00357 * @param size full block size 00358 */ 00359 bool is_full_gap(difference_type size, value_type last) 00360 { 00361 //TODO: IF THERE IS NO BLOCK_BEGIN, IS IT LAST OR IS IT GAP_BEGIN 00362 return gap_size==size-1; 00363 } 00364 }; 00369 struct _M_key_comp 00370 { 00371 /* bool operator()(const DataNode& a, const DataNode& b) 00372 { 00373 00374 return key_compare()(*(a.top_BST()),*(b.top_BST())); 00375 } 00376 00377 bool operator()(const SequenceIterator& a, const DataNode& b) 00378 { 00379 return key_compare()(*a, *b.top_BST()); 00380 } 00381 00382 */ bool operator()(const SequenceIterator& a, const SequenceIterator& b) 00383 { 00384 return key_compare()(*a, *b); 00385 } 00386 00387 /* bool operator()(DataNode& a, SequenceIterator& b) 00388 { 00389 return key_compare()(*(a.top_BST()), *b); 00390 } 00391 */ }; 00392 00393 //TODO:do not create anything on the fly 00394 00399 struct _M_key_comp_pq 00400 //MAKE SURE THAT IN THE INTERNAL TREE WE COMPARE BY NODES NOT BY SequenceIterator 00401 { 00402 bool operator()(const DataNode& a, const DataNode& b) 00403 { 00404 return key_compare_pq()(a.point, b.point); 00405 } 00406 }; 00407 00408 //TODO:need to chnage this to reference _M_first, _M_last, gaps_offsets 00409 struct _M_KeyOfValue 00410 { 00411 const SequenceIterator& operator()(const DataNode& a) 00412 { 00413 return a.block_begin; 00414 /* if(a.block_begin!=no_full_block()) 00415 { 00416 return a.block_begin; 00417 } 00418 00419 if(block.gap_size!=0) 00420 return (block.gap_begin)+_M_first+gaps_offsets[block.gap_size]; 00421 else 00422 return _M_last;*/ 00423 00424 } 00425 }; 00426 00427 00428 00429 public: 00434 private: 00435 // typedef typename DataNode::_M_key_comp _M_key_comp; 00436 // typedef typename DataNode::_M_key_comp_pq _M_key_comp_pq; 00437 // typedef typename DataNode::_M_KeyOfValue _M_KeyOfValue; 00438 public: 00439 typedef typename _Alloc::pointer pointer; 00440 typedef typename _Alloc::const_pointer const_pointer; 00441 typedef typename _Alloc::reference reference; 00442 typedef typename _Alloc::const_reference const_reference; 00443 //TODO: chnage these 00444 typedef block::_Rb_tree<SequenceIterator, DataNode, 00445 _M_KeyOfValue, _M_key_comp ,_M_key_comp_pq, _Alloc> _Rep_type; 00446 typedef typename DataNode::event_type event_type; 00447 typedef typename DataNode::priority_type priority_type; 00448 typedef typename _Rep_type::const_iterator const_iterator; 00449 typedef typename _Rep_type::const_reverse_iterator reverse_iterator; 00450 typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 00451 typedef typename _Rep_type::size_type size_type; 00452 typedef typename _Rep_type::difference_type difference_type; 00453 typedef typename _Rep_type::allocator_type allocator_type; 00455 private: 00456 typedef typename _Rep_type::iterator tree_iterator; 00457 public: 00458 00462 template <class _Tp> 00463 /* 00464 * TODO: encasulate tree iterator in _space_th ietartor 00465 * such that every space_iter has 00466 * 1. tree_iterator 00467 * 2. sequence_iterator 00468 */ 00469 class _Space_TH_Iterator: public tree_iterator 00470 { 00471 public: 00472 typedef typename _Tp::value_type::value_type value_type; 00473 typedef value_type& reference; 00474 typedef value_type* pointer; 00475 00476 typedef typename tree_iterator::_Base_ptr _Base_ptr; 00477 typedef typename tree_iterator::_Link_type _Link_type; 00478 typedef _Space_TH_Iterator<_Tp> _Self; 00479 00480 _Space_TH_Iterator():tree_iterator(){}; 00481 _Space_TH_Iterator (tree_iterator a):_M_node(a._M_node){} 00482 _Space_TH_Iterator(_Link_type __x): _M_node(__x) { } 00483 00484 reference 00485 operator*() const 00486 {return *((static_cast<_Link_type>(_M_node)->_M_value_field).top_BST());} 00487 00488 pointer 00489 operator->() const 00490 {return &((static_cast<_Link_type>(_M_node)->_M_value_field).top_BST()); } 00491 00492 _Tp& 00493 data() 00494 {return ((static_cast<_Link_type>(_M_node)->_M_value_field)); } 00495 00496 00497 _Self& 00498 operator++() 00499 { 00500 _M_node = _Rb_tree_increment(_M_node); 00501 return *this; 00502 } 00503 00504 _Self 00505 operator++(int) 00506 { 00507 _Self __tmp = *this; 00508 _M_node = _Rb_tree_increment(_M_node); 00509 return __tmp; 00510 } 00511 00512 _Self& 00513 operator--() 00514 { 00515 _M_node = _Rb_tree_decrement(_M_node); 00516 return *this; 00517 } 00518 00519 _Self 00520 operator--(int) 00521 { 00522 _Self __tmp = *this; 00523 _M_node = _Rb_tree_decrement(_M_node); 00524 return __tmp; 00525 } 00526 00527 bool 00528 operator==(const _Self& __x) const 00529 { return _M_node == __x._M_node; } 00530 00531 bool 00532 operator!=(const _Self& __x) const 00533 { return _M_node != __x._M_node; } 00534 00535 _Base_ptr _M_node; 00536 }; 00537 typedef _Space_TH_Iterator<DataNode> iterator; 00538 typedef typename std::iterator_traits<SequenceIterator>::difference_type block_size_type; 00539 00544 _Rep_type _M_t; // red-black tree representing my_tree_heap 00545 00546 //\todo TODO: block size needs to be determined in the constructor 00547 block_size_type block_size; 00548 00554 SequenceIterator _M_first; 00555 SequenceIterator _M_last; 00557 00558 SequenceIterator _M_last_in_th; 00559 00560 //iterator to the node that points to the last gap of any size>0 00561 tree_iterator _M_last_gap; 00562 00571 // SequenceIterator* gaps; 00572 00582 tree_iterator* left_most_gap; 00595 block_size_type* gaps_offsets; 00597 _Compare _comp; 00599 _Compare_PQ _comp_pq; 00600 public: 00601 00604 // allocation/deallocation 00615 block_tree_heap(SequenceIterator f, SequenceIterator l, int b = 1) 00616 : _M_t(_M_key_comp(), _M_key_comp_pq(), allocator_type()), 00617 _comp(_Compare()), _comp_pq(_Compare_PQ()),block_size(b) 00618 { 00619 //cout<<"constructing"<<endl; 00620 _M_first=f; 00621 //beacuse of the offset it is not ok to put _M_last=l 00622 //since the value of pointer may infact be l 00623 //but when offsett is subtracted it a valid number 00624 _M_last=f-1; 00625 _M_last_in_th=f-1; 00626 //the last position is temporary 00627 gaps_offsets = new block_size_type [int(b)+1]; 00628 left_most_gap = new tree_iterator [int(b)+1]; 00629 00630 for(int i=0; i<int(b+1); ++i) 00631 { 00632 gaps_offsets[i]=0; 00633 left_most_gap[i]=_M_t.end(); 00634 } 00635 00636 } 00637 00650 template<class RandomAccessIterator> 00651 block_tree_heap(RandomAccessIterator first, RandomAccessIterator last, 00652 const _Compare& __comp, 00653 const _Compare_PQ& __comp_pq, 00654 const allocator_type& __a = allocator_type()) 00655 : _M_t(__comp, __comp_pq, __a), _comp(__comp), _comp_pq(__comp_pq) 00656 { 00657 //TODO: 00658 } 00659 00660 ~block_tree_heap() 00661 { 00662 //TODO add deletes 00663 } 00664 00665 private: 00666 block_tree_heap(const block_tree_heap<_Key,Geometry, _Compare,_Compare_PQ,_Alloc>& __x) 00667 {} 00668 public: 00670 00672 00676 void print() 00677 { 00678 //cout<<"BST\n"; 00679 00680 for(tree_iterator it=_M_t.begin(); it!=_M_t.end(); ++it) 00681 { 00682 //cout<<"+==============+"<<endl; 00683 // //cout<<"Priority: "<<it->point<<endl; 00684 // //cout<<"Event: "<<(int)it->my_event<<endl; 00685 // //cout<<"Top pq : "<<*(get_top_pq(it))<<endl; 00686 //cout<<"Next gap :"; 00687 if(_M_t.get_gap_next(it)!=_M_t.end()) 00688 { 00689 cout<<_M_t.get_gap_next(it)->block_begin[0]; 00690 } 00691 else 00692 { 00693 cout<<"null"; 00694 } 00695 cout<<endl; 00696 cout<<"Prev gap :"; 00697 if(_M_t.get_gap_prev(it)!=_M_t.end()) 00698 { 00699 cout<<_M_t.get_gap_prev(it)->block_begin[0]; 00700 } 00701 else 00702 { 00703 cout<<"null"; 00704 } 00705 cout<<endl; 00706 cout<<"Gap "<<get_gap(it)-_M_first<<" "; 00707 if(get_gap(it)!=_M_last) 00708 { 00709 cout<<""<<get_gap(it)-_M_first<<""; 00710 }else 00711 { 00712 cout<<"null"; 00713 } 00714 cout<<"\nGap size "; 00715 cout<<it->gap_size; 00716 00717 00718 cout<<endl<<endl;; 00719 00720 if(it->block_begin!=no_full_block()) 00721 { 00722 for(int i=0; i<block_size; ++i) 00723 { 00724 cout<<""<<it->block_begin[i]<<" "; 00725 // if(successor(it,it->block_begin+i)!=_M_last) 00726 // cout<<"N: "<<*successor(it,it->block_begin+i); 00727 // else 00728 // cout<<"N: null"; 00729 00730 } 00731 } 00732 cout<<endl<<"..................."<<endl; 00733 if(it->gap_size!=0) 00734 { 00735 for(int i=0; i<it->gap_size; ++i) 00736 { 00737 cout<<""<<get_gap(it)[i]<<" "; 00738 // if(successor(it,get_gap(it)+i)!=_M_last) 00739 // cout<<"N: "<<*successor(it,get_gap(it)+i); 00740 // else 00741 // cout<<"N: null"; 00742 } 00743 } 00744 cout<<endl<<"+==============+"<<endl; 00745 } 00746 00747 cout<<endl<<"---------"<<endl; 00748 cout<<"Offsets:\n"; 00749 for(int i=0; i<block_size; i++) 00750 { 00751 cout<<i<<" "<<gaps_offsets[i]<<endl; 00752 } 00753 00754 cout<<"Leftmost gaps"<<endl; 00755 for(int i=0; i<block_size; i++) 00756 { 00757 if(left_most_gap[i]==_M_t.end()) 00758 { 00759 cout<<i<<"none"<<endl; 00760 } 00761 else 00762 { 00763 cout<<i<<" ["<<(get_gap(left_most_gap[i])-_M_first)<<"] "<<*get_gap(left_most_gap[i])<<endl; 00764 } 00765 } 00766 00767 cout<<endl; 00768 cout<<"Last gap: "; 00769 if(_M_last_gap!=_M_t.end()) 00770 { 00771 cout<<"["<<get_gap(_M_last_gap)-_M_first<<"]"<<endl; 00772 } 00773 else 00774 { 00775 cout<<"nill"<<endl; 00776 } 00777 00778 00779 } 00780 public: 00781 00782 00783 SequenceIterator no_full_block() 00784 { 00785 return _M_last; 00786 } 00787 00788 const iterator insert(SequenceIterator new_line) 00789 { 00790 00791 #ifdef DEBUG 00792 //cout<<new_line-_M_first<<" "<<_M_last_in_th-_M_first<<endl; 00793 if(new_line!=_M_last_in_th+1) 00794 { 00795 cerr<<"Fatal error: new_line!=_M_last_in_th+1\n"; 00796 exit(1); 00797 } 00798 #endif 00799 00800 std::pair<tree_iterator, bool> p; 00801 //find the first node whose smallest element is larger 00802 //that is, a node where a the top line is located 00803 //below new_line 00804 tree_iterator it = _M_t.find(new_line); 00805 //cout<<"Finished find it==end is"<<(it==_M_t.end())<<endl; 00806 00807 //tree is empty 00808 if(it==_M_t.end() && it==_M_t.begin()) 00809 { 00810 //cout<<"Starting insert one node tree"<<endl; 00811 p=_M_t.insert_unique(create_node(new_line)); 00812 if(p.second) 00813 { 00814 it=_M_t.PQ_insert(p.first); 00815 left_most_gap[it->gap_size]=it; 00816 _M_t.set_gap_next(it, _M_t.end()); 00817 _M_t.set_gap_prev(it, _M_t.end()); 00818 _M_last_in_th++; 00819 it->block_begin=no_full_block(); 00820 //cout<<"Setting "<<*new_line<<" as top pq"<<endl; 00821 set_top_pq(it, new_line); 00822 } 00823 //cout<<"Finish insert one node tree"<<endl; 00824 _M_last_gap = it; 00825 return it; 00826 } 00827 else 00828 { 00829 //else, insert into a node before it 00830 if(it!=_M_t.begin()) 00831 { 00832 //cout<<"I was NOT begins, hence --it!"<<endl; 00833 --it; 00834 //cout<<"it = "<<*(it->top_BST())<<endl; 00835 } 00836 00837 //if gap is full, split 00838 if(it->is_full_gap(block_size, _M_last)) 00839 { 00840 //cout<<"Starting insert full node. gapsize ="<<it->gap_size<<endl; 00841 #ifdef DEBUG 00842 if(it->gap_size!=block_size-1) 00843 { 00844 cerr<<"Fatal error: max gap size is not the same as gap size of full block!\n"; 00845 exit(1); 00846 } 00847 #endif 00848 00849 00850 //TODO:if gapsize becomes 0, where should next point to 00851 00852 //if the gap is full, there are two cases 00853 //1.if there is a full block, need to insert and make the current gap a full block 00854 //2.otherwise need to insert and split into two 00855 00856 //case 1 00857 if(it->block_begin==no_full_block()) 00858 { 00859 //cout<<"starting NOT full block, but full gap"<<endl; 00860 insert_into_gap(it, new_line); 00861 it->block_begin=get_gap(it); 00862 //TODO: need to move over to the other side of dead elements 00863 it->gap_size=0; 00864 left_most_gap[block_size]=_M_t.end(); 00865 //cout<<"_M_last_in_th is "<<_M_last_in_th-_M_first<<endl; 00866 _M_last_in_th++; 00867 // update_top_pq(it); 00868 return it; 00869 } 00870 00871 //case 2 00872 SequenceIterator new_block; 00873 //cout<<"starting full block, AND full gap"<<endl; 00874 insert_into_gap(it, new_line); 00875 //cout<<"Finished insert_into_gap"<<endl; 00876 //TODO: need to move over to the other side of dead elements 00877 new_block=get_gap(it); 00878 std::pair<tree_iterator, bool> p; 00879 p=_M_t.insert_unique(create_node(new_block)); 00880 if(p.second) 00881 { 00882 00883 /*for(SequenceIterator i=get_gap(it); i<get_gap(it)+it->gap_size; i++) 00884 cout<<*i<<" "; 00885 cout<<endl; 00886 for(SequenceIterator i=it->block_begin; i<it->block_begin+block_size; i++) 00887 cout<<*i<<" "; 00888 */ 00889 if(left_most_gap[block_size]==it) 00890 { 00891 //cout<<"IM LEFTMOST"<<endl; 00892 if(_M_t.get_gap_next(it)->gap_size!=block_size-1) 00893 { 00894 left_most_gap[block_size-1]=_M_t.end(); 00895 gaps_offsets[block_size-1]=0; 00896 } 00897 else 00898 { 00899 left_most_gap[block_size-1]=_M_t.get_gap_next(it); 00900 } 00901 } 00902 //for consistancy 00903 left_most_gap[block_size]=_M_t.end(); 00904 gaps_offsets[block_size]=0; 00905 00906 //cout<<"starting update_pointers"<<endl; 00907 if(_M_t.get_gap_next(it)!=_M_t.end()) 00908 { 00909 _M_t.set_gap_prev(_M_t.get_gap_next(it), _M_t.end()); 00910 } 00911 _M_t.set_gap_next(it, _M_t.end()); 00912 00913 if(_M_t.get_gap_prev(it)!=_M_t.end()) 00914 { 00915 _M_t.set_gap_next(_M_t.get_gap_prev(it), _M_t.get_gap_next(it)); 00916 } 00917 else 00918 { 00919 if(_M_last_gap==it && _M_t.get_gap_next(it)==_M_t.end()) 00920 { 00921 _M_last_gap=_M_t.get_gap_prev(it); 00922 } 00923 } 00924 00925 _M_t.set_gap_prev(it, _M_t.end()); 00926 00927 00928 it->gap_size=0; 00929 it=_M_t.PQ_insert(p.first); 00930 //TODO: is this correct, should it point to gap size of 1 00931 _M_t.set_gap_next(it, _M_t.end()); 00932 _M_t.set_gap_prev(it, _M_t.end()); 00933 _M_last_in_th++; 00934 it->block_begin=new_block; 00935 it->gap_size=0; 00936 return it; 00937 } 00938 //cout<<"Finish insert "<<endl; 00939 // update_top_pq(it); 00940 return it; 00941 00942 } 00943 else //node is not full 00944 { 00945 //cout<<"Starting insert not full node, gapsize "<<it->gap_size<<endl; 00946 insert_into_gap(it, new_line); 00947 _M_last_in_th++; 00948 //cout<<"Set gap to be "<<_M_first[get_gap(it)-_M_first-gaps_offsets[it->gap_size]]<<endl; 00949 // update_top_pq(it); 00950 return it; 00951 } 00952 00953 } 00954 } 00955 00956 00957 void insert_into_gap(tree_iterator it, SequenceIterator new_line) 00958 { 00959 if(it->gap_size==0) 00960 { 00961 if(left_most_gap[1]==_M_t.end()) 00962 { 00963 left_most_gap[1]=it; 00964 } 00965 00966 if(_M_last_gap!=_M_t.end() && _M_last_gap!=it) 00967 { 00968 _M_t.set_gap_next(_M_last_gap,it); 00969 _M_t.set_gap_prev(it, _M_last_gap); 00970 } 00971 it->gap_size++; 00972 set_gap(it, new_line); 00973 update_block_after_insert(it, new_line); 00974 _M_last_gap=it; 00975 return; 00976 } 00977 00978 tree_iterator tmp=left_most_gap[it->gap_size]; 00979 //1. swap with the first gap with the same size 00980 if(get_gap(it)!=_M_last && get_gap(it)!=get_leftmost_gap(it->gap_size)) 00981 { 00982 //cout<<"get_gap(it)!=get_leftmost_gap(it->gap_size)"<<endl; 00983 swap_gaps(get_gap(it), get_leftmost_gap(it->gap_size), it->gap_size); 00984 //swap gap pointers 00985 SequenceIterator t=get_gap(it); 00986 //reset gap becuase when swapping location chnaged 00987 set_gap(it, get_leftmost_gap(it->gap_size)); 00988 set_gap(left_most_gap[it->gap_size], t); 00989 //cout<<"swapped blocks\n"; 00990 // <<it->block_begin[0]<<" "<<get_gap(it)-_M_first<<" "<<it->gap_size<<" "<<endl 00991 // <<left_most_gap[1]->block_begin[0]<<" "<<get_gap(left_most_gap[1])-_M_first<<" "<<left_most_gap[1]->gap_size<<endl; 00992 00993 _M_t.swap_gap_next(it, left_most_gap[it->gap_size]); 00994 _M_t.swap_gap_prev(it, left_most_gap[it->gap_size]); 00995 00996 if(_M_t.get_gap_prev(it)!=_M_t.end()) 00997 { 00998 _M_t.set_gap_next(_M_t.get_gap_prev(it), it); 00999 } 01000 if(_M_t.get_gap_next(it)!=_M_t.end()) 01001 { 01002 _M_t.set_gap_prev(_M_t.get_gap_next(it), it); 01003 } 01004 01005 if(_M_t.get_gap_prev(left_most_gap[it->gap_size])!=_M_t.end()) 01006 { 01007 _M_t.set_gap_next(_M_t.get_gap_prev(left_most_gap[it->gap_size]), left_most_gap[it->gap_size]); 01008 } 01009 if(_M_t.get_gap_next(left_most_gap[it->gap_size])!=_M_t.end()) 01010 { 01011 _M_t.set_gap_prev(_M_t.get_gap_next(left_most_gap[it->gap_size]), left_most_gap[it->gap_size]); 01012 } 01013 01014 01015 01016 01017 //cout<<"updated gap_next and gap_prev"<<endl; 01018 01019 01020 } 01021 else 01022 { 01023 //cout<<"did not swap"<<endl; 01024 //swap not needed 01025 } 01026 01027 01028 //2. move all elements by one 01029 //place the new element as the first one in the gap 01030 if(it->gap_size!=0) 01031 { 01032 01033 01034 //cout<<"move_blocks("<<get_gap(it)-_M_first<<", _M_last_in_th+1);"<<endl; 01035 01036 *(get_gap(it))=move_blocks(get_gap(it), _M_last_in_th+1); 01037 new_line=get_gap(it); 01038 01039 //cout<<"finished move"<<endl; 01040 // for(SequenceIterator i=get_gap(it); i<get_gap(it)+it->gap_size+1; ++i) 01041 // cout<<*i<<endl; 01042 01043 //need to re-set the gap since, the offsets are now different 01044 set_gap(it, get_gap(it), it->gap_size+1); 01045 01046 } 01047 else 01048 { 01049 if(left_most_gap[1]==_M_t.end()) 01050 { 01051 left_most_gap[1]=it; 01052 gaps_offsets[1]=0; 01053 //cout<<"Setting gap"<<endl; 01054 set_gap(it, new_line, it->gap_size+1); 01055 } 01056 else 01057 { 01058 //cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl; 01059 //WHAT IS THIS FOR??? 01060 it->gap_begin=new_line-get_gap(left_most_gap[1]); 01061 } 01062 } 01063 01064 //3. update offsets for all gaps of size less than or equal it->gap_size 01065 for(int i=it->gap_size; i>0; i--) 01066 { 01067 if(left_most_gap[i] !=_M_t.end()) 01068 { 01069 gaps_offsets[i]+=1; 01070 } 01071 } 01072 //cout<<"updated all offsets"<<endl; 01073 01074 //3.6.update leftmost pointers for size it->gap_size+1 01075 update_left_most_pointer(it, it->gap_size+1); 01076 01077 //3.7.update leftmost pointers for size it->gap_size 01078 //after swap (or without it) 01079 //it was the leftmost of its size 01080 //since, we're are going to increment its size, 01081 //the leftmost gap of same size must become the new leftmost 01082 if(_M_t.get_gap_next(it)!=_M_t.end()) 01083 { 01084 01085 if(_M_t.get_gap_next(it)->gap_size==it->gap_size) 01086 { 01087 left_most_gap[it->gap_size]=_M_t.get_gap_next(it); 01088 } 01089 else 01090 { 01091 left_most_gap[it->gap_size]=_M_t.end(); 01092 gaps_offsets[it->gap_size]=0; 01093 } 01094 } 01095 else 01096 { 01097 //cout<<"DOING THAT"<<endl; 01098 left_most_gap[it->gap_size]=_M_t.end(); 01099 gaps_offsets[it->gap_size]=0; 01100 } 01101 01102 //3.8 update last gap pointer 01103 //a. if no swap, nothing chnages 01104 //b. if swapped, the one that swapped with may become the last 01105 if(_M_t.get_gap_next(tmp)==_M_t.end()) 01106 { 01107 _M_last_gap=tmp; 01108 } 01109 01110 01111 //5.increase size of the node 01112 it->gap_size++; 01113 //cout<<"increased current size"<<it->gap_size<<endl; 01114 01115 //6.restore order in the block and tree/heap 01116 update_block_after_insert(it, new_line); 01117 } 01118 01119 01120 void update_left_most_pointer(tree_iterator it, int new_size) 01121 { 01122 //cout<<"Updating leftmost"<<endl; 01123 #ifdef DEBUG 01124 if(_M_t.get_gap_prev(it)==_M_t.end()) 01125 { 01126 if(left_most_gap[new_size]!=_M_t.end()) 01127 { 01128 cerr<<"Fatal error: trying to assign it to leftmost["<<new_size<<"]" 01129 <<"which is non-null"<<endl; 01130 exit(-1); 01131 } 01132 } 01133 #endif 01134 01135 01136 if(left_most_gap[new_size]==_M_t.end()) 01137 { 01138 left_most_gap[new_size]=it; 01139 gaps_offsets[new_size]=0; 01140 //cout<<"Set leftmost["<<new_size<<"] = it"<<endl; 01141 } 01142 else 01143 { 01144 //cout<<"Leftmost is "<<endl; 01145 //cout<<get_gap(left_most_gap[new_size])-_M_first<<endl; 01146 _M_t.set_gap_next(_M_t.get_gap_prev(it), it); 01147 } 01148 } 01149 01150 01160 value_type move_blocks(SequenceIterator first, SequenceIterator last) 01161 { 01162 01163 //cout<<"In move_block"<<endl; 01164 //cout<<"last= "<<last-_M_first<<" "<<endl; 01165 //cout<<"first= "<<first-_M_first<<" "<<endl; 01166 if(first==last) 01167 return *first; 01168 value_type tmp = *first; 01169 first++; 01170 for(;first!=last+1; ++first) 01171 { 01172 //cout<<"moving "<<*first<<endl; 01173 std::swap(*first, tmp); 01174 } 01175 //cout<<"finished move_block"<<endl; 01176 return tmp; 01177 } 01178 01179 //TODO: 01180 // it is not necessary to perform the full 01181 //scan after insert, but needs to be done after delete 01182 void update_top_pq(tree_iterator it) 01183 { 01184 SequenceIterator top_block=_M_last, top_gap=_M_last, tmp; 01185 point_type top_priority_block, top_priority_gap; 01186 char type_block, type_gap; 01187 std::pair<bool, point_type> x; 01188 01189 01190 if(it->block_begin!=no_full_block()) 01191 { 01192 //cout<<"Updating PQ in block"<<endl; 01193 top_block= 01194 std::min_element(it->block_begin, it->block_begin+block_size, _comp_pq); 01195 top_priority_block = (*top_block)[1]; 01196 type_block = RIGHT_EVENT; 01197 01198 //TODO:watch out for block size 2 01199 for(SequenceIterator i=it->block_begin; i!=it->block_begin+block_size-1; i++) 01200 { 01201 x=intersection(*i, *(i+1)); 01202 if(x.first && _comp_pq(top_priority_block, x.second)) 01203 { 01204 top_block=i; 01205 top_priority_block=x.second; 01206 type_block=INTERSECTION_EVENT; 01207 } 01208 } 01209 01210 if(it->gap_size!=0) 01211 { 01212 x=intersection(*(it->block_begin+block_size-1), *get_gap(it)); 01213 if(x.first && _comp_pq(top_priority_block,x.second)) 01214 { 01215 top_block=it->block_begin+block_size-1; 01216 top_priority_block = x.second; 01217 type_block=INTERSECTION_EVENT; 01218 } 01219 } 01220 } 01221 01222 if(it->gap_size!=0) 01223 { 01224 //cout<<"Updating PQ in gap"<<endl; 01225 top_gap= 01226 std::min_element(get_gap(it), get_gap(it)+it->gap_size, _comp_pq); 01227 top_priority_gap=(*top_gap)[1]; 01228 type_gap = RIGHT_EVENT; 01229 01230 for(SequenceIterator i=get_gap(it); i<get_gap(it)+it->gap_size-1; i++) 01231 { 01232 x=intersection(*i, *(i+1)); 01233 if(x.first && _comp_pq(top_priority_gap,x.second)) 01234 { 01235 top_gap=i; 01236 top_priority_gap=x.second; 01237 type_gap=INTERSECTION_EVENT; 01238 } 01239 } 01240 //cout<<"After loop top_pq is "<<*top_gap<<endl; 01241 if(successor(it,get_gap(it)+it->gap_size-1)!=_M_last) 01242 { 01243 //cout<<"there is a successor"<<endl; 01244 x=intersection(*(get_gap(it)+it->gap_size-1), 01245 *successor(it,get_gap(it)+it->gap_size-1)); 01246 if(x.first && _comp_pq(top_priority_gap,x.second)) 01247 { 01248 top_gap=get_gap(it)+it->gap_size-1; 01249 top_priority_gap=x.second; 01250 type_gap=INTERSECTION_EVENT; 01251 } 01252 } 01253 } 01254 01255 //DONT FORGET EVENTTYPE 01256 01257 if(top_block==_M_last) 01258 { 01259 01260 #ifdef DEBUG 01261 if(top_gap==_M_last) 01262 { 01263 cerr<<"Fatal error: top_block and top_gap are null in update_top_pq\n"; 01264 exit(1); 01265 } 01266 #endif 01267 01268 //cout<<"Setting "<<*top_gap<<" as top PQ"<<endl; 01269 set_top_pq(it, top_gap); 01270 it->point=top_priority_gap; 01271 it->my_event=type_gap; 01272 } 01273 else if(top_gap==_M_last) 01274 { 01275 set_top_pq(it, top_block); 01276 it->point=top_priority_block; 01277 it->my_event=type_block; 01278 } 01279 else if(_comp_pq(top_priority_block, top_priority_gap)) 01280 { 01281 set_top_pq(it,top_block); 01282 it->point=top_priority_block; 01283 it->my_event=type_block; 01284 } 01285 else 01286 { 01287 set_top_pq(it,top_gap); 01288 it->point=top_priority_gap; 01289 it->my_event=type_gap; 01290 } 01291 01292 } 01293 01294 01295 //Account for blocksize=1; 01296 DataNode& create_node(SequenceIterator l) 01297 { 01298 DataNode* block = new DataNode(l); 01299 block->gap_begin = l-_M_first; 01300 block->block_begin = l; 01301 return (*block); 01302 } 01303 01304 01305 inline SequenceIterator get_gap(tree_iterator block) 01306 { 01307 return get_gap(*block); 01308 } 01309 01311 inline SequenceIterator get_gap(const DataNode& block) 01312 { 01313 if(block.gap_size!=0){ 01314 return (block.gap_begin)+_M_first+gaps_offsets[block.gap_size]; 01315 } 01316 else 01317 return _M_last; 01318 } 01319 01320 inline void set_gap(tree_iterator block, SequenceIterator new_gap, block_size_type gap_size) 01321 { 01322 block->gap_begin=new_gap - _M_first-gaps_offsets[gap_size]; 01323 //cout<<"Setting gap to be "<<block->gap_begin<<" offset: "<<gaps_offsets[gap_size]<<endl; 01324 } 01325 01326 inline void set_gap(tree_iterator block, SequenceIterator new_gap) 01327 { 01328 set_gap(block, new_gap, block->gap_size); 01329 } 01330 01331 01332 01333 01334 inline SequenceIterator get_leftmost_gap(block_size_type size) 01335 { 01336 return get_gap(left_most_gap[size]); 01337 } 01338 01346 inline void swap_gaps(SequenceIterator b1, SequenceIterator b2, block_size_type size) 01347 { 01348 std::swap_ranges(b1,b1+size, b2); 01349 //cout<<"-----\n"; 01350 /* for(SequenceIterator i=b1;i!=b1+size; ++i) 01351 //cout<<*i<<endl; 01352 cout<<"-----\n"; 01353 for(SequenceIterator i=b2;i!=b2+size; ++i) 01354 cout<<*i<<endl; 01355 */ 01356 01357 } 01358 01362 block_size_type max_gap_size() 01363 { 01364 for(int i=block_size-1; i>1; --i) 01365 { 01366 if(left_most_gap[i]!=_M_last) 01367 { 01368 return block_size_type(i); 01369 } 01370 } 01371 01372 } 01373 01388 void update_block_after_insert(tree_iterator& block, SequenceIterator new_el) 01389 { 01390 //new element just inserted 01391 SequenceIterator tmp=new_el; 01392 value_type tmp_new_el = *new_el; 01393 //cout<<"New_el is "<<*new_el<<endl; 01394 //cout<<"Current top_pq "<<*get_top_pq(block)<<endl; 01395 01396 //if new element is smaller than the largest element in the 01397 //block, both block and gap need to be sorted 01398 if(block->block_begin!=no_full_block() && block->gap_size!=0) 01399 { 01400 if(_comp(*new_el,*(block->block_begin+block_size-1))) 01401 { 01402 //cout<<"Sorting block and gap"<<endl; 01403 std::swap(*new_el, *(block->block_begin+block_size-1)); 01404 std::sort(block->block_begin,block->block_begin+block_size, _comp); 01405 std::sort(get_gap(block), get_gap(block)+(block->gap_size), _comp); 01406 tmp=std::find(block->block_begin,block->block_begin+block_size, tmp_new_el); 01407 } 01408 else 01409 { 01410 std::sort(get_gap(block), get_gap(block)+(block->gap_size), _comp); 01411 tmp=std::find(get_gap(block), get_gap(block)+(block->gap_size), tmp_new_el); 01412 } 01413 } 01414 //only gap needs to be sorted 01415 else if(block->gap_size!=0) 01416 { 01417 //cout<<"Sorting only gap "<<endl; 01418 std::sort(get_gap(block), get_gap(block)+(block->gap_size), _comp); 01419 tmp=std::find(get_gap(block), get_gap(block)+(block->gap_size), tmp_new_el); 01420 } 01421 else 01422 { 01423 //cout<<"Sorting only block "<<endl; 01424 std::sort(block->block_begin, block->block_begin+block_size, _comp); 01425 tmp=std::find(block->block_begin,block->block_begin+block_size, tmp_new_el); 01426 } 01427 01428 #ifdef DEBUG 01429 if(tmp_new_el!=*tmp) 01430 { 01431 cerr<<"Fatal error: tmp_new_el!=*tmp in update_block_after insert" 01432 <<*new_el<<" != "<<*tmp<<endl; 01433 exit(1); 01434 } 01435 #endif 01436 01437 return; 01438 } 01439 01440 inline SequenceIterator get_top_pq(tree_iterator it) 01441 { 01442 return it->top_PQ(get_gap(it),block_size, !(it->block_begin==no_full_block())); 01443 } 01444 01445 inline void set_top_pq(tree_iterator it, SequenceIterator new_top) 01446 { 01447 it->set_top_pq(new_top, get_gap(it), block_size, it->block_begin!=no_full_block()); 01448 //cout<<*get_top_pq(it)<<"Was set as top pq"<<endl; 01449 } 01450 01451 inline event_type get_event(iterator block) 01452 { 01453 return (static_cast<typename iterator::_Link_type>(block._M_node)->_M_value_field).my_event; 01454 } 01455 01456 01461 void 01462 pop() 01463 { 01464 //remove from PQ 01465 //remove from BST and destroy 01466 // _M_t.erase(_M_t.erase_top_PQ()); 01467 } 01471 iterator 01472 top() const 01473 { 01474 return _M_t.get_top(); 01475 } 01476 01477 priority_type get_priority(iterator block) 01478 { 01479 return (static_cast<typename iterator::_Link_type>(block._M_node)->_M_value_field).get_priority (); 01480 } 01481 01482 01490 void segment_intersection_event(iterator it) 01491 { 01492 // _M_t.segment_intersection_event(it._M_node, point, intersecting._M_node); 01493 } 01494 01495 bool empty() 01496 { 01497 } 01499 private: 01500 iterator successor(iterator block) 01501 { 01502 return ++block; 01503 } 01504 01514 SequenceIterator successor(tree_iterator node, SequenceIterator line) 01515 { 01516 01517 //there is a full block and like is not the last 01518 if(node->block_begin!=no_full_block()) 01519 { 01520 if(line < node->block_begin + block_size -1) 01521 { 01522 return line+1; 01523 } 01524 if(get_gap(node)!=_M_last && line == node->block_begin + block_size-1) 01525 { 01526 return get_gap(node); 01527 } 01528 } 01529 //there is a gap and line is in the gap 01530 if(get_gap(node)!=_M_last && line < get_gap(node) + node->gap_size -1) 01531 { 01532 return line+1; 01533 } 01534 if(++node!=_M_t.end()) 01535 { 01536 return node->block_begin; 01537 } 01538 return _M_last; 01539 } 01540 01541 01542 iterator predecessor(iterator block) 01543 { 01544 01545 } 01546 01560 void 01561 swap_lines(iterator a, iterator b) 01562 { 01563 // _M_t._M_swap_nodes(a._M_node, b._M_node); 01564 } 01565 01566 public: 01567 01570 // accessors: 01572 key_compare 01573 key_comp() const 01574 { return _M_t.key_comp(); } 01576 key_compare_pq 01577 key_comp_pq() const 01578 { 01579 // return _M_t.key_comp_pq(); 01580 } 01582 allocator_type 01583 get_allocator() const 01584 { return _M_t.get_allocator(); } 01590 const_iterator 01591 begin() const 01592 { return _M_t.begin(); } 01593 01594 iterator 01595 begin() 01596 { return _M_t.begin(); } 01597 01602 const_iterator 01603 end() const 01604 { return _M_t.end();} 01605 01606 iterator 01607 end() 01608 { return _M_t.end();} 01609 01610 bool 01611 empty() const 01612 { return _M_t.empty(); } 01613 01615 size_type 01616 size() const 01617 { return _M_t.size(); } 01618 01627 void 01628 clear() 01629 { 01630 _M_t.clear(); 01631 } 01632 01633 01635 private: 01642 void adjust_PQ(iterator it) 01643 { 01644 // _M_t.adjust_PQ(it._M_node); 01645 } 01646 01647 private: 01657 void 01658 erase(iterator __position) 01659 { 01660 typedef typename _Rep_type::iterator _Rep_iterator; 01661 _M_t.erase((_Rep_iterator&)__position); 01662 } 01663 public: 01664 01665 }; 01666 } // namespace 01667 01668 #endif /* _my_tree_heap_H */ 01669
Code Documentation generated Using Doxygen
Copyright © Ilya Katz and Hervé Brönnimann, 2005, 2006.