The GroupIndex Template Library
Main Page | Class Hierarchy | Class List | File List | Class Members

IntervalIntersectionGList.h

00001 #ifndef DEF_INTERVALINTERSECTIONGLIST
00002 #define DEF_INTERVALINTERSECTIONGLIST
00003 
00004 #pragma warning( once : 4786 )        
00005 
00006 #include "compression.h"
00007 #include "GInvertedList.h"
00008 
00009 #ifdef list
00010 #undef list
00011 #endif
00012 
00013 #include <limits>
00014 #include "util.h"
00015 
00016 #include "../avlTree/avlTree.h"         
00017 #include "../ekdTree/dynEkdTree.h"
00018 
00019 #define AREA_SEARCH
00020 //#define BIN_SEARCH
00021 //#define LINEAR_SEARCH
00022 
00023 namespace groupindex
00024 {
00025 
00026 /***************************************************************************************
00027  * class Interval (Interface)                                                                                                          *
00028  ***************************************************************************************/
00049 template<class Group, class numeric, int Dim>
00050 class Interval : public ListTupel<Group>
00051 {
00052         
00053 public:
00054         
00055         static const unsigned int longsize;
00056 
00058         numeric cmin[Dim];
00060         numeric cmax[Dim];
00061 
00063     int matched;
00064 
00066         Interval<Group,numeric,Dim>& operator = (const Interval<Group,numeric,Dim>& intv);
00067 
00069         bool operator < (Interval<Group, numeric, Dim> &i2) const;
00070 
00071         bool operator==(Interval<Group, numeric, Dim > &i2) const;
00072 
00073     friend std::ofstream& operator<<(std::ofstream& ofs, Interval<Group, numeric, Dim > i);
00074 
00076         bool operator > (const Interval<Group,numeric,Dim >& ic2) const;
00077 
00079         Interval<Group, numeric, Dim >();
00080 
00082         ~Interval();
00083 
00091         Interval<Group, numeric, Dim >(ListTupel<Group> mylt);
00092 
00100         Interval<Group, numeric, Dim >(Group myg);
00101 
00102         Interval<Group, numeric, Dim >(Group myg, int newmatched);
00103 
00110         Interval<Group, numeric, Dim >(FILE* stream);
00111 
00118     Interval<Group, numeric, Dim>(std::ifstream& ifs);
00119     Interval<Group, numeric, Dim>(std::fstream& ifs);
00120 
00128         inline unsigned long indexSize();
00129         
00132         inline void writeToFile(FILE* stream);
00133         
00141         bool expand(Group &x);
00142 
00144         inline numeric operator[](int i);
00145 
00146         //friend ListTupel<Group>& operator=(ListTupel<Group>& lt, const Interval<Group,numeric,Dim>& i);
00147         operator ListTupel<Group>&();
00148 };
00149 
00150 
00151 
00152 /* **************************************************************************************
00153  * class treeSaver      (Interface)                                                                                                    *
00154  ***************************************************************************************/
00159 template <class treetype>
00160 class treeSaver
00161 {
00162         public:
00163 
00164                 treeSaver();
00165                 treeSaver(treetype* tree, int pos);
00166                 ~treeSaver();
00167                 inline treetype* getTree();
00168                 inline int getFileNum();
00169                 inline bool operator < (treeSaver& compare);
00170                 inline bool operator == (treeSaver& compare);
00171                 operator = (treeSaver& setto);
00172 
00173         friend std::ofstream& operator<<(std::ofstream& o, treeSaver<treetype>& ts);
00174 
00175         private:
00176                 
00177                 treetype** m_tree;
00178                 int                filenum;
00179 
00180 };
00181 
00182 template <class treetype>
00183 std::ofstream& operator<<(std::ofstream& o, treeSaver<treetype>& ts)
00184 {
00185     o<<**ts.m_tree;
00186 }
00187 
00188  
00189 
00190 template<class Group, class numeric, int Dim, class numeric_writer = double_writer>
00191 /***************************************************************************************
00192  * class IntervalIntersectionGList (GInvertedList) (Interface)                                         *
00193  ***************************************************************************************/
00234 class IntervalIntersectionGList : public GInvertedList<Group>
00235 {
00236  
00237 
00238 
00239 public:
00240 
00241     typedef dynEkdTree<Interval<Group, numeric, Dim >, Dim, numeric, numeric_writer> tpTREE;
00242     typedef avlTree<treeSaver<tpTREE> > avl_tree_type;
00244         IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >(const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& glist);
00245 
00247         IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >();
00248 
00249         IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >(long id);
00250 
00252         IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >(std::ifstream& ifs);
00253 
00255         IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >(std::fstream& ifs);
00256 
00258         virtual ~IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >();
00259 
00260 
00261     
00262     // ////////////////////////////////////////////////////////////////////
00263     // /////////// Iterator Anfang ////////////////////////////////////////
00264     // ////////////////////////////////////////////////////////////////////
00270     class iterator
00271         {
00272                 protected:
00273 
00274                         avlTree<treeSaver<tpTREE> >* m_tree_tree;
00275 
00276                         tpTREE* m_tree;
00277         
00278                         typename dynEkdTree<Interval<Group, numeric, Dim>, Dim, numeric, numeric_writer>::iterator m_iterator;
00279 
00280                         int m_current_file;
00281                         int m_hitsNecessary;
00282 
00283                         bool m_at_end;
00284 
00285             Group m_g_factor;
00286 
00287             Interval<Group, numeric, Dim> m_current_interval;
00288 
00289                         std::list<IntervalIntersectionGList*>* m_merge_list;
00290 
00291             // "Simulation" des Vereinigens von Listen mittels MergeList:
00292                         std::list<IntervalIntersectionGList*>::iterator m_merge_iterate;
00293                         std::list<IntervalIntersectionGList*>::iterator m_merge_end;
00294 
00295                 public:
00296 
00298             // ////////////////////////////////////////////////////////////////////
00299                         iterator()
00300             // ////////////////////////////////////////////////////////////////////
00301             {
00302                     m_tree_tree = NULL;
00303                     m_tree = NULL;
00304                     m_iterator = NULL;
00305                     m_current_file = 0;
00306                     m_hitsNecessary = 0;
00307                     m_at_end = false;
00308             }
00309 
00311             // ////////////////////////////////////////////////////////////////////
00312                         iterator(const iterator& copyFrom)
00313             // ////////////////////////////////////////////////////////////////////
00314             {
00315                     m_tree_tree = copyFrom.m_tree_tree;
00316                     m_tree = copyFrom.m_tree;
00317                     m_iterator = copyFrom.m_iterator;
00318                     m_current_file = copyFrom.m_current_file;
00319                     m_hitsNecessary = copyFrom.m_hitsNecessary;
00320                     m_at_end = copyFrom.m_at_end;
00321             }
00322 
00326             // ////////////////////////////////////////////////////////////////////
00327                         iterator(avlTree<treeSaver<tpTREE> >& from_tree, bool begin_or_end, int hitsNeeded)
00328             // ////////////////////////////////////////////////////////////////////
00329             {
00330                     m_hitsNecessary = hitsNeeded;
00331 
00332                     m_tree_tree = &from_tree;
00333 
00334                     if (begin_or_end)
00335                     {
00336                             m_at_end = false;
00337                             m_tree = m_tree_tree->getFirst()->getTree();
00338                             m_current_file = m_tree_tree->getFirst()->getFileNum();
00339                             m_iterator = m_tree->begin();
00340 
00341                             // Jetzt noch den ersten wirklichen Treffer suchen:
00342                             if (*m_iterator)
00343                                     if ((*m_iterator)->matched < m_hitsNecessary)
00344                                             (*this)++;
00345                     }
00346                     else
00347                             m_at_end = true;
00348             }
00349 
00350 
00351             // ////////////////////////////////////////////////////////////////////
00352                         iterator(avlTree<treeSaver<tpTREE> >& from_tree, bool begin_or_end, int hitsNeeded, 
00353                                 std::list<IntervalIntersectionGList*>* mergelist, Group& g_factor)
00354             // ////////////////////////////////////////////////////////////////////
00355             {
00356                     m_hitsNecessary = hitsNeeded;
00357 
00358                     m_merge_list = mergelist;
00359 
00360                     m_merge_iterate = mergelist->begin();
00361                     m_merge_end         = mergelist->end();
00362 
00363                     m_tree_tree = &from_tree;
00364 
00365                 m_g_factor = g_factor;
00366 
00367                     if (begin_or_end)
00368                     {
00369                             m_at_end = false;
00370                             m_tree = m_tree_tree->getFirst()->getTree();
00371                             m_current_file = m_tree_tree->getFirst()->getFileNum();
00372                                         tpTREE::iterator it(m_tree->begin());
00373                             //m_iterator = m_tree->begin();
00374                                         m_iterator = it;
00375 
00376                             // Jetzt noch den ersten wirklichen Treffer suchen:
00377                             if (*m_iterator)
00378                                     if ((*m_iterator)->matched < m_hitsNecessary)
00379                                             (*this)++;
00380                     }
00381                     else
00382                             m_at_end = true;
00383             }
00384 
00385 
00387             // ////////////////////////////////////////////////////////////////////
00388                         inline const Interval<Group, numeric, Dim>& operator *()
00389             // ////////////////////////////////////////////////////////////////////
00390                         {
00391                 if (m_at_end)
00392                     throw IndexingException(IndexingException::END_ITERATOR_DEREFERENCED);
00393                 m_current_interval = *(*m_iterator);
00394                 m_current_interval.g *= m_g_factor;
00395                 m_current_interval .i = m_current_file;
00396                                 return m_current_interval;
00397                         }
00398 
00399 
00400             // ////////////////////////////////////////////////////////////////////
00401                         inline bool operator ==(iterator& compare)
00402             // ////////////////////////////////////////////////////////////////////
00403             {
00404                     if (m_at_end)
00405                             return compare.m_at_end;
00406                     if (compare.m_at_end)
00407                             return m_at_end;
00408                     else
00409                             //return (m_tree_tree == m_tree_tree) && (m_tree == m_tree)
00410                                 //    && (m_iterator == m_iterator);
00411                     // ÄNDERUNG -am 07.12.
00412                             return !compare.m_at_end && (m_tree_tree == compare.m_tree_tree) && (m_tree == compare.m_tree)
00413                                     && (m_iterator == compare.m_iterator);
00414             }
00415 
00416 
00417 
00418             // ////////////////////////////////////////////////////////////////////
00419                         inline bool operator !=(iterator& compare)
00420             // ////////////////////////////////////////////////////////////////////
00421                         {
00422                                 return !(*this==compare);
00423                         }
00424 
00426             // ////////////////////////////////////////////////////////////////////
00427                         iterator &operator ++()
00428             // ////////////////////////////////////////////////////////////////////
00429             {
00430                     m_iterator++;
00431                     if (!*(m_iterator))
00432                     {
00433                             treeSaver<tpTREE>* next = m_tree_tree->getNext();
00434 
00435                             // Hier nur solche Elemente erlauben, die auch Treffer sind.
00436                             if (next)
00437                             {
00438                                     m_tree = next->getTree();
00439                                     m_current_file = next->getFileNum();
00440                                     m_iterator = m_tree->begin();
00441                             }
00442                             else
00443                                     m_tree = NULL;
00444                     }
00445 
00446 /*                  if (*m_iterator)
00447                     {
00448                             if ((*m_iterator)->matched>=m_hitsNecessary)
00449                                     return *this;
00450                             else
00451                                     return (*this)++;
00452                     }
00453                     else 
00454                     {
00455                             // An dieser Stelle wird die Vereinigung von Listen "simuliert":
00456                             MergeListGetNext();
00457 
00458                             if (!*(m_iterator))
00459                                     m_at_end = true;
00460 
00461                             return *this;
00462                     }*/
00463                                 // Umbau des rekursiven Aufrufs:
00464                                 while (*m_iterator && (*m_iterator)->matched<m_hitsNecessary)
00465                                 {
00466                                         m_iterator++;
00467                                         if (!*(m_iterator))
00468                                         {
00469                                                 treeSaver<tpTREE>* next = m_tree_tree->getNext();
00470 
00471                                                 // Hier nur solche Elemente erlauben, die auch Treffer sind.
00472                                                 if (next)
00473                                                 {
00474                                                         m_tree = next->getTree();
00475                                                         m_current_file = next->getFileNum();
00476                                                         m_iterator = m_tree->begin();
00477                                                 }
00478                                                 else
00479                                                         m_tree = NULL;
00480                                         }
00481                     }
00482 
00483                     if (*m_iterator)
00484                             return *this;
00485                     else 
00486                     {
00487                             // An dieser Stelle wird die Vereinigung von Listen "simuliert":
00488                             MergeListGetNext();
00489 
00490                             if (!*(m_iterator))
00491                                     m_at_end = true;
00492 
00493                             return *this;
00494                     }
00495             }
00496                         
00497             // ////////////////////////////////////////////////////////////////////
00498                         iterator &operator ++(int)
00499             // ////////////////////////////////////////////////////////////////////
00500             {
00501                     ++m_iterator;
00502                     if (!*(m_iterator))
00503                     {
00504                             treeSaver<tpTREE>* next = m_tree_tree->getNext();
00505 
00506                             if (next)
00507                             {
00508                                     m_tree = next->getTree();
00509                                     m_current_file = next->getFileNum();
00510                                     m_iterator = m_tree->begin();
00511                             }
00512                             else
00513                                     m_tree = NULL;
00514                     }
00515 
00516                     // Hier nur solche Elemente erlauben, die auch Treffer sind:
00517 /*                  if (*m_iterator)
00518                     {
00519                             if ((*m_iterator)->matched>=m_hitsNecessary)
00520                                     return *this;
00521                             else
00522                                     return (*this)++;
00523                     }
00524                     else 
00525                     {
00526                             // An dieser Stelle wird die Vereinigung von Listen "simuliert":
00527                             MergeListGetNext();
00528 
00529                             if (!*(m_iterator))
00530                                     m_at_end = true;
00531 
00532                             return *this;
00533                     }*/
00534                                 // Umbau des rekursiven Aufrufs:
00535                                 while (*m_iterator && (*m_iterator)->matched<m_hitsNecessary)
00536                                 {
00537                                         m_iterator++;
00538                                         if (!*(m_iterator))
00539                                         {
00540                                                 treeSaver<tpTREE>* next = m_tree_tree->getNext();
00541 
00542                                                 // Hier nur solche Elemente erlauben, die auch Treffer sind.
00543                                                 if (next)
00544                                                 {
00545                                                         m_tree = next->getTree();
00546                                                         m_current_file = next->getFileNum();
00547                                                         m_iterator = m_tree->begin();
00548                                                 }
00549                                                 else
00550                                                         m_tree = NULL;
00551                                         }
00552                     }
00553 
00554                     if (*m_iterator)
00555                             return *this;
00556                     else 
00557                     {
00558                             // An dieser Stelle wird die Vereinigung von Listen "simuliert":
00559                             MergeListGetNext();
00560 
00561                             if (!*(m_iterator))
00562                                     m_at_end = true;
00563 
00564                             return *this;
00565                     }
00566             }
00567 
00568             // ////////////////////////////////////////////////////////////////////
00569                         inline int getCurrentFile()
00570             // ////////////////////////////////////////////////////////////////////
00571             {
00572                     return m_current_file;
00573             }
00574 
00575 
00576 
00577        
00578         public:
00579             // ////////////////////////////////////////////////////////////////////
00580             void MergeListGetNext()
00581             // ////////////////////////////////////////////////////////////////////
00582             {
00583                     if (m_merge_iterate != m_merge_end)
00584                     {
00585                             m_merge_iterate++;
00586 
00587                             if (m_merge_iterate != m_merge_end)
00588                             {
00589                                     m_tree_tree = &((*m_merge_iterate)->treeList);
00590 
00591                                     m_tree = m_tree_tree->getFirst()->getTree();
00592                                     m_current_file = m_tree_tree->getFirst()->getFileNum();
00593                                     m_iterator = m_tree->begin();
00594 
00595                                     // Jetzt noch den ersten wirklichen Treffer suchen:
00596                                     if (*m_iterator)
00597                                             if ((*m_iterator)->matched < m_hitsNecessary)
00598                                                     (*this)++;
00599                             }
00600                     }
00601             }
00602 
00603 
00604         };
00605         // /////////// Iterator Ende   ////////////////////////////////////////
00606 
00607     // ////////////////////////////////////////////////////////////////////
00608     // /////////// pure_iterator Anfang ////////////////////////////////////////
00609     // ////////////////////////////////////////////////////////////////////
00615     class pure_iterator : public iterator
00616         {
00617     public:
00618 
00619             pure_iterator() 
00620                 : iterator()
00621             {}
00622 
00623             pure_iterator(const pure_iterator& p_it) 
00624                 : iterator(p_it)
00625             {}
00626 
00627                         pure_iterator(avlTree<treeSaver<tpTREE> >& from_tree, bool begin_or_end, int hitsNeeded)
00628                 : iterator(from_tree, begin_or_end, hitsNeeded)
00629             {}
00630 
00631                         pure_iterator(avlTree<treeSaver<tpTREE> >& from_tree, bool begin_or_end, int hitsNeeded, 
00632                                 std::list<IntervalIntersectionGList*>* mergelist, Group& g_factor)
00633                 : iterator(from_tree, begin_or_end, hitsNeeded, mergelist, g_factor)
00634             {}
00635 
00637             // ////////////////////////////////////////////////////////////////////
00638                         inline const Interval<Group, numeric, Dim>& operator *()
00639             // ////////////////////////////////////////////////////////////////////
00640                         {
00641                 if (m_at_end)
00642                     throw IndexingException(IndexingException::END_ITERATOR_DEREFERENCED);
00643                 m_current_interval = *(*m_iterator);
00644                 m_current_interval .i = m_current_file;
00645                                 return m_current_interval;
00646                         }
00647 
00648 
00649         };
00650         // /////////// Pure Iterator Ende   ////////////////////////////////////////
00651 
00652 
00653 
00655         inline iterator begin();
00656         inline iterator begin(bool);
00657 
00659         inline pure_iterator pure_begin();
00660         inline pure_iterator pure_begin(bool);
00661 
00663         inline iterator end();
00664         inline iterator end(bool);
00665 
00667         inline pure_iterator pure_end();
00668     inline pure_iterator pure_end(bool);
00669 
00671         inline int size() const;
00672         
00674         inline friend bool operator < (const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl1, const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl2);
00675         
00677         inline friend bool operator > (const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl1, const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl2);
00678         
00679         friend std::ofstream& operator <<(std::ofstream& o, IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& l);
00680 
00682     // geerbt von GInvertedList
00683         //void insert(Group& g, int i);
00684 
00686         void merge(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& set2);
00687 
00689     void setCredit(int credit);
00690 
00692         inline void intersect(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& set2);
00693 
00695         void intersect(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& set2, int credit);
00696 
00698         inline void setHeapStream(std::fstream& hps);
00699 
00700 protected:
00701 
00702         Group g_factor[maxStabSize];
00703         int g_factor_stabSize;
00704 
00706         int intersects;
00707 
00709         int intervals_matched;
00710 
00712         int m_credit;
00713 
00715         unsigned long interval_count;
00716         
00718         numeric min_dist;
00719 
00725         numeric epsilon;
00726 
00727         
00729         unsigned long tree_count;
00730 
00732         Interval<Group, numeric, Dim >* intervals;
00733 
00734 public:
00736         //ekdTree< Interval<Group, numeric, Dim > ,Dim, numeric >** treeList;
00737         avlTree<treeSaver<tpTREE> > treeList;
00738 
00739 protected:
00740         numeric* ranking;
00741         
00743         numeric_writer freadInit;
00744 
00745 
00747         numeric distance(numeric* g1, numeric* g2);
00748         
00750         numeric distance(numeric* g1, Group g2);
00751         
00753         numeric distance(Group g1, Group g2);
00754 
00771         void writeToFile(std::ofstream& ofs);
00772         
00774         ListTupel<Group> operator[](int index);
00775 
00776         /*virtual bool readIntervals(Interval<Group,Dim,L>* buffer)
00777         // buffer muss groß genug sein, daß element_count viele ListTupel
00778         // Platz finden.
00779         {
00780         }*/
00781 
00783         virtual void readElements(ListTupel<Group>* buffer);
00784 
00786         virtual void readIntervals();
00787 
00789         void readElements();
00790         
00792         void initFileRead(std::ifstream& ifs);
00793         void initFileRead(std::fstream& ifs);
00794 
00795 
00801         void deleteFile(int fileindex);
00802         
00808         bool interval_range_search(Group x, int left,int right, int &hit_pos);
00809 
00810         void printElements();
00811         
00812     void pure_printElements();
00813 
00814 
00816 //      int rangeSearch(tpTREE* search_tree, Interval<Group, numeric, Dim >** result);
00817         int rangeSearch(Group& g_1, tpTREE* search_tree, int fileNum, Interval<Group, numeric, Dim >** result);
00819         std::list<IntervalIntersectionGList*> m_merged_with;
00820 };
00821 
00822 /***************************************************************************************
00823  * class Interval (Implementierung)                                                                                                    *
00824  ***************************************************************************************/
00825 
00826 
00827 /* 
00828 // /////////////////////////////////////////////////////////////////////////////////////
00829 ListTupel<Group>& operator=(ListTupel<Group>& lt, const Interval<Group,numeric,Dim>& i)
00830 // /////////////////////////////////////////////////////////////////////////////////////
00831 {
00832         lt = i.lt;
00833         return lt;
00834 }*/
00835  
00836 template<class Group, class numeric, int Dim>
00837 Interval<Group,numeric,Dim>::operator ListTupel<Group>&()
00838 {
00839         return lt;
00840 }
00841  
00842  
00843 template<class Group, class numeric, int Dim>
00844 // /////////////////////////////////////////////////////////////////////////////////////
00845 Interval<Group,numeric,Dim>& Interval<Group,numeric,Dim>::operator = (const Interval<Group,numeric,Dim>& intv)
00846 // /////////////////////////////////////////////////////////////////////////////////////
00847 {
00848         this->g = intv.g;
00849         this->i = intv.i;
00850         for (int i=0; i<Dim; i++)
00851         {
00852                 this->cmax[i] = intv.cmax[i];
00853                 this->cmin[i] = intv.cmin[i];
00854         }
00855         this->matched = intv.matched;
00856     this->credit = intv.credit;
00857         //GInvertedList<Group> new_gl = GInvertedList<Group>(glist);
00858         //*this = new_gl;
00859         return (*this);
00860 }
00861 
00862 template<class Group, class numeric, int Dim>
00863 // /////////////////////////////////////////////////////////////////////////////////////
00864 bool Interval<Group,numeric,Dim>::operator < (Interval<Group, numeric, Dim> &i2) const
00865 // /////////////////////////////////////////////////////////////////////////////////////
00866 {
00867         if (lt.i<i2.lt.i)
00868                 return true;
00869         return false;
00870 }       
00871 
00872 template<class Group, class numeric, int Dim>
00873 // /////////////////////////////////////////////////////////////////////////////////////
00874 bool Interval<Group,numeric,Dim>::operator==(Interval<Group, numeric, Dim > &i2) const
00875 // /////////////////////////////////////////////////////////////////////////////////////
00876 {
00877         if (lt.i!=i2.lt.i)
00878                 return false;
00879         for (int i=0; i<Dim; i++)
00880                 if (lt[i]!=i2.lt.g[i])
00881                         return false;
00882 
00883         return true;
00884 }       
00885 
00886 template<class Group, class numeric, int Dim>
00887 // /////////////////////////////////////////////////////////////////////////////////////
00888 std::ofstream& operator<<(std::ofstream& ofs, Interval<Group, numeric, Dim > i)
00889 // /////////////////////////////////////////////////////////////////////////////////////
00890 {
00891     //ofs<<i.lt.g;
00892     ofs<<(ListTupel<Group>)i;
00893     return ofs;
00894 }
00895 
00896 
00897 template<class Group, class numeric, int Dim>
00898 // /////////////////////////////////////////////////////////////////////////////////////
00899 bool Interval<Group,numeric,Dim>::operator > (const Interval<Group,numeric,Dim >& ic2) const
00900 // /////////////////////////////////////////////////////////////////////////////////////
00901 {
00902         if (i>ic2.i)
00903                 return false;
00904         return true;
00905 }
00906 
00907 template<class Group, class numeric, int Dim>
00908 // /////////////////////////////////////////////////////////////////////////////////////
00909 Interval<Group,numeric,Dim>::Interval()
00910 // /////////////////////////////////////////////////////////////////////////////////////
00911 {
00912         matched = 0;
00913 }
00914 
00915 template<class Group, class numeric, int Dim>
00916 // /////////////////////////////////////////////////////////////////////////////////////
00917 Interval<Group,numeric,Dim>::~Interval()
00918 // /////////////////////////////////////////////////////////////////////////////////////
00919 {
00920         matched = 0;
00921 }
00922 
00923 template<class Group, class numeric, int Dim>
00924 // /////////////////////////////////////////////////////////////////////////////////////
00925 Interval<Group,numeric,Dim>::Interval<Group, numeric, Dim >(ListTupel<Group> mylt)
00926 // /////////////////////////////////////////////////////////////////////////////////////
00927 {
00928         matched = 0;
00929         g = mylt.g;
00930         i= mylt.i;
00931 
00932         for (int i=0; i<Dim; i++)
00933         {
00934                 numeric g_l = g[i];
00935                 cmin[i] = g_l;// - Group::epsilon;
00936                 cmax[i] = g_l;// + Group::epsilon;
00937         }
00938 
00939 }
00940 
00941 template<class Group, class numeric, int Dim>
00942 // /////////////////////////////////////////////////////////////////////////////////////
00943 Interval<Group,numeric,Dim>::Interval(Group myg)
00944 // /////////////////////////////////////////////////////////////////////////////////////
00945 {
00946         matched = 0;
00947         lt.g = myg;
00948 
00949         for (int i=0; i<Dim; i++)
00950         {
00951                 numeric g_l = g[i];
00952                 cmin[i] = g_l;// - Group::epsilon;
00953                 cmax[i] = g_l;// + Group::epsilon;
00954         }
00955 
00956 }
00957 
00958 template<class Group, class numeric, int Dim>
00959 // /////////////////////////////////////////////////////////////////////////////////////
00960 Interval<Group,numeric,Dim>::Interval<Group, numeric, Dim >(Group myg, int newmatched)
00961 // /////////////////////////////////////////////////////////////////////////////////////
00962 {
00963         matched = newmatched;
00964         g = myg;
00965 
00966         for (int i=0; i<Dim; i++)
00967         {
00968                 numeric g_l = myg[i];
00969                 cmin[i] = g_l;// - Group::epsilon;
00970                 cmax[i] = g_l;// + Group::epsilon;
00971         }
00972 
00973 }
00974 
00975 template<class Group, class numeric, int Dim>
00976 // /////////////////////////////////////////////////////////////////////////////////////
00977 Interval<Group,numeric,Dim>::Interval(FILE* stream)
00978 // /////////////////////////////////////////////////////////////////////////////////////
00979 {
00980         lt.g.readFromFile(stream);
00981         matched = 0;
00982 
00983         for (int i=0; i<Dim; i++)
00984         {
00985                 numeric g_l = lt.g[i];
00986                 cmin[i] = g_l;// - Group::epsilon;
00987                 cmax[i] = g_l;// + Group::epsilon;
00988         }
00989 
00990 }
00991 
00992 template<class Group, class numeric, int Dim>
00993 // /////////////////////////////////////////////////////////////////////////////////////
00994 Interval<Group, numeric, Dim>::Interval(std::ifstream& ifs)
00995 // /////////////////////////////////////////////////////////////////////////////////////
00996 {
00997         ifs >> (*this);
00998         matched = 0;
00999 
01000         for (int i=0; i<Dim; i++)
01001         {
01002                 numeric g_l = g[i];
01003                 cmin[i] = g_l;// - Group::epsilon;
01004                 cmax[i] = g_l;// + Group::epsilon;
01005         }
01006 }
01007 
01008 template<class Group, class numeric, int Dim>
01009 // /////////////////////////////////////////////////////////////////////////////////////
01010 Interval<Group, numeric, Dim>::Interval(std::fstream& ifs)
01011 // /////////////////////////////////////////////////////////////////////////////////////
01012 {
01013         ifs >> (*this);
01014         matched = 0;
01015 
01016         for (int i=0; i<Dim; i++)
01017         {
01018                 numeric g_l = g[i];
01019                 cmin[i] = g_l;// - Group::epsilon;
01020                 cmax[i] = g_l;// + Group::epsilon;
01021         }
01022 }
01023 
01024 template<class Group, class numeric, int Dim>
01025 // /////////////////////////////////////////////////////////////////////////////////////
01026 inline unsigned long Interval<Group,numeric,Dim>::indexSize()
01027 // /////////////////////////////////////////////////////////////////////////////////////
01028 {
01029         return g.indexSize() + sizeof(long);
01030 }
01031 
01032 template<class Group, class numeric, int Dim>
01033 // /////////////////////////////////////////////////////////////////////////////////////
01034 inline void Interval<Group,numeric,Dim>::writeToFile(FILE* stream)
01035 // /////////////////////////////////////////////////////////////////////////////////////
01036 {
01037         lt.g.writeToFile(stream);
01038 }
01039 
01040 template<class Group, class numeric, int Dim>
01041 // /////////////////////////////////////////////////////////////////////////////////////
01042 bool Interval<Group,numeric,Dim>::expand(Group &x)
01043 // /////////////////////////////////////////////////////////////////////////////////////
01044 {
01045 
01046         int i;
01047 
01048         //for (i=0; i<Dim; i++)
01049         //{
01050         //      if (abs(cmax[i]-x[i]) >= Group::epsilon)
01051         //              return false;
01052         //}
01053         for (i=0; i<Dim; i++)
01054         {
01055                 numeric g_i = x[i];
01056                 cmin[i] = cmin[i] < g_i ? cmin[i] : g_i;
01057                 cmax[i] = cmax[i] > g_i ? cmax[i] : g_i;
01058         }
01059 
01060         return true;
01061 
01062 }
01063 
01064 template<class Group, class numeric, int Dim>
01065 // /////////////////////////////////////////////////////////////////////////////////////
01066 inline numeric Interval<Group,numeric,Dim>::operator[](int i) 
01067 // /////////////////////////////////////////////////////////////////////////////////////
01068 {
01069         return g[i];
01070 }
01071 
01072 
01073 /***************************************************************************************
01074  * class treeSaver      (Implementierung)                                                                                      *
01075  ***************************************************************************************/
01076 
01077 template <class treetype>
01078 // /////////////////////////////////////////////////////////////////////////////////////
01079 treeSaver<treetype>::treeSaver()
01080 // /////////////////////////////////////////////////////////////////////////////////////
01081 {
01082         m_tree=NULL;
01083         filenum=0;
01084 }
01085 
01086 template <class treetype>
01087 // /////////////////////////////////////////////////////////////////////////////////////
01088 treeSaver<treetype>::treeSaver(treetype* tree, int pos)
01089 // /////////////////////////////////////////////////////////////////////////////////////
01090 {
01091         m_tree  = new treetype*;
01092         *m_tree  = tree;
01093         filenum = pos;
01094 }
01095 
01096 template <class treetype>
01097 // /////////////////////////////////////////////////////////////////////////////////////
01098 inline treeSaver<treetype>::~treeSaver()
01099 // /////////////////////////////////////////////////////////////////////////////////////
01100 {
01101         if (m_tree)
01102     {
01103         delete m_tree;
01104         m_tree = NULL;
01105     }
01106 }
01107 
01108 template <class treetype>
01109 // /////////////////////////////////////////////////////////////////////////////////////
01110 inline treetype* treeSaver<treetype>::getTree()
01111 // /////////////////////////////////////////////////////////////////////////////////////
01112 {
01113         return *m_tree;
01114 }
01115 
01116 template <class treetype>
01117 // /////////////////////////////////////////////////////////////////////////////////////
01118 inline int treeSaver<treetype>::getFileNum()
01119 // /////////////////////////////////////////////////////////////////////////////////////
01120 {
01121         return filenum;
01122 }
01123 
01124 template <class treetype>
01125 // /////////////////////////////////////////////////////////////////////////////////////
01126 inline bool treeSaver<treetype>::operator < (treeSaver& compare)
01127 // /////////////////////////////////////////////////////////////////////////////////////
01128 {
01129         return filenum < compare.filenum;
01130 }
01131 
01132 template <class treetype>
01133 // /////////////////////////////////////////////////////////////////////////////////////
01134 inline bool treeSaver<treetype>::operator == (treeSaver& compare)
01135 // /////////////////////////////////////////////////////////////////////////////////////
01136 {
01137         return filenum == compare.filenum;
01138 }
01139 
01140 template <class treetype>
01141 // /////////////////////////////////////////////////////////////////////////////////////
01142 treeSaver<treetype>::operator = (treeSaver& setto)
01143 // /////////////////////////////////////////////////////////////////////////////////////
01144 {
01145         if (m_tree) delete m_tree;
01146         m_tree = new treetype*;
01147 
01148         *m_tree = *setto.m_tree;
01149         filenum = setto.filenum;
01150 }
01151 
01152 
01153 /***************************************************************************************
01154  * class IntervalIntersectionGList (GInvertedList) (Implementierung)                           *
01155  ***************************************************************************************/
01156 
01157 template<class Group, class numeric, int Dim, class numeric_writer>
01158 // /////////////////////////////////////////////////////////////////////////////////////
01159 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >(long id) : GInvertedList<Group>(id)
01160 // ////////////////////////////////////////////////////////////////////////////////////
01161 {
01162     ranking = NULL;
01163 }
01164 
01165 template<class Group, class numeric, int Dim, class numeric_writer>
01166 // /////////////////////////////////////////////////////////////////////////////////////
01167 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::IntervalIntersectionGList(const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& glist) : GInvertedList<Group>(glist)
01168 // /////////////////////////////////////////////////////////////////////////////////////
01169 {
01170         ranking = NULL;
01171 /*      m_stream = glist.mystream;
01172         strcpy(insertion_file_name,glist.insertion_file_name);
01173         my_fileoffset = glist.my_fileoffset;
01174         mode = glist.mode;
01175 
01176         epsilon = glist.epsilon;
01177 
01178         m_elements = NULL;*/
01179         intervals = NULL;
01180 
01181         interval_count = glist.interval_count;
01182         min_dist = glist.min_dist;
01183         tree_count = glist.tree_count;
01184 
01185         m_element_count = glist.m_element_count;
01186         intersects = 0;
01187         m_credit = glist.m_credit;
01188 }
01189 
01190 template<class Group, class numeric, int Dim, class numeric_writer>
01191 // /////////////////////////////////////////////////////////////////////////////////////
01192 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::IntervalIntersectionGList() : GInvertedList<Group>()
01193 // /////////////////////////////////////////////////////////////////////////////////////
01194 {
01195         ranking = NULL;
01196         m_elements = NULL;
01197         intervals = NULL;
01198 
01199     interval_count = 0;
01200         insertion_file_name[0] = '\0';
01201         element_count = 0;
01202 
01203         mode = MODE_CREATE_INDEX;
01204         intersects = 0;
01205 
01206         tree_count = 0;
01207         m_credit = 0;
01208 }
01209 
01210 template<class Group, class numeric, int Dim, class numeric_writer>
01211 // /////////////////////////////////////////////////////////////////////////////////////
01212 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::IntervalIntersectionGList(std::ifstream& ifs)
01213 // /////////////////////////////////////////////////////////////////////////////////////
01214 {
01215 
01216     ranking = NULL;
01217 
01218     ins_buffer_size = INS_BUFFER_SIZE;
01219     ins_buffer_pos = 0;
01220     insertion_buffer=NULL;
01221     
01222     initFileRead(ifs);
01223 }
01224 
01225 template<class Group, class numeric, int Dim, class numeric_writer>
01226 // /////////////////////////////////////////////////////////////////////////////////////
01227 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::IntervalIntersectionGList(std::fstream& ifs)
01228 // /////////////////////////////////////////////////////////////////////////////////////
01229 {
01230 
01231     ranking = NULL;
01232 
01233     ins_buffer_size = INS_BUFFER_SIZE;
01234     ins_buffer_pos = 0;
01235     insertion_buffer=NULL;
01236     
01237     initFileRead(ifs);
01238 }
01239 
01240 template<class Group, class numeric, int Dim, class numeric_writer>
01241 // /////////////////////////////////////////////////////////////////////////////////////
01242 inline void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::setHeapStream(std::fstream& hps)
01243 // /////////////////////////////////////////////////////////////////////////////////////
01244 {
01245 }
01246 
01247 template<class Group, class numeric, int Dim, class numeric_writer>
01248 // /////////////////////////////////////////////////////////////////////////////////////
01249 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::begin()
01250 // /////////////////////////////////////////////////////////////////////////////////////
01251 {
01252     readIntervals();
01253         return iterator(treeList, true, intersects-m_credit, &m_merged_with, m_factor);
01254 }
01255 
01256 template<class Group, class numeric, int Dim, class numeric_writer>
01257 // /////////////////////////////////////////////////////////////////////////////////////
01258 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_begin()
01259 // /////////////////////////////////////////////////////////////////////////////////////
01260 {
01261     readIntervals();
01262         return pure_iterator(treeList, true, intersects-m_credit, &m_merged_with, m_factor);
01263 }
01264 
01265 template<class Group, class numeric, int Dim, class numeric_writer>
01266 // /////////////////////////////////////////////////////////////////////////////////////
01267 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::begin(bool)
01268 // /////////////////////////////////////////////////////////////////////////////////////
01269 {
01270         return begin();
01271 }
01272 
01273 template<class Group, class numeric, int Dim, class numeric_writer>
01274 // /////////////////////////////////////////////////////////////////////////////////////
01275 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_begin(bool)
01276 // /////////////////////////////////////////////////////////////////////////////////////
01277 {
01278         return pure_begin();
01279 }
01280 
01281 template<class Group, class numeric, int Dim, class numeric_writer>
01282 // /////////////////////////////////////////////////////////////////////////////////////
01283 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::end()
01284 // /////////////////////////////////////////////////////////////////////////////////////
01285 {
01286         return iterator(treeList, false, intersects-m_credit, &m_merged_with, m_factor);
01287 }
01288 
01289 template<class Group, class numeric, int Dim, class numeric_writer>
01290 // /////////////////////////////////////////////////////////////////////////////////////
01291 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::end(bool dummy)
01292 // /////////////////////////////////////////////////////////////////////////////////////
01293 {
01294         return end();
01295 }
01296 
01297 template<class Group, class numeric, int Dim, class numeric_writer>
01298 // /////////////////////////////////////////////////////////////////////////////////////
01299 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_end()
01300 // /////////////////////////////////////////////////////////////////////////////////////
01301 {
01302         return pure_iterator(treeList, false, intersects-m_credit, &m_merged_with, m_factor);
01303 }
01304 
01305 template<class Group, class numeric, int Dim, class numeric_writer>
01306 // /////////////////////////////////////////////////////////////////////////////////////
01307 inline IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_iterator IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_end(bool dummy)
01308 // /////////////////////////////////////////////////////////////////////////////////////
01309 {
01310         return pure_end();
01311 }
01312 
01313 template<class Group, class numeric, int Dim, class numeric_writer>
01314 // /////////////////////////////////////////////////////////////////////////////////////
01315 inline int IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::size() const
01316 // /////////////////////////////////////////////////////////////////////////////////////
01317 {
01318         return interval_count;
01319 }
01320 
01321 template<class Group, class numeric, int Dim, class numeric_writer>
01322 // /////////////////////////////////////////////////////////////////////////////////////
01323 numeric IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::distance(numeric* g1, numeric* g2)
01324 // /////////////////////////////////////////////////////////////////////////////////////
01325 {
01326 
01327         numeric max_dist = 0;
01328         numeric diff;
01329 
01330         for (int i=0; i<Dim; i++)
01331         {
01332                 numeric l1 = g1[i];
01333                 numeric l2 = g2[i];
01334                 if (l2 < l1)
01335                         diff = l1-l2;
01336                 else
01337                         diff = l2-l1;
01338                 if (max_dist<diff)
01339                         max_dist = diff;
01340         }
01341 
01342         return max_dist;
01343 
01344 }
01345 
01346 template<class Group, class numeric, int Dim, class numeric_writer>
01347 // /////////////////////////////////////////////////////////////////////////////////////
01348 numeric IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::distance(numeric* g1, Group g2)
01349 // /////////////////////////////////////////////////////////////////////////////////////
01350 {
01351 
01352         numeric max_dist = 0;
01353         numeric diff;
01354 
01355         for (int i=0; i<Dim; i++)
01356         {
01357                 numeric l1 = g1[i];
01358                 numeric l2 = g2[i];
01359                 if (l2 < l1)
01360                         diff = l1-l2;
01361                 else
01362                         diff = l2-l1;
01363                 if (max_dist<diff)
01364                         max_dist = diff;
01365         }
01366 
01367         return max_dist;
01368 
01369 }
01370 
01371 template<class Group, class numeric, int Dim, class numeric_writer>
01372 // /////////////////////////////////////////////////////////////////////////////////////
01373 numeric IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::distance(Group g1, Group g2)
01374 // /////////////////////////////////////////////////////////////////////////////////////
01375 {
01376 
01377         numeric max_dist = 0;
01378         numeric diff;
01379 
01380         for (int i=0; i<Dim; i++)
01381         {
01382                 numeric l1 = g1[i];
01383                 numeric l2 = g2[i];
01384                 if (l2 < l1)
01385                         diff = l1-l2;
01386                 else
01387                         diff = l2-l1;
01388                 if (max_dist < diff)
01389                         max_dist = diff;
01390         }
01391 
01392         return max_dist;
01393 
01394 }
01395 
01396 template<class Group, class numeric, int Dim, class numeric_writer>
01397 // /////////////////////////////////////////////////////////////////////////////////////
01398 inline bool operator < (const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl1, const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl2)
01399 // /////////////////////////////////////////////////////////////////////////////////////
01400 { 
01401         return sl1.size() < sl2.size();
01402 }
01403 
01404 template<class Group, class numeric, int Dim, class numeric_writer>
01405 // /////////////////////////////////////////////////////////////////////////////////////
01406 inline bool operator > (const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl1, const IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& sl2)
01407 // /////////////////////////////////////////////////////////////////////////////////////
01408 { 
01409         return sl1.size() > sl2.size();
01410 }
01411 
01412 template<class Group, class numeric, int Dim, class numeric_writer>
01413 // /////////////////////////////////////////////////////////////////////////////////////
01414 std::ofstream& operator << (std::ofstream& o, IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& l)
01415 // /////////////////////////////////////////////////////////////////////////////////////
01416 {
01417         l.writeToFile(o);
01418         return o;
01419 }
01420 
01421 template<class Group, class numeric, int Dim, class numeric_writer>
01422 // /////////////////////////////////////////////////////////////////////////////////////
01423 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::writeToFile(std::ofstream& ofs)
01424 // /////////////////////////////////////////////////////////////////////////////////////
01425 {
01426 
01427     // insertion_buffer Flushen
01428     if (insertion_buffer != NULL && ins_buffer_pos != 0)
01429     {
01430 
01431         if (chdir("list")==-1)
01432             #ifdef VISUALC_INCLUDES
01433             mkdir("list");
01434             #else
01435             mkdir("list",0);
01436             #endif
01437         else
01438             chdir("..");
01439 
01440             std::/*o*/fstream buf_insertion_stream;
01441         buf_insertion_stream.open(m_insertion_file_name, std::ios::app | std::ios::out | std::ios::binary);
01442             if (!buf_insertion_stream)
01443             {
01444             throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01445                     return;
01446             }
01447 
01448         for (int j=0; j<ins_buffer_pos; j++)
01449             buf_insertion_stream<<insertion_buffer[j];
01450         ins_buffer_pos = 0;
01451 
01452         buf_insertion_stream.close();
01453 
01454     }
01455 
01456         std::ifstream insertion_stream;
01457     insertion_stream.open(m_insertion_file_name,std::ios::binary);
01458 
01459     // Zunächst werden bereits indexierte Objekte verworfen, d.h, 
01460     // es werden nur Elemente indexiert, die seit dem letzten Schreibvorgang
01461     // mit insert() eingefügt wurden.
01462     m_element_count = m_new_element_count;
01463     // Später könnten hier zunächst die bereits indexierten Elemente 
01464     // (von denen es m_element_count viele gibt) noch zusätzlich eingelesen werden.
01465 
01466         if (!insertion_stream)
01467         {
01468                 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01469                 return;
01470         }
01471 
01472         // file-pointer an Anfang setzen
01473     insertion_stream.seekg(0,std::ios::beg);
01474 
01475         Interval<Group, numeric, Dim >* code_elements = new Interval<Group, numeric, Dim >[m_element_count];
01476 
01477         tree_count = 0;
01478 
01479         if (code_elements==NULL /*|| treeList==NULL*/)
01480         {
01481                 throw IndexingException(IndexingException::OUT_OF_MEMORY);
01482         }
01483         
01484         // Alle Datensätze aus File in array lesen;
01485         // Platzbedarf aller ekdTrees aus der Liste berechnen
01486         for (int i=0; i<m_element_count; i++)
01487         {
01488                 ListTupel<Group> lt;
01489                 
01490                 insertion_stream>>lt;
01491 
01492                 if (!insertion_stream)
01493                 {
01494                         throw IndexingException(IndexingException::FILE_ERROR_READ);
01495                         return;
01496                 }
01497 
01498                 //Interval<Group,Dim,L> ilc(lt);
01499                 Interval<Group, numeric, Dim > ilc(lt);
01500                 code_elements[i] = ilc;
01501         }
01502 
01503     insertion_stream.close();
01504 
01505         // array sortieren bzgl. Dateiindex (i.e. lt.i)
01506         heapsort< Interval<Group, numeric, Dim > >(code_elements,m_element_count);
01507 
01508     min_dist = FLT_MAX;
01509         
01510         tree_count = 0;
01511         int tree_start = 0;
01512         int tree_size = 0;
01513     int ins_pos = 1;
01514 
01515 /*      for (i=1; i<m_element_count; i++)
01516         {
01517                 // durch diese Abfrage wird verhindert, daß gleiche ListTupel mehrfach in
01518                 // einer G-invertierten Liste gespeichert werden.
01519                 numeric dist = distance(code_elements[i].g,code_elements[ins_pos-1].g);
01520                 if ((code_elements[i].i != code_elements[ins_pos-1].i) 
01521                         || dist != 0)
01522                 {
01523             code_elements[ins_pos] = code_elements[i];
01524             ins_pos++;
01525         }
01526     }
01527     m_element_count = ins_pos;*/
01528 
01529         for (i=1; i<m_element_count; i++)
01530         {
01531                 if (i<m_element_count && code_elements[i].i!=code_elements[i-1].i)
01532                 {
01533                         
01534                         // neuen ekdTree erzeugen
01535                         treeList.insert(treeSaver<tpTREE>
01536                                 (new tpTREE(&(code_elements[tree_start]),i-tree_start), code_elements[i-1].i));
01537                         
01538                         tree_size += treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->indexSize() 
01539                                 + sizeof (int);
01540                         
01541                         if (treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->epsilon<min_dist)
01542                                 min_dist = treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->epsilon;
01543 
01544                         tree_count++;
01545                         tree_start = i;
01546 
01547                 }
01548         }
01549 
01550         // ekdTree für die letzten Elemente der Liste erzeugen
01551         treeList.insert(*(new treeSaver<tpTREE>
01552                 (new tpTREE(&(code_elements[tree_start]),i-tree_start), code_elements[i-1].i)));
01553 
01554         tree_size += treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->indexSize() + sizeof (int);
01555         if (treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->epsilon<min_dist)
01556                 min_dist = treeList.findData(treeSaver<tpTREE >(NULL, code_elements[i-1].i))->getTree()->epsilon;
01557         tree_count++;
01558 
01559 
01560 
01561         //... zuerst die Minimaldistanz in die Datei schreiben
01562         // ACHTUNG: möglicher Konflikt bei LEDA/real; deshalb werden
01563         // ALLE Minimaldistanzen, gleich welchen Typs, als numeric_writer in die Datei geschrieben
01564     
01565 
01566         numeric_writer md;
01567         md = min_dist;
01568         md.write(ofs);
01569         //... und dann die Anzahl von ekd-Bäumen
01570         ofs.write((char*)&tree_count,sizeof(unsigned long));
01571         //... und dann die Anzahl von Einträgen insgesamt
01572         ofs.write((char*)&m_element_count,sizeof(unsigned long));
01573         // ... dann die Länge der Liste schreiben (Platz für min_dist und tree_count NICHT mitrechnen!)
01574         //long bytesize = unique_element_count*(Group::indexSize()+sizeof(int));
01576     long pos_old = ofs.tellp();
01578 
01579     unsigned long bytesize = tree_size;
01580     ofs.write((char*)&bytesize, sizeof(unsigned long));
01581 
01582         long tmp = ofs.tellp();
01583         
01584         //int written = 1;
01585         avlTree<treeSaver<tpTREE> >::iterator itTree = treeList.begin();
01586         avlTree<treeSaver<tpTREE> >::iterator itStop = treeList.end();
01587         int FileNum;
01588         while (itTree!=itStop)
01589         {
01590                 FileNum = (*itTree)->getFileNum();
01591                 ofs.write((char*)&FileNum, sizeof(FileNum));
01592                 
01593         ofs<<*((*itTree)->getTree());
01594                 //delete (*itTree)->getTree();
01595                 ++itTree;
01596         }
01597 
01599     long pos_new = ofs.tellp();
01601 
01602     delete[] code_elements;
01603         
01604     ::remove(m_insertion_file_name);
01605 }
01606 
01607 template<class Group, class numeric, int Dim, class numeric_writer>
01608 // /////////////////////////////////////////////////////////////////////////////////////
01609 ListTupel<Group> IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::operator[](int index)
01610 // /////////////////////////////////////////////////////////////////////////////////////
01611 // VORSICHT: Vor Aufruf dieses Operators müssen die Variablen
01612 // mystream, my_fileoffset sowie gsize mit initFileRead() gesetzt
01613 // werden!
01614 {       
01615 
01616         ListTupel<Group> lt = ListTupel<Group>();
01617 
01618         if (mode!=MODE_SEARCH)
01619                 return lt;
01620         
01621         // offset im File berechnen und von der Stelle aus lesen...
01622         long offset = my_fileoffset + index*(Group::indexSize()+sizeof(int));
01623         fseek(mystream, offset, SEEK_SET);
01624         fread(&lt, Group::indexSize(), 1, mystream);
01625         return lt;
01626 }
01627 
01628 template<class Group, class numeric, int Dim, class numeric_writer>
01629 // /////////////////////////////////////////////////////////////////////////////////////
01630 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::readElements(ListTupel<Group>* buffer)
01631 // /////////////////////////////////////////////////////////////////////////////////////
01632 // buffer muss groß genug sein, daß element_count viele ListTupel
01633 // Platz finden.
01634 /*********************************************************************
01635 * FORMAT:                                                                                                                        *
01636 * sizeof(unsigned long) Bytes Länge der gesamten Liste in Bytes      *
01637 * sizeof(numeric)        Bytes Minimaldistanz                        *
01638 * sizeof(unsigned long) Bytes Anzahl von ekd-Bäumen                                      *
01639 *                                                                    *
01640 * Danach für jeden ekd-Baum der Liste:                               *
01641 * sizeof(int) Dateiindex                                                                                         *
01642 * sizeof(unsigned long) Bytes Größe des ekd-Baumes in Bytes          *
01643 **********************************************************************
01644 */
01645 {
01646         readIntervals();
01647 }
01648 
01649 template<class Group, class numeric, int Dim, class numeric_writer>
01650 // /////////////////////////////////////////////////////////////////////////////////////
01651 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::readIntervals()
01652 // /////////////////////////////////////////////////////////////////////////////////////
01653 {
01654 
01655         //if (epsilon>Group::max_epsilon)
01656         //      epsilon = Group::max_epsilon;
01657 
01658         intervals_matched = m_element_count;
01659 
01660         if (tree_count==0)
01661                 return;
01662 
01663         // wenn die Elemente bereits gelesen sind, werden sie nicht nochmal gelesen...
01664         if (treeList.numberOfNodes()>0)
01665                 return;
01666 
01667     m_stream->seekg(m_fileoffset, std::ios::beg);
01668         if (!(*m_stream))
01669         {
01670                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01671                 return;
01672         }
01673 
01674         for (int i=0; i<tree_count; i++)
01675         {
01676 
01677                 int tidx;
01678                 m_stream->read((char*)&tidx,sizeof(int));
01679                 if (!(*m_stream))
01680                 {
01681                         throw IndexingException(IndexingException::FILE_ERROR_READ);
01682                         return;
01683                 }
01684 
01685                 treeList.insert(treeSaver<tpTREE>(new tpTREE(*m_stream), tidx));
01686                 if (!(*m_stream))
01687                 {
01688                         throw IndexingException(IndexingException::FILE_ERROR_READ);
01689                         return;
01690                 }
01691         }
01692 
01693         //interval_count = element_count;
01694 }
01695         
01696 template<class Group, class numeric, int Dim, class numeric_writer>
01697 // /////////////////////////////////////////////////////////////////////////////////////
01698 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::readElements()
01699 // /////////////////////////////////////////////////////////////////////////////////////
01700 {
01701         intervals_matched = m_element_count;
01702 
01703         if (tree_count>0)
01704                 readIntervals();
01705 }
01706 
01707 /*template<class Group, class numeric, int Dim, class numeric_writer>
01708 // /////////////////////////////////////////////////////////////////////////////////////
01709 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::insert(Group& g, int i)
01710 // /////////////////////////////////////////////////////////////////////////////////////
01711 {
01712 
01713         // Index muss sich im Einfügemodus befinden
01714         FILE* insertion_stream = fopen(m_insertion_file_name, "ab");
01715 
01716         if (insertion_stream==NULL)
01717         {
01718                 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01719                 return;
01720         }
01721 
01722         if (ferror(insertion_stream)!=0)
01723         {
01724                 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01725                 return;
01726         }
01727 
01728         ListTupel<Group>* lt = new ListTupel<Group>();
01729         lt->g = g;
01730         lt->i = i;
01731 
01732         //fwrite(lt,sizeof(ListTupel<Group>),1,insertion_stream);
01733         g.writeToFile(insertion_stream);
01734         fwrite(&i,sizeof(int),1,insertion_stream);
01735         
01736         fclose(insertion_stream);
01737 
01738         delete lt;
01739 
01740         m_element_count++;
01741 
01742 }*/
01743 
01744 template<class Group, class numeric, int Dim, class numeric_writer>
01745 // /////////////////////////////////////////////////////////////////////////////////////
01746 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::initFileRead(std::ifstream& ifs)
01747 // /////////////////////////////////////////////////////////////////////////////////////
01748 /************************************************************************
01749 * FORMAT:                                                                                                                           *
01750 * sizeof(numeric_writer)        Bytes   Minimaldistanz                          *
01751 * sizeof(unsigned long) Bytes   Anzahl von ekd-Bäumen                                   *
01752 * sizeof(unsigned long) Bytes   Anzahl von Einträgen insgesamt              *
01753 * sizeof(unsigned long) Bytes   Länge des verbleibenden Teils der Liste *
01754 *                                                               in Bytes                                                                *
01755 *                                                                       *
01756 * Danach für jeden ekd-Baum der Liste:                                  *
01757 *                                                                                                                                               *
01758 * sizeof(int) Bytes             Dateiindex                                                              *                               
01759 * ? Bytes                       ekd-Baum                                                                *
01760 *************************************************************************
01761 */
01762 {
01763 
01764         freadInit = 1.0;
01765 
01766         // Minimaldistanz dieser Liste auslesen
01767         numeric_writer md;
01768         md.read(ifs);
01769         min_dist = md;
01770 
01771         if (!ifs)
01772         {
01773                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01774                 return;
01775         }
01776 
01777         // Anzahl ekd-Bäume der aktuellen Liste ermitteln
01778         ifs.read((char*)&tree_count, sizeof(unsigned long));
01779         if (!ifs)
01780         {
01781                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01782                 return;
01783         }
01784 
01785         // Anzahl Einträge in der aktuellen Liste ermitteln
01786         ifs.read((char*)&m_element_count, sizeof(unsigned long));
01787         if (!ifs)
01788         {
01789                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01790                 return;
01791         }
01792     interval_count = m_element_count;
01793 
01794         // Wieviele Bytes müssen bis zum Anfang der nächsten G-Liste übersprungen werden?
01795         // => bsize viele!
01796         unsigned long bsize;
01797         ifs.read((char*)&bsize, sizeof(unsigned long));
01798         if (!ifs)
01799         {
01800                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01801                 return;
01802         }
01803 
01804         // An der aktuellen Position in der Datei können bei Bedarf die Einträge 
01805         // der Liste ausgelesen werden; deshalb merken wir uns diese Position
01806         // in der Memeber-Variable my_fileoffset!
01807 
01808         m_stream = &ifs;
01809         m_fileoffset = ifs.tellg();
01810         if (!ifs)
01811         {
01812                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01813                 return;
01814         }
01815 
01816         // stream-Position auf nächste Liste setzen
01817     ifs.seekg(bsize, std::ios::cur);
01818         if (!ifs)
01819         {
01820                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01821                 return;
01822         }
01823 
01824 }
01825 
01826 template<class Group, class numeric, int Dim, class numeric_writer>
01827 // /////////////////////////////////////////////////////////////////////////////////////
01828 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::initFileRead(std::fstream& ifs)
01829 // /////////////////////////////////////////////////////////////////////////////////////
01830 /************************************************************************
01831 * FORMAT:                                                                                                                           *
01832 * sizeof(numeric_writer)        Bytes   Minimaldistanz                          *
01833 * sizeof(unsigned long) Bytes   Anzahl von ekd-Bäumen                                   *
01834 * sizeof(unsigned long) Bytes   Anzahl von Einträgen insgesamt              *
01835 * sizeof(unsigned long) Bytes   Länge des verbleibenden Teils der Liste *
01836 *                                                               in Bytes                                                                *
01837 *                                                                       *
01838 * Danach für jeden ekd-Baum der Liste:                                  *
01839 *                                                                                                                                               *
01840 * sizeof(int) Bytes             Dateiindex                                                              *                               
01841 * ? Bytes                       ekd-Baum                                                                *
01842 *************************************************************************
01843 */
01844 {
01845 
01846         freadInit = 1.0;
01847 
01848         // Minimaldistanz dieser Liste auslesen
01849         numeric_writer md;
01850         md.read(ifs);
01851         min_dist = md;
01852 
01853         if (!ifs)
01854         {
01855                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01856                 return;
01857         }
01858 
01859         // Anzahl ekd-Bäume der aktuellen Liste ermitteln
01860         ifs.read((char*)&tree_count, sizeof(unsigned long));
01861         if (!ifs)
01862         {
01863                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01864                 return;
01865         }
01866 
01867         // Anzahl Einträge in der aktuellen Liste ermitteln
01868         ifs.read((char*)&m_element_count, sizeof(unsigned long));
01869         if (!ifs)
01870         {
01871                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01872                 return;
01873         }
01874     interval_count = m_element_count;
01875 
01876         // Wieviele Bytes müssen bis zum Anfang der nächsten G-Liste übersprungen werden?
01877         // => bsize viele!
01878         unsigned long bsize;
01879         ifs.read((char*)&bsize, sizeof(unsigned long));
01880         if (!ifs)
01881         {
01882                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01883                 return;
01884         }
01885 
01886         // An der aktuellen Position in der Datei können bei Bedarf die Einträge 
01887         // der Liste ausgelesen werden; deshalb merken wir uns diese Position
01888         // in der Memeber-Variable my_fileoffset!
01889 
01890         m_stream = &ifs;
01891         m_fileoffset = ifs.tellg();
01892         if (!ifs)
01893         {
01894                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01895                 return;
01896         }
01897 
01898         // stream-Position auf nächste Liste setzen
01899     ifs.seekg(bsize, std::ios::cur);
01900     
01901     //char buf[1024];
01902     //ifs.read(&(buf[0]),1024);
01903 
01904         if (!ifs)
01905         {
01906                 throw IndexingException(IndexingException::FILE_ERROR_READ);
01907                 return;
01908         }
01909 
01910 }
01911 
01912 template<class Group, class numeric, int Dim, class numeric_writer>
01913 // /////////////////////////////////////////////////////////////////////////////////////
01914 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::deleteFile(int fileindex)
01915 // /////////////////////////////////////////////////////////////////////////////////////
01916 {
01917         if (mode!=MODE_CREATE_INDEX)
01918         {
01919                 throw IndexingException(IndexingException::INDEX_WRONG_MODE);
01920                 return;
01921         }
01922 
01923         FILE* insertion_stream = fopen(insertion_file_name, "rb");
01924         if (insertion_stream==NULL)
01925         {
01926                 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01927                 return;
01928         }
01929 
01930         rewind(insertion_stream);
01931 
01932         ListTupel<Group>* elements = new ListTupel<Group>[element_count];
01933         
01934         // Alle Datensätze aus File in array lesen
01935         for (int i=0; i<element_count; i++)
01936         {
01937                 elements[i].g.readFromFile(insertion_stream);
01938                 fread(&(elements[i].i), sizeof(int), 1, insertion_stream);
01939                 if (ferror(insertion_stream)!=0)
01940                         return false;
01941         }
01942 
01943         fclose(insertion_stream);
01944 
01945         insertion_stream = fopen(insertion_file_name, "wb");
01946         if (insertion_stream==NULL)
01947         {
01948                 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
01949                 return;
01950         }
01951 
01952         int new_element_count = 0;
01953 
01954         for (i=0; i<element_count; i++)
01955         {
01956                 if (elements[i].i!=fileindex)
01957                 {
01958                         elements[i].g.writeToFile(insertion_stream);
01959                         fwrite(&(elements[i].i),sizeof(int),1,insertion_stream);
01960                         new_element_count++;
01961                         // elements[i] in Datei schreiben
01962                 }
01963         }
01964 
01965         fclose (insertion_stream);
01966 
01967         element_count = new_element_count;
01968 
01969         delete[] elements;
01970 
01971 }
01972 
01973 template<class Group, class numeric, int Dim, class numeric_writer>
01974 // /////////////////////////////////////////////////////////////////////////////////////
01975 bool IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::interval_range_search(Group x, int left,int right, int &hit_pos)
01976 // /////////////////////////////////////////////////////////////////////////////////////
01977 {
01978         // EIN FÜR ALLE MAL:
01979         // Die Intervalle sind ABSTEIGEND sortiert.
01980         // Der größte Wert hat Index 0, der kleinste Index element_count!
01981 
01982         Interval<Group, numeric, Dim > ilc_x(x);
01983         
01985         //BEGIN DEBUG
01986         
01987         //for (int i=left; i<=right; i++)
01988         //{
01989         //      unsigned long diff = distance(intervals[i].cmin , ilc_x.g);
01990         //      hit_pos = i;
01991         //      if (diff<=Group::epsilon)
01992         //              return true;                    
01993         //}
01994         //return false;
01995         
01996         // END DEBUG
01998 
01999         bool found = false;
02000         int mid;
02001 
02002         if (left==right)
02003         {
02004                 //unsigned long diff = array[left] > x ? array[left]-x : x-array[left];
02005                 numeric diff = distance(intervals[left].cmin , ilc_x.g);
02006                 hit_pos = left;
02007                 if (diff<=Group::epsilon)
02008                         return true;
02009 
02010                 return false;
02011         }
02012         
02013         if (intervals[left]<intervals[right])
02014         { cout<<"Fehler im Index?\n";cout.flush(); }
02015 
02016         if (ilc_x < intervals[right])
02017         {
02018                 left = right-1;
02019                 hit_pos = right;
02020                 //unsigned long diff = array[left] > x ? array[left]-x : x-array[left];
02021                 numeric diff = distance(intervals[right].cmin,ilc_x.g);
02022                 if (diff<=Group::epsilon)
02023                         return true;
02024                 return false;
02025         }
02026         if (intervals[left] < ilc_x)
02027     { 
02028                 //left--;
02029                 right = left+1;
02030                 hit_pos = left;
02031                 //unsigned long diff = array[right] > x ? array[right]-x : x-array[right];
02032                 numeric diff = distance(intervals[left].cmin,ilc_x.g);
02033                 if (diff<=Group::epsilon)
02034                         return true;
02035                 return false;
02036         }
02037 
02038         while (left<right-1 && !found)
02039         {
02040                 
02041                 mid = (left+right)/2;
02042 
02043                 Interval<Group, numeric, Dim > cmp = intervals[mid];
02044                 if (cmp==ilc_x)
02045                         found = true;
02046                 else if (cmp<ilc_x)
02047                         right = mid;
02048                 else // (current>elements2[mid])
02049                         left = mid;
02050 
02051         }
02052 
02053         if (found)
02054         {
02055                 hit_pos = mid;
02056                 return true;
02057         }
02058 
02059         numeric diff = distance(intervals[left].cmin,ilc_x.g);
02060         if (diff<=Group::epsilon)
02061         {
02062                 hit_pos = left;
02063                 return true;
02064         }
02065 
02066         diff = distance(intervals[right].cmin,ilc_x.g);
02067         if (diff<=Group::epsilon)
02068         {
02069                 hit_pos = right;
02070                 return true;
02071         }
02072 
02073         return false;
02074 
02075 }
02076 
02077 template<class Group, class numeric, int Dim, class numeric_writer>
02078 // /////////////////////////////////////////////////////////////////////////////////////
02079 inline void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::intersect(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& set2)
02080 // /////////////////////////////////////////////////////////////////////////////////////
02081 {
02082         intersect(set2, 0);
02083 }
02084 
02085 template<class Group, class numeric, int Dim, class numeric_writer>
02086 // /////////////////////////////////////////////////////////////////////////////////////
02087 IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::~IntervalIntersectionGList()
02088 // /////////////////////////////////////////////////////////////////////////////////////
02089 {
02090     if (insertion_buffer != NULL)
02091     {
02092         delete[] insertion_buffer;
02093         insertion_buffer = NULL;
02094     }
02095 
02096         if (ranking!=NULL)
02097                 delete[] ranking;
02098 
02099         if (m_elements!=NULL)
02100                 delete[] m_elements;
02101 
02102         m_elements = NULL;
02103 
02104     // dynEkdTrees löschen...
02105     treeSaver<tpTREE>* current_tree = treeList.getFirst();
02106 
02107     while (current_tree != NULL)
02108     {
02109         delete current_tree->getTree();
02110         current_tree = treeList.getNext();
02111     }
02112 
02113 }
02114 
02115 template<class Group, class numeric, int Dim, class numeric_writer>
02116 // /////////////////////////////////////////////////////////////////////////////////////
02117 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::printElements()
02118 // /////////////////////////////////////////////////////////////////////////////////////
02119 {
02120 
02121         int i,j;
02122 
02123         if (treeList.numberOfNodes()==0)
02124                 readIntervals();
02125 
02126         iterator iterate = begin();
02127         iterator stop    = end();
02128         while(iterate!=stop)
02129         {
02130         std::cout<<(*iterate).i<<", "<<((*iterate).g)<<std::endl;
02131                 iterate++;
02132         }
02133 }
02134 
02135 template<class Group, class numeric, int Dim, class numeric_writer>
02136 // /////////////////////////////////////////////////////////////////////////////////////
02137 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::pure_printElements()
02138 // /////////////////////////////////////////////////////////////////////////////////////
02139 {
02140 
02141         int i,j;
02142 
02143         if (treeList.numberOfNodes()==0)
02144                 readIntervals();
02145 
02146         pure_iterator iterate = pure_begin();
02147         pure_iterator stop    = pure_end();
02148         while(iterate!=stop)
02149         {
02150         std::cout<<(*iterate).i<<", "<<((*iterate).g)<<std::endl;
02151                 iterate++;
02152         }
02153 }
02154 
02155 /*
02156 template<class Group, class numeric, int Dim, class numeric_writer>
02157 // /////////////////////////////////////////////////////////////////////////////////////
02158 int IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::rangeSearch(tpTREE* search_tree, Interval<Group, numeric, Dim >** result)
02159 // /////////////////////////////////////////////////////////////////////////////////////
02160 {
02161         int count;
02162         numeric low[Dim];
02163         numeric high[Dim];
02164 
02165         // untere und obere Grenze für Umgebungsanfrage bestimmen
02166         numeric local_epsilon = search_tree->epsilon;
02167 
02168         if (local_epsilon>Group::max_epsilon)
02169                 local_epsilon = Group::max_epsilon;
02170         
02171         for (int k=0; k<Dim; k++)
02172         {
02173                 numeric g_k = g_1[k];
02174                 low[k] = g_k - local_epsilon / 2 ;//epsilon;
02175                 high[k] = g_k + local_epsilon / 2 ;//epsilon;
02176         }
02177         
02178         return search_tree->search(low,high,result,1,count);
02179 
02180 }
02181 */
02182 
02183 // Version mit "simuliertem" Merge
02184 template<class Group, class numeric, int Dim, class numeric_writer>
02185 // /////////////////////////////////////////////////////////////////////////////////////
02186 int IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::rangeSearch(Group& g_1, tpTREE* search_tree, int fileNum, Interval<Group, numeric, Dim >** result)
02187 // /////////////////////////////////////////////////////////////////////////////////////
02188 {
02189         int count, count2;
02190         numeric low[Dim];
02191         numeric high[Dim];
02192         numeric dist_min, dist_min2, dist_max, dist_max2;
02193 
02194         Interval<Group, numeric, Dim > ** result2 = new Interval<Group, numeric, Dim > *[1];
02195 
02196 #ifndef USE_GROUP_DISTANCE
02197         // untere und obere Grenze für Umgebungsanfrage bestimmen
02198         numeric local_epsilon = search_tree->epsilon;
02199 
02200         if (local_epsilon>Group::max_epsilon)
02201                 local_epsilon = Group::max_epsilon;
02202 #else
02203         numeric local_epsilon = Group::max_epsilon;
02204 #endif
02205         
02206         for (int k=0; k<Dim; k++)
02207         {
02208                 numeric g_k = g_1[k];
02209                 low[k] = g_k - local_epsilon / 2;//epsilon;
02210                 high[k] = g_k + local_epsilon / 2;//epsilon;
02211         }
02212         
02213         search_tree->search(low,high,result,1,count);
02214 
02215         std::list<IntervalIntersectionGList*>::iterator start = m_merged_with.begin();
02216         std::list<IntervalIntersectionGList*>::iterator stop  = m_merged_with.end();
02217 
02218         treeSaver<tpTREE>* treelook;
02219 
02220         while (start!=stop)
02221         {
02222                 treelook=(*start)->treeList.findData(treeSaver<tpTREE>(NULL, fileNum));
02223 
02224                 if (treelook)
02225                 {
02226                         treelook->getTree()->search(low, high, result2, 1, count2);
02227                         if (count==0)
02228                         {
02229                                 result[0] = result2[0];
02230                                 count     = count2;
02231                         }
02232                         else
02233                                 if (count2>0)
02234                                 { 
02235                                         dist_min  = distance(result[0]->cmin,g_1);
02236                                         dist_max  = distance(result[0]->cmax,g_1);
02237                                         dist_min2 = distance(result2[0]->cmin,g_1);
02238                                         dist_max2 = distance(result2[0]->cmax,g_1);
02239 
02240                                         if (dist_min2 < dist_min && dist_max2 < dist_max)
02241                                                 result[0] = result2[0];
02242                                 }
02243                 }
02244 
02245                 start++;
02246         }
02247 
02248         delete result2;
02249 
02250         return count;
02251 }
02252 
02253 template<class Group, class numeric, int Dim, class numeric_writer>
02254 // /////////////////////////////////////////////////////////////////////////////////////
02255 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::setCredit(int credit)
02256 // /////////////////////////////////////////////////////////////////////////////////////
02257 {
02258     m_credit = credit;
02259 }
02260 
02261 template<class Group, class numeric, int Dim, class numeric_writer>
02262 // /////////////////////////////////////////////////////////////////////////////////////
02263 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::intersect(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >& glist2, int credit)
02264 // /////////////////////////////////////////////////////////////////////////////////////
02265 {
02266         m_credit = credit;
02267 
02268         if (intervals==NULL)
02269                 readIntervals();
02270 
02271         //DEBUG
02272         glist2.readIntervals();
02273         glist2.m_credit = credit;
02274 
02275         // Liste leer ?
02276         if (glist2.size()<=0)
02277         {
02278                 intersects++;
02279                 return;
02280         }
02281 
02282         intervals_matched = 0;
02283 
02284         // Durchlaufe alle ekdTrees in glist2
02285 
02286         iterator iterate(glist2.begin());
02287         iterator stop   (glist2.end());
02288 
02289         std::list<std::pair<Interval<Group, numeric, Dim>,int> > ins_list;
02290 
02291         while(iterate!=stop)
02292         {
02293                 Group g_1 = (*iterate).g;
02294                 g_1 *= m_factor_inverse;
02295 
02296                 // zunächst Suchbereich auf gültige Werte von i einschränken
02297                 treeSaver<tpTREE> *treepos = treeList.findData(treeSaver<tpTREE>(NULL, iterate.getCurrentFile()));                              
02298 
02299                 if (treepos)
02300                 {
02301                         // EPSILON-BEREICHSSUCHE im verbleibenden ekd-Baum.
02302                         // Relevant für das Suchergebnis ist ausschließlich 
02303                         // das Gruppenelement, da die Dateinummern innerhalb
02304                         // des Baumes sicher übereinstimmen.
02305 
02306                         Interval<Group, numeric, Dim > ** result = new Interval<Group, numeric, Dim > *[1];
02307 
02308             // int found = rangeSearch(treepos->getTree(), result);
02309                         // Das Vereinigen von Listen wird simuliert:
02310                         int found = rangeSearch(g_1, treepos->getTree(), iterate.getCurrentFile(), result);
02311 
02312                         Interval<Group, numeric, Dim >* current_interval = result[0];
02313 
02314                         // Mismatches beachten!
02315                         if (found>0)
02316                         {
02317                                 numeric dist_min = distance(current_interval->cmin,g_1);
02318                                 numeric dist_max = distance(current_interval->cmax,g_1);
02319                         #ifndef USE_GROUP_DISTANCE
02320                                 numeric local_epsilon = treepos->getTree()->epsilon;
02321                         #else
02322                                 numeric local_epsilon = Group::max_epsilon;
02323                         #endif
02324 
02325 
02326                         #ifndef USE_GROUP_DISTANCE
02327                                 Interval<Group, numeric, Dim >* old_interval = current_interval;
02328                         #endif
02329                                 if (dist_min <= local_epsilon && dist_max <= local_epsilon)
02330                                 {
02331                                         current_interval->matched++;
02332                                         current_interval->expand(g_1);
02333                                         intervals_matched++;
02334                                 }
02335 
02336                         #ifndef USE_GROUP_DISTANCE
02337                                 // Falls epsilon > Minimaldistanz:
02338                                 for (int i_found = 1; i_found<found; i_found++)
02339                                 {
02340                                         Interval<Group, numeric, Dim > i_new;
02341                                         i_new = *old_interval;
02342                                         old_interval->expand(g_1);
02343                                         ins_list.push_back(std::pair<Interval<Group, numeric, Dim>, int>(i_new, iterate.getCurrentFile()));
02344                                 }
02345                         #endif
02346 
02347                         } else {
02348                                 // Einfügen von (g_1) in treeList[pos]
02349                                 treepos->getTree()->insert(*(new Interval<Group, numeric, Dim>(g_1, 0)));
02350 
02351                         }
02352                         delete[] result;
02353                 } 
02354                 else 
02355                 {
02356                         // Neuen Baum anlegen für Dateinummer set2FileIndex 
02357                         // und Interval(g_1) in diesen Baum mit entsprechender Anzahl mismatches
02358                         // einfügen.
02359                         treeList.insert(treeSaver<tpTREE>
02360                                 (new tpTREE(new Interval<Group, numeric, Dim>(g_1, 0), 1), iterate.getCurrentFile()));
02361                 }
02362 
02363                 iterate++;
02364         }
02365 
02366 #ifndef USE_GROUP_DISTANCE
02367         std::list<std::pair<Interval<Group, numeric, Dim >, int> >::iterator ins_it = ins_list.begin();
02368         std::list<std::pair<Interval<Group, numeric, Dim >, int> >::iterator ins_end = ins_list.end();
02369         for (; ins_it != ins_end; ins_it++)
02370         {
02371                 treeSaver<tpTREE> *treepos = treeList.findData(treeSaver<tpTREE>(NULL, (*ins_it).second));                              
02372                 treepos->getTree()->insert(*(new Interval<Group, numeric, Dim>(((*ins_it).first).g, 0)));
02373         }
02374 #endif
02375         intersects++;
02376         
02377 }
02378 
02379 template<class Group, class numeric, int Dim, class numeric_writer>
02380 // /////////////////////////////////////////////////////////////////////////////////////
02381 void IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::merge(IntervalIntersectionGList<Group, numeric, Dim, numeric_writer>& set2)
02382 // /////////////////////////////////////////////////////////////////////////////////////
02383 {
02384         m_merged_with.insert(m_merged_with.begin(), &set2);
02385 }
02386 
02387 /*
02388 template<class Group>
02389 ostream& operator<<(ostream& o, GInvertedList<Group> g)
02390 {
02391         IntervalIntersectionGList<Group> em = *((IntervalIntersectionGList<Group>*)((void*)&g));
02392         if (!em.readElements())
02393                 return o;
02394         for (int i=0; i<em.size(); i++)
02395         {
02396                 o<<em.elements[i].i<<" - "<<em.elements[i].g<<endl;
02397         }
02398         o<<endl;
02399         return o;
02400 }
02401 
02402 */
02403 
02404 
02405 
02406 /*
02407 template<class Group, class numeric, int Dim, class numeric_writer>
02408 // /////////////////////////////////////////////////////////////////////////////////////
02409 inline Interval<Group, numeric, Dim, numeric_writer>& IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator::operator *() const
02410 // /////////////////////////////////////////////////////////////////////////////////////
02411 {
02412         return *m_iterator;
02413 }
02414 */
02415 
02416 /*template<class Group, class numeric, int Dim, class numeric_writer>
02417 // /////////////////////////////////////////////////////////////////////////////////////
02418 inline bool IntervalIntersectionGList<Group, numeric, Dim, numeric_writer >::iterator::operator !=(iterator& compare)
02419 // /////////////////////////////////////////////////////////////////////////////////////
02420 {
02421         return !(*this==compare);
02422 }*/
02423 
02424 
02425 }
02426 
02427 #endif // DEF_INTERVALINTERSECTIONGLIST
02428 
The GroupIndex-Template-Library
Universität Bonn, Institut für Informatik III, 2001