00001 #ifndef DEF_GINVERTEDLIST
00002 #define DEF_GINVERTEDLIST
00003
00004 #pragma warning( disable : 4786 )
00005
00006 #ifndef maxStabSize
00007 #define maxStabSize 6
00008 #endif
00009
00010 #include "ListTupel.h"
00011 #include "default_containers.h"
00012 #include "consts.h"
00013 #include "heap.h"
00014 #ifndef DEF_LIMITS
00015 #include <climits>
00016 #define DEF_LIMITS
00017 #endif
00018 #ifndef VISUALC_INCLUDES
00019 #include <unistd.h>
00020 #include <sys/stat.h>
00021 #include <mingw/stdlib.h>
00022 #endif
00023 const unsigned short power2[] = { 128, 64, 32, 16, 8, 4, 2, 1 } ;
00024 #include <cstdio>
00025 #include <cstdlib>
00026 #include <io.h>
00027
00028
00029 namespace groupindex
00030 {
00031
00032
00033 template <class Group>
00034 std::ofstream& operator<<(std::ofstream& ofs, ListTupel<Group>& lt)
00035 {
00036 ofs<<lt.g;
00037 ofs.write((char*)&(lt.i),sizeof(int));
00038 return ofs;
00039
00040 }
00041
00042 template <class Group>
00043 std::ifstream& operator>>(std::ifstream& ifs, ListTupel<Group>& lt)
00044 {
00045 ifs>>lt.g;
00046 ifs.read((char*)&(lt.i),sizeof(int));
00047 return ifs;
00048
00049 }
00050
00058 template<class Group>
00059 class GInvertedList
00060 {
00061
00062 protected:
00063 class read_iterator;
00064
00065 public:
00066
00071 class iterator;
00072
00081
00082
00083 protected:
00084
00085 ListTupel<Group>* insertion_buffer;
00086 int ins_buffer_size;
00087 int ins_buffer_pos;
00090
00091
00092 std::fstream* m_stream;
00093
00094
00096 long m_fileoffset;
00097
00099 long m_id;
00100
00102 char m_insertion_file_name[1024];
00103
00105 Group m_factor_inverse;
00106
00108 Group m_factor;
00109
00111 ListTupel<Group>* m_pos_beg;
00112
00114 ListTupel<Group>* m_pos_end;
00115
00117 int m_element_count;
00118
00121 int m_new_element_count;
00122
00124 ListTupel<Group>* m_elements;
00125
00128 std::set<int> m_deleted_fileindices;
00129
00130 void initFileRead(std::ifstream& ifs);
00131 void initFileRead(std::fstream& ifs);
00132
00134 virtual void readElements();
00135
00137 virtual void readElements(int credit);
00138
00140 virtual void readElements(ListTupel<Group>* buffer, int credit);
00141
00143 void clear();
00144
00146 inline void setFileName(long id);
00147
00164 virtual void writeToFile(std::ofstream& ofs);
00165
00167 inline read_iterator find(const ListTupel<Group>& lt);
00168
00169 inline read_iterator find(const ListTupel<Group>& lt, read_iterator& it);
00170
00171 inline void remove(read_iterator& it);
00172
00173
00174 inline void decrease(read_iterator& it);
00175
00181 inline void assign(const read_iterator& new_beg, const read_iterator& new_end);
00182
00194 void initInsertion();
00195
00200 void insert(read_iterator& pos, const ListTupel<Group>& lt);
00201
00202 void initUpdate();
00203
00204 public:
00205
00207 GInvertedList<Group>(const GInvertedList<Group>& glist);
00208
00212 GInvertedList<Group>(long id);
00213
00215 GInvertedList<Group>();
00216
00225 GInvertedList(std::fstream& ifs);
00226
00231 inline GInvertedList<Group>& operator*=(const Group& g);
00232
00234 inline iterator begin();
00235 inline iterator begin(bool dummy);
00236
00238 inline iterator end();
00239 inline iterator end(bool dummy);
00240
00241 protected:
00242 inline read_iterator _begin(void*);
00243
00244 inline read_iterator _end(void*);
00245
00246 public:
00248 inline int size() const;
00249
00250 void setCredit(int credit)
00251 {
00252 }
00253
00255 friend std::ofstream& operator<< ANSI_BRACES (std::ofstream& o, GInvertedList<Group>& l);
00256
00270 virtual void insert(const Group& g, int i);
00271
00273 void remove(int fileindex);
00274
00284 void intersect(GInvertedList<Group>& set2, int& mismatches);
00285
00286 void merge(GInvertedList<Group>& set2);
00287
00289 inline void setHeapStream(std::fstream& hps)
00290 {
00291 }
00292
00294 ~GInvertedList();
00295
00296 protected:
00297
00303 class read_iterator
00304 {
00305
00306 protected:
00307
00308 ListTupel<Group>* lt;
00309
00310 public:
00311
00312
00313 inline read_iterator() {}
00314
00315
00316
00317 inline read_iterator(ListTupel<Group>* l)
00318
00319 {
00320 lt = l;
00321 }
00322
00323
00324 inline ListTupel<Group>& operator*() const
00325
00326 {
00327 return *lt;
00328 }
00329
00331
00332 inline read_iterator& operator++()
00333
00334 {
00335
00336 do
00337 {
00338 lt = <[1];
00339 } while (lt->credit<0);
00340
00341 return *this;
00342 }
00343
00345
00346 inline read_iterator& operator++(int)
00347
00348 {
00349
00350 do
00351 {
00352 lt = <[1];
00353 } while (lt->credit<0);
00354
00355 return *this;
00356 }
00357
00358
00359 inline bool operator!=(const read_iterator& it)
00360
00361 {
00362 return !(lt == it.lt);
00363 }
00364
00365
00366 inline bool operator==(const read_iterator& it)
00367
00368 {
00369 return (lt == it.lt);
00370 }
00371
00372 };
00373
00374
00375 public:
00376
00377
00378
00384 class iterator : public read_iterator
00385 {
00386
00387 protected:
00388 Group* m_factor;
00389
00390 public:
00391
00392 inline iterator() {}
00393
00394 inline iterator(const read_iterator& it) : read_iterator(it) {}
00395
00396 inline iterator(const iterator& it) : read_iterator((read_iterator)it)
00397 {
00398 m_factor = it.m_factor;
00399 }
00400
00401
00402 inline iterator(ListTupel<Group>* l, Group* g)
00403
00404 {
00405 lt = l;
00406 while (lt->credit<0)
00407 lt = <[1];
00408 m_factor = g;
00409 }
00410
00411
00412 inline ListTupel<Group> operator*()
00413
00414 {
00415
00416 ListTupel<Group> r_lt;
00417
00418
00419
00420 r_lt.g = (*lt).g;
00421 r_lt.g *= (*m_factor);
00422 r_lt.credit = (*lt).credit;
00423
00424 r_lt.i = (*lt).i;
00425 return r_lt;
00426 }
00427
00428 };
00429
00430 };
00431
00432
00433
00434
00448 template<class Group>
00449
00450 void GInvertedList<Group>::writeToFile(std::ofstream& ofs)
00451
00452 {
00453
00454
00455 if (insertion_buffer != NULL)
00456 {
00457
00458 if (chdir("list")==-1)
00459 #ifdef VISUALC_INCLUDES
00460 mkdir("list");
00461 #else
00462 mkdir("list",0);
00463 #endif
00464 else
00465 chdir("..");
00466
00467 std::fstream insertion_stream;
00468 insertion_stream.open(m_insertion_file_name, std::ios::app | std::ios::out | std::ios::binary);
00469 if (!insertion_stream)
00470 {
00471 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
00472 return;
00473 }
00474
00475 for (int j=0; j<ins_buffer_pos; j++)
00476 insertion_stream<<insertion_buffer[j];
00477 ins_buffer_pos = 0;
00478
00479 insertion_stream.close();
00480
00481 }
00482
00483
00484 readElements();
00485
00486 ListTupel<Group>* new_elements = NULL;
00487 if (m_new_element_count>0)
00488 {
00489 std::ifstream insertion_stream;
00490 insertion_stream.open(m_insertion_file_name,std::ios::binary);
00491
00492 if (insertion_stream == NULL || !insertion_stream)
00493 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
00494
00495 new_elements = new ListTupel<Group>[m_new_element_count+1];
00496
00497 new_elements[m_new_element_count].credit = 0;
00498
00499
00500 for (int i=0; i<m_new_element_count; i++)
00501 {
00502 insertion_stream>>new_elements[i];
00503 if (!insertion_stream)
00504 throw IndexingException(IndexingException::FILE_ERROR_READ);
00505 }
00506
00507 insertion_stream.close();
00508
00509
00510 heapsort< ListTupel<Group> >(new_elements,m_new_element_count);
00511
00512 }
00513
00514 ListTupel<Group>* all_elements = new ListTupel<Group>[m_element_count+m_new_element_count];
00515 long bytesize = 0;
00516
00517
00518 int i_old = 0;
00519 int i_new = 0;
00520 int i_all = 0;
00521
00522 while (i_old<m_element_count || i_new<m_new_element_count)
00523 {
00524
00525 if (i_new>=m_new_element_count || i_old<m_element_count && m_elements[i_old]>new_elements[i_new])
00526 {
00527
00528 std::set<int>::iterator found = m_deleted_fileindices.find(m_elements[i_old].i);
00529 if (found==m_deleted_fileindices.end())
00530 {
00531 all_elements[i_all] = m_elements[i_old];
00532 bytesize += m_elements[i_old].size();
00533 i_all++;
00534 }
00535
00536 do {
00537 i_old++;
00538 } while (i_old<m_element_count && m_elements[i_old]==m_elements[i_old-1]);
00539
00540 } else {
00541
00542 while (i_old<m_element_count && m_elements[i_old]==new_elements[i_new])
00543 {
00544
00545 i_old++;
00546 }
00547
00548 std::set<int>::iterator found = m_deleted_fileindices.find(new_elements[i_new].i);
00549 if (found==m_deleted_fileindices.end())
00550 {
00551 all_elements[i_all] = new_elements[i_new];
00552 bytesize += new_elements[i_new].size();
00553 i_all++;
00554 }
00555
00556 do {
00557 i_new++;
00558 } while (i_new<m_new_element_count && new_elements[i_new]==new_elements[i_new-1]);
00559
00560 }
00561
00562 }
00563
00564 int all_element_count = i_all;
00565
00566
00567
00568 ofs.write((char*)&m_id,sizeof(long));
00569 ofs.write((char*)&all_element_count,sizeof(long));
00570 ofs.write((char*)&bytesize,sizeof(long));
00571
00572 m_fileoffset = ofs.tellp();
00573
00574
00575 for (i_all = 0; i_all<all_element_count; i_all++)
00576 {
00577
00578 ofs<<all_elements[i_all];
00579
00580 };
00581
00582 m_element_count = all_element_count;
00583 m_new_element_count = 0;
00584
00585
00586 delete[] m_elements;
00587 delete[] new_elements;
00588 delete[] all_elements;
00589 m_elements = NULL;
00590
00591
00592
00593 ::remove(m_insertion_file_name);
00594
00595 m_deleted_fileindices.clear();
00596
00597 }
00598
00600 template<class Group>
00601
00602 GInvertedList<Group>::GInvertedList<Group>(const GInvertedList<Group>& glist)
00603
00604 {
00605 ins_buffer_size = glist.ins_buffer_size;
00606 ins_buffer_pos = glist.ins_buffer_pos;
00607 if (glist.insertion_buffer!=NULL)
00608 {
00609 insertion_buffer = new ListTupel<Group>[ins_buffer_size];
00610 for (int i=0; i<ins_buffer_pos; i++)
00611 insertion_buffer[i] = glist.insertion_buffer[i];
00612 }
00613 else
00614 insertion_buffer = NULL;
00615
00616 m_stream = glist.m_stream;
00617 strcpy(m_insertion_file_name,glist.m_insertion_file_name);
00618 m_fileoffset = glist.m_fileoffset;
00619 m_factor = glist.m_factor;
00620 m_factor_inverse = glist.m_factor_inverse;
00621
00622 m_elements = NULL;
00623 m_element_count = glist.m_element_count;
00624 m_new_element_count = glist.m_new_element_count;
00625
00626 m_pos_beg = NULL;
00627 m_pos_end = NULL;
00628
00629 m_id = glist.m_id;
00630
00631 }
00632
00634 template<class Group>
00635
00636 GInvertedList<Group>::GInvertedList<Group>()
00637
00638 {
00639 m_elements = NULL;
00640 m_stream = NULL;
00641
00642 m_insertion_file_name[0] = '\0';
00643 m_element_count = 0;
00644 m_new_element_count = 0;
00645
00646 m_pos_beg = NULL;
00647 m_pos_end = NULL;
00648
00649 ins_buffer_size = INS_BUFFER_SIZE;
00650 ins_buffer_pos = 0;
00651 insertion_buffer=NULL;
00652
00653 m_id = -1;
00654 };
00655
00657 template<class Group>
00658
00659 GInvertedList<Group>::GInvertedList<Group>(long id)
00660
00661 {
00662 m_elements = NULL;
00663 m_element_count = 0;
00664 m_new_element_count = 0;
00665
00666 m_pos_beg = NULL;
00667 m_pos_end = NULL;
00668
00669 m_id = id;
00670
00671 ins_buffer_size = INS_BUFFER_SIZE;
00672 ins_buffer_pos = 0;
00673 insertion_buffer=NULL;
00674
00675 initInsertion();
00676
00677 };
00678
00679 template<class Group>
00680
00681 inline GInvertedList<Group>& GInvertedList<Group>::operator*=(const Group& g)
00682
00683 {
00684 m_factor = g;
00685 m_factor_inverse = g;
00686 !m_factor_inverse;
00687 return *this;
00688 };
00689
00690 template<class Group>
00691
00692 inline GInvertedList<Group>::iterator GInvertedList<Group>::begin()
00693
00694 {
00695
00696 if (m_elements==NULL)
00697 readElements();
00698
00699 return iterator(m_pos_beg, &m_factor);
00700 };
00701
00702 template<class Group>
00703
00704 inline GInvertedList<Group>::iterator GInvertedList<Group>::begin(bool dummy)
00705
00706 {
00707 return begin();
00708 }
00709
00710 template<class Group>
00711
00712 inline GInvertedList<Group>::iterator GInvertedList<Group>::end()
00713
00714 {
00715 return iterator(m_pos_end);
00716 };
00717
00718 template<class Group>
00719
00720 inline GInvertedList<Group>::iterator GInvertedList<Group>::end(bool dummy)
00721
00722 {
00723 return end();
00724 }
00725
00726 template<class Group>
00727
00728 inline GInvertedList<Group>::read_iterator GInvertedList<Group>::_begin(void*)
00729
00730 {
00731 return read_iterator(m_pos_beg);
00732 };
00733
00734 template<class Group>
00735
00736 inline GInvertedList<Group>::read_iterator GInvertedList<Group>::_end(void*)
00737
00738 {
00739 return read_iterator(m_pos_end);
00740 };
00741
00742
00746 template<class Group>
00747
00748 inline int GInvertedList<Group>::size() const
00749
00750 {
00751 return m_element_count;
00752 };
00753
00767 template<class Group>
00768
00769 void GInvertedList<Group>::insert(const Group& g, int i)
00770
00771 {
00772
00773
00774
00775
00776 m_new_element_count++;
00777
00778 if (insertion_buffer == NULL)
00779 insertion_buffer = new ListTupel<Group>[ins_buffer_size];
00780
00781 ListTupel<Group> lt(g,i);
00782 if (ins_buffer_pos < ins_buffer_size)
00783 {
00784 insertion_buffer[ins_buffer_pos++] = lt;
00785 return;
00786 }
00787
00788 if (chdir("list")==-1)
00789 #ifdef VISUALC_INCLUDES
00790 mkdir("list");
00791 #else
00792 mkdir("list",0);
00793 #endif
00794 else
00795 chdir("..");
00796
00797 std::fstream insertion_stream;
00798 insertion_stream.open(m_insertion_file_name, std::ios::app | std::ios::out | std::ios::binary);
00799 if (!insertion_stream)
00800 {
00801 throw IndexingException(IndexingException::FILE_ERROR_OPEN);
00802 return;
00803 }
00804
00805 for (int j=0; j<ins_buffer_size; j++)
00806 insertion_stream<<insertion_buffer[j];
00807 insertion_stream<<lt;
00808 ins_buffer_pos = 0;
00809
00810 insertion_stream.close();
00811
00812 };
00813
00825 template<class Group>
00826
00827 void GInvertedList<Group>::initInsertion()
00828
00829 {
00830 setFileName(m_id);
00831 };
00832
00833
00834 template<class Group>
00835
00836 inline void GInvertedList<Group>::setFileName(long id)
00837
00838 {
00839
00840 char sNum[28];
00841 my_itoa(id, sNum, 16);
00842 strcpy(m_insertion_file_name,"list/glist_");
00843 strcat(m_insertion_file_name,sNum);
00844
00845 m_stream = NULL;
00846
00847 }
00848
00849
00850 template<class Group>
00851
00852 void GInvertedList<Group>::initFileRead(std::ifstream& ifs)
00853
00854 {
00855
00856 long bytesize;
00857
00858
00859 ifs.read((char*)&m_id, sizeof(long));
00860
00861
00862 ifs.read((char*)&m_element_count, sizeof(long));
00863
00864 m_new_element_count = 0;
00865
00866
00867 ifs.read((char*)&bytesize, sizeof(long));
00868 if (!ifs)
00869 throw IndexingException(IndexingException::FILE_ERROR_READ);
00870
00871
00872 initInsertion();
00873
00874 m_stream = &ifs;
00875
00876 m_fileoffset = ifs.tellg();
00877
00878
00879
00880 ifs.seekg(bytesize, std::ios::cur);
00881 if (!ifs)
00882 throw IndexingException(IndexingException::FILE_ERROR_READ);
00883
00884 }
00885
00886 template<class Group>
00887
00888 void GInvertedList<Group>::initFileRead(std::fstream& ifs)
00889
00890 {
00891
00892 long bytesize;
00893
00894
00895 ifs.read((char*)&m_id, sizeof(long));
00896
00897
00898 ifs.read((char*)&m_element_count, sizeof(long));
00899
00900 m_new_element_count = 0;
00901
00902
00903 ifs.read((char*)&bytesize, sizeof(long));
00904 if (!ifs)
00905 throw IndexingException(IndexingException::FILE_ERROR_READ);
00906
00907
00908 initInsertion();
00909
00910 m_stream = &ifs;
00911
00912 m_fileoffset = ifs.tellg();
00913
00914
00915
00916 ifs.seekg(bytesize, std::ios::cur);
00917 if (!ifs)
00918 throw IndexingException(IndexingException::FILE_ERROR_READ);
00919
00920 }
00921
00929 template<class Group>
00930
00931 GInvertedList<Group>::GInvertedList<Group>(std::fstream& ifs)
00932
00933 {
00934
00935 ins_buffer_size = INS_BUFFER_SIZE;
00936 ins_buffer_pos = 0;
00937 insertion_buffer=NULL;
00938
00939 m_elements = NULL;
00940 m_pos_beg = NULL;
00941 m_pos_end = NULL;
00942
00943 initFileRead(ifs);
00944
00945 }
00946
00948 template<class Group>
00949
00950 void GInvertedList<Group>::readElements()
00951
00952 {
00953 if (m_elements!=NULL || m_stream==NULL)
00954
00955 return;
00956
00957 m_elements = new ListTupel<Group>[m_element_count+1];
00958
00959
00960 m_elements[m_element_count].credit = 0;
00961 readElements(m_elements, 0);
00962 m_pos_beg = &(m_elements[0]);
00963 m_pos_end = &(m_elements[m_element_count]);
00964 };
00965
00967 template<class Group>
00968
00969 void GInvertedList<Group>::readElements(int credit)
00970
00971 {
00972 if (m_elements!=NULL || m_stream==NULL)
00973
00974 return;
00975
00976 m_elements = new ListTupel<Group>[m_element_count+2];
00977
00978
00979
00980 m_elements[m_element_count].credit = 0;
00981 readElements(m_elements, credit);
00982 m_pos_beg = &(m_elements[0]);
00983 m_pos_end = &(m_elements[m_element_count]);
00984 };
00985
00992 template<class Group>
00993
00994 void GInvertedList<Group>::readElements(ListTupel<Group>* buffer, int credit)
00995
00996 {
00997 if (m_stream==NULL)
00998 return;
00999
01000
01001 (*m_stream).seekg(m_fileoffset, std::ios::beg);
01002 int i;
01003 for (i=0; i<m_element_count; i++)
01004 {
01005 (*m_stream)>>(ListTupel<Group>&)buffer[i];
01006 buffer[i].credit = 0;
01007
01008
01009
01010
01011
01012
01013 }
01014
01015 if (!(*m_stream))
01016 {
01017 throw IndexingException(IndexingException::FILE_ERROR_READ);
01018 }
01019
01020 for (i=0; i<m_element_count; buffer[i++].credit = credit);
01021
01022
01023 };
01024
01026 template<class Group>
01027
01028 void GInvertedList<Group>::clear()
01029
01030 {
01031 delete[] m_elements;
01032 m_elements = NULL;
01033 }
01034
01036 template<class Group>
01037
01038 void GInvertedList<Group>::remove(int fileindex)
01039
01040 {
01041
01042
01043
01044
01045
01046
01047 m_deleted_fileindices.insert(fileindex);
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098 }
01099
01100
01101 template<class Group>
01102
01103 GInvertedList<Group>::read_iterator GInvertedList<Group>::find(const ListTupel<Group>& lt)
01104
01105 {
01106 read_iterator found = end();
01107 int left = 0;
01108 int right = size();
01109 int mid = 0;
01110
01111 ListTupel<Group> l1 = lt;
01112 l1.g *= m_factor_inverse;
01113
01114 while (left<=right && found==end())
01115 {
01116 mid = (left+right)/2;
01117
01118 ListTupel<Group>* cmp = &m_elements[mid];
01119 if (l1.i==(*cmp).i && !(l1.g!=(*cmp).g))
01120 found = read_iterator(cmp);
01121 else if (l1<*cmp)
01122 left = mid+1;
01123 else
01124 right = mid-1;
01125 }
01126
01127 return found;
01128 };
01129
01130
01131 template<class Group>
01132
01133 GInvertedList<Group>::read_iterator GInvertedList<Group>::find(const ListTupel<Group>& lt, read_iterator& it)
01134
01135 {
01136 return find(lt);
01137 };
01138
01144 template<class Group>
01145
01146 inline void GInvertedList<Group>::assign(const read_iterator& new_beg, const read_iterator& new_end)
01147
01148 {
01149 m_pos_beg = &*new_beg;
01150 m_pos_end = &(*new_end);
01151 (*new_end).credit = 0;
01152 };
01153
01154 template<class Group>
01155
01156 inline void GInvertedList<Group>::remove(read_iterator& it)
01157
01158 {
01159 (*it).credit = -1;
01160 }
01161
01162 template<class Group>
01163
01164 inline void GInvertedList<Group>::decrease(read_iterator& it)
01165
01166 {
01167 if ((--((*it).credit))==-1)
01168 m_element_count--;
01169 }
01170
01180 template<class Group>
01181
01182 void GInvertedList<Group>::intersect(GInvertedList<Group>& glist2, int& mismatches)
01183
01184 {
01185
01186 if (m_elements==NULL)
01187 readElements(mismatches);
01188
01189 glist2.readElements(mismatches>0 ? mismatches-1 : 0);
01190
01191
01192
01193
01194 read_iterator it = _begin(NULL);
01195
01196
01197 read_iterator ins = _begin(NULL);
01198 read_iterator last = _end(NULL);
01199
01200 for (; it != last; it++)
01201 {
01202
01203 ListTupel<Group> l1 = *it;
01204 l1.g *= m_factor;
01205
01206 read_iterator found = glist2.find(l1);
01207
01208 if (found!=glist2.end())
01209 {
01210 glist2.remove(found);
01211 *ins = *it;
01212 ins++;
01213 } else {
01214
01215 decrease(it);
01216 if ((*it).credit>=0)
01217 {
01218 *ins = *it;
01219 ins++;
01220 }
01221 }
01222
01223 }
01224
01225
01226
01227
01228 assign(_begin(NULL), ins);
01229
01230 if (mismatches>0)
01231 {
01232 merge(glist2);
01233 mismatches--;
01234 }
01235
01236 glist2.clear();
01237
01238 };
01239
01240 template<class Group>
01241 bool operator>(const GInvertedList<Group>& l1, const GInvertedList<Group>& l2)
01242 {
01243 return l1.size() > l2.size();
01244 }
01245
01246 template<class Group>
01247
01248 void GInvertedList<Group>::merge(GInvertedList<Group>& glist2)
01249
01250 {
01251
01252 glist2.readElements();
01253 readElements();
01254
01255 m_element_count = size()+glist2.size();
01256 ListTupel<Group>* new_elements = new ListTupel<Group>[m_element_count+1];
01257
01258 new_elements[m_element_count].credit = 0;
01259
01260 read_iterator it1 = _begin(NULL);
01261 read_iterator it2 = glist2._begin(NULL);
01262 int ins_pos = 0;
01263
01264 while (it1!=(read_iterator)(end()) || it2!=(read_iterator)(glist2.end()))
01265 {
01266 if (it2==(read_iterator)(glist2.end()) || ( it1!=(read_iterator)(end()) && (*it1)<(*it2) ) )
01267 {
01268 new_elements[ins_pos++] = *it1;
01269 it1++;
01270 } else {
01271 (*it2).g *= (glist2.m_factor);
01272 (*it2).g *= (m_factor_inverse);
01273 new_elements[ins_pos++] = *it2;
01274 it2++;
01275 }
01276 }
01277
01278 delete[] m_elements;
01279 m_elements = new_elements;
01280 assign(read_iterator(&new_elements[0]),read_iterator(&new_elements[m_element_count]));
01281
01282 }
01283
01285 template<class Group>
01286
01287 GInvertedList<Group>::~GInvertedList<Group>()
01288
01289 {
01290 if (m_elements != NULL)
01291 delete[] m_elements;
01292
01293 ::remove(m_insertion_file_name);
01294
01295 m_elements = NULL;
01296
01297 if (insertion_buffer != NULL)
01298 delete[] insertion_buffer;
01299 insertion_buffer = NULL;
01300
01301 };
01302
01303 template<class Group>
01304
01305 std::ofstream& operator<<(std::ofstream& o, GInvertedList<Group>& l)
01306
01307 {
01308 l.writeToFile(o);
01309 return o;
01310 };
01311
01312 template<class Group>
01313
01314 std::ostream& operator<<(std::ostream& o, GInvertedList<Group>& l)
01315
01316 {
01317 o<<l.m_factor<<"*("<<endl;
01318 l.readElements();
01319 GInvertedList<Group>::read_iterator it = l.begin();
01320 GInvertedList<Group>::read_iterator fin = l.end();
01321
01322 for (; it!=fin; it++)
01323 o<<" <"<<(*it).g<<", "<<(*it).i<<", "<<(*it).credit<<">"<<endl;
01324 o<<")"<<endl<<endl;
01325
01326 return o;
01327 };
01328
01329 }
01330
01331 #endif