00001
00013 #include <iostream>
00014 #include <iomanip>
00015 #include <list>
00016 #include <vector>
00017 #include <set>
00018 #include <fstream>
00019 #include <istream>
00020 #include <sstream>
00021
00022 using namespace std;
00023
00024 #include "RamDisco.hpp"
00025
00026
00027
00032 unsigned long
00033 precalcula_escribe_con_hermanos(NodoTrieS *n)
00034 {
00035
00036
00037 int t = 0;
00038 if (n != NULL) {
00039 t = 1;
00040 }
00041
00042 while (n != NULL) {
00043 t += precalcula_escribe_actual(n->cad.length(),
00044 &(n->cpos));
00045
00046 n = n->hermano_mayor;
00047
00048 }
00049
00050 return t;
00051 }
00052
00053 unsigned long
00054 precalcula_escribe(NodoTrieS *n)
00055 {
00056 long t = precalcula_escribe_con_hermanos(n);
00057
00058
00059 while (n != NULL) {
00060 t += precalcula_escribe(n->hijo_menor);
00061
00062 n = n->hermano_mayor;
00063 }
00064
00065 return t;
00066 }
00067
00068
00069 extern stringstream *depuraos ;
00070
00080 void
00081 escribePlanoStream(NodoTrieS *n, std::iostream &os, long desp)
00082 {
00083
00084 NodoTrieS *tn;
00085 long nh = precalcula_escribe_con_hermanos(n);
00086 long dultimo = nh;
00087 long dhijo = 0;
00088
00089
00090 tn = n;
00091 long pactual = 0;
00092
00093 while (tn != NULL && tn->cad.length() > 0) {
00094 if (tn->hijo_menor != NULL) {
00095 dhijo = dultimo - pactual;
00096 dultimo += precalcula_escribe(tn->hijo_menor);
00097 } else {
00098 dhijo = 0;
00099 }
00100
00101 escribeNodo(os, tn->cad, &(tn->cpos), dhijo, desp);
00102
00103 if (depuraos != NULL) {
00104 cout << depuraos->str() << endl;
00105 }
00106 pactual += precalcula_escribe_actual((tn->cad).length(),
00107 &(tn->cpos));
00108 tn = tn->hermano_mayor;
00109 }
00110 os << "\n";
00111
00112 tn = n;
00113 while (tn != NULL) {
00114 if (tn->hijo_menor != NULL) {
00115 escribePlanoStream(tn->hijo_menor, os, desp);
00116 }
00117 tn = tn->hermano_mayor;
00118 }
00119 }
00120
00121
00122
00123 NodoTrieS *
00124 leePlanoStream(std::istream &is) throw(string)
00125 {
00126 string cad;
00127 set<Pos> *cpos;
00128 long hijo, hermano;
00129 int c = is.get();
00130 if (c == '\n' || c == EOF) {
00131 return NULL;
00132 }
00133 while (c != FINCADENA && c != EOF) {
00134 cad += c;
00135 c = is.get();
00136 }
00137
00138 if (c != FINCADENA) {
00139 throw errorFormato(is, string("Se esperaba ") + FINCADENA);
00140 }
00141 hermano = leeNDesp(is);
00142 hijo = leeNDesp(is);
00143
00144
00145 cpos = leePos(is, NULL);
00146 if (long(is.tellg()) != hermano) {
00147 stringstream ss;
00148 ss << "Cursor y hermano difieren (" << is.tellg() << ", " << hermano << ")";
00149 throw errorFormato(is, ss.str());
00150 }
00151
00152 NodoTrieS *hermanomayor = leePlanoStream(is);
00153 NodoTrieS *hijomenor = NULL;
00154 if (hijo > 0) {
00155 is.seekg(hijo);
00156 hijomenor = leePlanoStream(is);
00157 }
00158 NodoTrieS *r = new NodoTrieS(cad, hijomenor,
00159 hermanomayor, *cpos);
00160
00161 return r;
00162 }
00163
00164
00165 void
00166 escribePlano(NodoTrieS &t, vector<Doc> &docs, char *na, char *nrel)
00167 {
00168
00169 ASSERT(na!=NULL && na[0] != '\0' && strlen(na)<FILENAME_MAX);
00170 ASSERT(nrel!=NULL && na[0] != '\0' && strlen(nrel)<FILENAME_MAX);
00171
00172 fstream os(na, ios_base::out);
00173 os << MARCAIND << endl;
00174 escribePlanoStream(&t, os);
00175 os.close();
00176
00177 escribeRelacion(nrel, docs, NULL);
00178 }
00179
00180
00181
00182 NodoTrieS *
00183 leePlano(char *na, char *nrel, vector<Doc> &docs)
00184 {
00185 NodoTrieS *r;
00186
00187 fstream is(na, ios_base::in);
00188 verificaIndice(is);
00189 try {
00190 r = leePlanoStream(is);
00191 } catch (string m) {
00192 stringstream ss;
00193 ss << na << ":" << is.tellg() << m << endl;
00194 throw ss.str();
00195 }
00196 is.close();
00197
00198 leeRelacion(nrel, docs);
00199
00200 return r;
00201 }
00202
00203
00204 long escribeCopiaNodoRam(iostream &os, NodoTrieS *a, int saltacad,
00205 NodoTrieS **phijo, vector<long>* renum)
00206 {
00207 ASSERT(phijo != NULL);
00208
00209 long ret = 0;
00210
00211
00212 string cad = (a != NULL ? a->cad.substr(saltacad) : "");
00213
00214 if (cad != "") {
00215
00216 *phijo = a->hijo_menor;
00217 long dhijo = 0;
00218 if (*phijo != NULL) {
00219 dhijo = precalcula_escribe_con_hermanos(a);
00220 }
00221
00222
00223
00224 set<Pos> *cp = copiaPos((a->cpos), renum);
00225 ret = escribeNodo(os, cad, cp, dhijo);
00226 delete cp;
00227
00228 }
00229
00230
00231 return ret;
00232 }
00233
00234
00235 long
00236 escribeCopiaSubarbolRam(iostream &os, NodoTrieS *a, int saltacad,
00237 bool conHermanos, vector<long>* renum)
00238 {
00239
00240 long prini = os.tellp();
00241
00242
00243
00244 string cad;
00245 long n;
00246 vector<NodoTrieS *> dhijo;
00247 vector<long> pih;
00248
00249 cad = (a != NULL ? a->cad.substr(saltacad) : "");
00250
00251
00252
00253
00254
00255
00256
00257 for (n = 0; cad != "" && (conHermanos || n == 0); n++) {
00258
00259
00260
00261
00262
00263
00264
00265 dhijo.push_back(a->hijo_menor);
00266 set<Pos> *cp = copiaPos((a->cpos), renum);
00267 long tp = escribeNodo(os, cad, cp, 0);
00268 delete cp;
00269
00270 pih.push_back(tp);
00271
00272 if (depuraos!=NULL) {
00273 cout << depuraos->str() << endl;
00274 }
00275 a = a->hermano_mayor;
00276 if (conHermanos) {
00277 cad = (a != NULL ? a->cad : "");
00278 }
00279 }
00280 if (n > 0) {
00281 os << endl;
00282
00283 }
00284 long i;
00285
00286
00287
00288
00289
00290
00291 long pini, pfin;
00292 for (i = 0; i < n; i++) {
00293 if (dhijo[i] != NULL) {
00294
00295
00296 pini = escribeCopiaSubarbolRam(os, dhijo[i], 0,
00297 true, renum);
00298
00299 pfin = os.tellp();
00300
00301 os.seekp(pih[i]);
00302
00303 escribeNDesp(os, pini);
00304
00305 os.seekp(pfin);
00306 }
00307 }
00308
00309 return prini;
00310 }
00311
00312
00313 long
00314 mezclaDiscoRam(istream &is1, NodoTrieS *a2, int saltacad, iostream &os,
00315 bool conHermanos1, bool conHermanos2,
00316 vector<long> *renum1, vector<long> *renum2)
00317 {
00318
00319 string cad1;
00320 string cad2;
00321 long numhermanos;
00322 long n1=0;
00323 long n2=0;
00324 long phermano1;
00325
00326
00327
00328 const int O_COPIA1=1,
00329 O_COPIA2=2,
00330 O_MEZCLA_H1H2=3,
00331 O_MEZCLA_H1=4,
00332 O_MEZCLA_H2=5,
00333 O_COPIA_PRIMERO_1=6,
00334 O_COPIA_PRIMERO_2=7;
00335
00336 ;
00337 vector<long> dhijo1(0);
00338 vector<int> dhijo2_saltacad(0);
00339 vector<NodoTrieS *> dhijo2(0);
00340 vector<string> resto1(0);
00341 vector<string> resto2(0);
00342 vector<int> opera(0);
00343 vector<long> pih(0);
00344
00345 long prini = os.tellp();
00346
00347
00348 if (a2 != NULL) {
00349
00350 }
00351 for (cad1=leeCad(is1), cad2=(a2 != NULL ? a2->cad.substr(saltacad) : ""),
00352 numhermanos = 0;
00353 (cad1!="" && (conHermanos1 || n1==0)) ||
00354 (cad2!="" && (conHermanos2 || n2==0));
00355 numhermanos++) {
00356
00357 dhijo1.push_back(-1);
00358 dhijo2_saltacad.push_back(0);
00359 dhijo2.push_back(NULL);
00360 resto1.push_back("");
00361 resto2.push_back("");
00362 opera.push_back(-1);
00363 pih.push_back(-1);
00364
00365 if (!conHermanos1 && n1 >= 1) {
00366 cad1="";
00367 }
00368 if (!conHermanos2 && n2 >= 1) {
00369 cad2="";
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 string c = "";
00381 if (cad1 != "" && cad2 != "") {
00382 c = prefijo_comun_mas_largo(cad1, cad2);
00383 }
00384
00385 if (c == "") {
00386 resto1[numhermanos] = "";
00387 resto2[numhermanos] = "";
00388 if (cad2=="" || (cad1!="" && cad1<cad2)) {
00389
00390
00391
00392 phermano1 = leeNDesp(is1);
00393 dhijo1[numhermanos] = leeNDesp(is1);
00394 dhijo2[numhermanos] = NULL;
00395 set<Pos> *cpos = leePos(is1, renum1);
00396 opera[numhermanos] = O_COPIA1;
00397 pih[numhermanos] =
00398 escribeNodo(os, cad1, cpos, 0);
00399 delete cpos;
00400 cpos = NULL;
00401 cad1 = leeCad(is1);
00402 n1++;
00403
00404
00405
00406 } else {
00407
00408
00409 ASSERT(cad1 == "" || (cad1 > cad2));
00410
00411 dhijo1[numhermanos] = -1;
00412 dhijo2_saltacad[numhermanos] = 0;
00413 dhijo2[numhermanos] = a2->hijo_menor;
00414
00415 opera[numhermanos] = O_COPIA2;
00416 set<Pos> *cp = copiaPos((a2->cpos), renum2);
00417 pih[numhermanos] =
00418 escribeNodo(os, cad2, cp, 0);
00419 delete cp;
00420 a2 = a2->hermano_mayor;
00421 cad2 = (a2 != NULL) ? a2->cad : "";
00422 n2++;
00423 }
00424 } else if (cad1 == cad2) {
00425 phermano1 = leeNDesp(is1);
00426 dhijo1[numhermanos] = leeNDesp(is1);
00427 dhijo2_saltacad[numhermanos] = 0;
00428 dhijo2[numhermanos] = a2->hijo_menor;
00429
00430 set<Pos> cpos;
00431 insert_iterator<set<Pos> >
00432 cpos_ins(cpos, cpos.begin());
00433 set<Pos> *cpos1 = leePos(is1, renum1);
00434 set<Pos> *cpos2 = copiaPos(a2->cpos, renum2);
00435
00436 set_union(cpos1->begin(), cpos1->end(),
00437 cpos2->begin(), cpos2->end(),
00438 cpos_ins);
00439
00440 pih[numhermanos] = escribeNodo(os, cad2, &cpos, 0);
00441 delete cpos1;
00442 cpos1=NULL;
00443 delete cpos2;
00444 cpos1=NULL;
00445
00446 resto1[numhermanos] = "";
00447 resto2[numhermanos] = "";
00448 opera[numhermanos] = O_MEZCLA_H1H2;
00449 cad1 = leeCad(is1);
00450 n1++;
00451 a2 = a2->hermano_mayor;
00452 cad2 = (a2 != NULL) ? a2->cad : "";
00453 n2++;
00454 } else {
00455 string r1 = cad1.substr(c.size());
00456 string r2 = cad2.substr(c.size());
00457 resto1[numhermanos] = r1;
00458 resto2[numhermanos] = r2;
00459 ASSERT(r1 != "" || r2 != "");
00460
00461 if (r1=="") {
00462
00463 ASSERT(r2 != "");
00464
00465
00466
00467
00468
00469 phermano1 = leeNDesp(is1);
00470 dhijo1[numhermanos] = leeNDesp(is1);
00471 dhijo2_saltacad[numhermanos] = saltacad +
00472 c.length();
00473 dhijo2[numhermanos] = a2;
00474 a2 = a2->hermano_mayor;
00475 set<Pos> *cpos1 = leePos(is1, renum1);
00476 pih[numhermanos] = escribeNodo(os, c, cpos1, 0);
00477 opera[numhermanos] = O_MEZCLA_H1;
00478 delete cpos1;
00479 cpos1=NULL;
00480 } else if (r2 == "") {
00481
00482 ASSERT(r1 != "");
00483
00484
00485 phermano1 = leeNDesp(is1);
00486 dhijo1[numhermanos] = (long)is1.tellg() -
00487 MAXLNUMERO - 1 - (long)r1.size();
00488 dhijo2_saltacad[numhermanos] = 0;
00489 dhijo2[numhermanos] = a2->hijo_menor;
00490 is1.seekg(phermano1);
00491 set<Pos> *cpos2 = copiaPos(a2->cpos, renum2);
00492
00493
00494 pih[numhermanos] = escribeNodo(os, c,
00495 cpos2, 0);
00496
00497 delete cpos2;
00498 a2 = a2->hermano_mayor;
00499 opera[numhermanos] = O_MEZCLA_H2;
00500 } else if (r1 < r2) {
00501
00502
00503
00504 phermano1 = leeNDesp(is1);
00505 pih[numhermanos] = escribeNodo(os, c, NULL, 0);
00506 dhijo1[numhermanos] = (long)is1.tellg() -
00507 MAXLNUMERO - 1 - (long)r1.size();
00508 dhijo2_saltacad[numhermanos] = saltacad +
00509 c.length();
00510 dhijo2[numhermanos] = a2;
00511 is1.seekg(phermano1);
00512 a2 = a2->hermano_mayor;
00513 opera[numhermanos] = O_COPIA_PRIMERO_1;
00514
00515
00516
00517 } else {
00518
00519
00520 phermano1 = leeNDesp(is1);
00521 pih[numhermanos] = escribeNodo(os, c, NULL, 0);
00522 dhijo1[numhermanos] = (long)is1.tellg() -
00523 MAXLNUMERO - 1 - (long)r1.size();
00524 dhijo2_saltacad[numhermanos] = saltacad +
00525 c.length();
00526 dhijo2[numhermanos] = a2;
00527
00528 is1.seekg(phermano1);
00529 a2 = a2->hermano_mayor;
00530 opera[numhermanos] = O_COPIA_PRIMERO_2;
00531 }
00532 cad1=leeCad(is1);
00533 n1++;
00534 cad2=(a2 != NULL ? a2->cad : "");
00535 n2++;
00536 }
00537 }
00538 os << endl;
00539
00540
00541
00542 long pini, pfin;
00543 long hijo1 = 0;
00544 NodoTrieS *hijo2 = NULL;
00545 long ph1, ph2, pnh1, pnh2;
00546 for (int n = 0; n < numhermanos; n++) {
00547 pini = 0;
00548 switch (opera[n]) {
00549 case O_COPIA1:
00550
00551 if (dhijo1[n] > 0) {
00552 is1.seekg(dhijo1[n]);
00553 pini = escribeCopiaSubarbol(os, is1,
00554 true, renum1);
00555 }
00556 break;
00557
00558 case O_COPIA2:
00559
00560 if (dhijo2[n] != NULL) {
00561
00562 pini = escribeCopiaSubarbolRam(os,
00563 dhijo2[n],
00564 0, true, renum2);
00565 }
00566 break;
00567
00568 case O_MEZCLA_H1H2:
00569
00570 if (depuraos!=NULL) {
00571
00572 }
00573
00574
00575 if (dhijo1[n] > 0 && dhijo2[n] != NULL) {
00576 is1.seekg(dhijo1[n]);
00577 pini = mezclaDiscoRam(is1, dhijo2[n],
00578 dhijo2_saltacad[n], os,
00579 true, true, renum1,
00580 renum2) ;
00581 } else if (dhijo1[n] > 0) {
00582 ASSERT(dhijo2[n] == NULL);
00583 is1.seekg(dhijo1[n]);
00584 pini = escribeCopiaSubarbol(os, is1,
00585 true, renum1);
00586 } else if (dhijo2[n] != NULL) {
00587
00588 ASSERT(dhijo1[n] == 0);
00589 pini = escribeCopiaSubarbolRam(os,
00590 dhijo2[n],
00591 dhijo2_saltacad[n],
00592 true, renum2);
00593
00594 }
00595 break;
00596 case O_MEZCLA_H1:
00597
00598 ASSERT(dhijo2[n] != NULL);
00599
00600
00601 if (dhijo1[n] > 0) {
00602 is1.seekg(dhijo1[n]);
00603 pini = mezclaDiscoRam(is1, dhijo2[n],
00604 dhijo2_saltacad[n],
00605 os, true, false, renum1,
00606 renum2) ;
00607 } else {
00608 pini = escribeCopiaSubarbolRam(os,
00609 dhijo2[n],
00610 dhijo2_saltacad[n],
00611 false, renum2);
00612 }
00613 break;
00614
00615 case O_MEZCLA_H2:
00616
00617 ASSERT(dhijo1[n] != 0);
00618
00619 is1.seekg(dhijo1[n]);
00620
00621 if (dhijo2[n] != NULL) {
00622 pini = mezclaDiscoRam(is1, dhijo2[n],
00623 dhijo2_saltacad[n],
00624 os, false, true, renum1,
00625 renum2) ;
00626 } else {
00627 pini = escribeCopiaSubarbol(os, is1,
00628 false, renum1);
00629 }
00630 break;
00631
00632 case O_COPIA_PRIMERO_1:
00633
00634 ASSERT(dhijo1[n] != 0);
00635 ASSERT(dhijo2[n] != NULL);
00636
00637 is1.seekg(dhijo1[n]);
00638 pini = os.tellp();
00639
00640
00641
00642
00643 pnh1 = escribeCopiaNodo(os, is1, hijo1, renum1);
00644 pnh2 = escribeCopiaNodoRam(os, dhijo2[n],
00645 dhijo2_saltacad[n],
00646 &hijo2, renum2);
00647 os << endl;
00648 ph1=os.tellp();
00649 if (hijo1 > 0) {
00650 is1.seekg(hijo1);
00651 (void)escribeCopiaSubarbol(os, is1,
00652 true, renum1);
00653 }
00654 ph2=os.tellp();
00655 if (hijo2 != NULL) {
00656 escribeCopiaSubarbolRam(os, hijo2,
00657 0, true, renum2);
00658 }
00659 pfin = os.tellp();
00660 if (hijo1 > 0) {
00661 os.seekp(pnh1);
00662 escribeNDesp(os, ph1);
00663 }
00664 if (hijo2 != NULL) {
00665 os.seekp(pnh2);
00666 escribeNDesp(os, ph2);
00667 }
00668 os.seekp(pfin);
00669
00670 break;
00671
00672 case O_COPIA_PRIMERO_2:
00673
00674 ASSERT(dhijo1[n] != 0);
00675 ASSERT(dhijo2[n] != NULL);
00676
00677 is1.seekg(dhijo1[n]);
00678 pini = os.tellp();
00679
00680 pnh2=escribeCopiaNodoRam(os, dhijo2[n],
00681 dhijo2_saltacad[n],
00682 &hijo2, renum2);
00683 pnh1=escribeCopiaNodo(os, is1, hijo1, renum1);
00684 os << endl;
00685 ph2=os.tellp();
00686 if (hijo2 != NULL) {
00687 escribeCopiaSubarbolRam(os, hijo2,
00688 0, true, renum2);
00689 }
00690 ph1=os.tellp();
00691 if (hijo1 > 0) {
00692 is1.seekg(hijo1);
00693 escribeCopiaSubarbol(os, is1,
00694 true, renum1);
00695 }
00696 pfin = os.tellp();
00697 if (hijo2 != NULL) {
00698 os.seekp(pnh2);
00699 escribeNDesp(os, ph2);
00700 }
00701 if (hijo1 > 0) {
00702 os.seekp(pnh1);
00703 escribeNDesp(os, ph1);
00704 }
00705 os.seekp(pfin);
00706
00707 break;
00708
00709 default:
00710 throw std::string("Falla: estado desconocido");
00711 break;
00712 }
00713 pfin = os.tellp();
00714
00715
00716 os.seekp(pih[n]);
00717 escribeNDesp(os, pini);
00718 os.seekp(pfin);
00719 }
00720
00721 return prini;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
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
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169