root/trunk/ciifl.c

Revision 389, 73.7 kB (checked in by heitor.barbieri, 3 weeks ago)

essage first commit

Line 
1/*-------------------------------------------------------------------------
2 ciifl.c
3    Faz o load do arquivo invertido (.ifp) e do dicionario (.n0* e .l0*)
4 -------------------------------------------------------------------------*/
5/* 19-02-95 : Correcao do load de arquivos com + de 32k postings
6              O primeiro segmento estava com o numero total de postings
7              corretos. Porem os apontadores dos segmentos seguintes
8              estavam incorretos. Algumas mudancas feitas(types) nao
9              implicavam  no erro.
10*/
11#define TRACE_HEADER 0
12#include <stdio.h>
13#include <string.h>
14#include "cisis.h"
15#include "ciupi.h"
16
17#if CICPP
18#include "cirec.hpp"   /* new RECSTRU */
19#endif /* CICPP */
20
21#if !CICPP
22char *ifllk_gidbnp=NULL;                /* dbn.par */
23#endif /* CICPP */
24
25#if CICPP
26#include <ciifl.hpp>
27#include <cidbx.hpp>
28#include <citrm.hpp>
29#include <cirun.hpp>
30#ifdef USE_ERROR_SYS
31#include <ui_win.hpp>
32#include <errorsys.hpp>
33extern MY_ERROR_SYSTEM * errsys;
34extern UIW_WINDOW *wprogress;
35extern MESS_SYSTEM *mess;
36void ISIS_OemToAnsi(char *in, char *out);
37#include <textdb.hpp>
38#define USE_INFO_SYS
39#endif
40#endif /* CICPP */
41
42#if !CICPP
43int ifl_balan=1;   /* Faz balanceamento da arvore */
44#endif /* CICPP */
45
46#define AOT            1
47
48#define  TSTBALANCE    DEBIFUPD
49#define  TRACELOAD     DEBIFUPD
50#define  RESUMOLOAD    DEBIFUPD
51#define  TRCBUFF       DEBIFUPD
52#define  MAXPSTS       MAXIDXPST
53#define  BLK(x)        x->ifpblk
54
55/* Esta estrutura guarda  o ultimo no de cada nivel
56   Foi definida em cima do maximo valor que sao os
57   nos da arvore do tipo 2.
58   Poderia ser feita uma alocacao dinamica
59*/
60#if !CICPP
61typedef struct tree_nodes {
62  int top;
63  N2STRU  idx_node[MAX_TREE_LEVEL];
64 } TREE_NODES;
65#endif /* CICPP */
66
67/* -----------------------------------------------------------------------*/
68/*                 Prototypes                                             */
69/* -----------------------------------------------------------------------*/
70#if !CICPP
71#if ANSI
72/*y*/ static void lifp_init_counters(void);
73static void lifp_init_leaf(L0STRU *lp,int treecase);
74static void lifp_init_node(N0STRU *n0p,int treecase);
75static BOOLEAN lifp_insert_leaf(DBXSTRU *dbxp,char *key,char *p_b_key,
76                         PUNT *p_b_punt, int treecase,INFX info1,
77                         INFO  info2);
78static BOOLEAN lifp_insert_node (DBXSTRU *dbxp,N0STRU *n0p,int treecase,
79                          int level,
80                          int isroot,UCHR *b_key,PUNT b_punt,
81                          UCHR *p_key,PUNT *p_punt);
82static void lifp_create_root(INVMAP *invp,N0STRU *n0p,PUNT esq,char *key,
83                      PUNT dir,int treecase,BOOLEAN first);
84#else
85/*y*/ static void lifp_init_counters();
86static void lifp_init_leaf();
87static void lifp_init_node();
88static BOOLEAN lifp_insert_leaf();
89static BOOLEAN lifp_insert_node ();
90static void lifp_create_root();
91#endif /* ANSI */
92#endif /* CICPP */
93
94#if !CICPP
95#if ANSI
96static void determina_nova_qtda(int ordem,int a,int b,int *n_a,int *n_b);
97static void init_invp_roots_nodes_leaves(INVMAP *invp);
98static void balance_nodes(DBXSTRU *dbxp,INVMAP *invp,int treecase,
99                 int level,PUNT idxpenultimo,PUNT idxultimo,N0STRU *np);
100static void balance_btree(DBXSTRU *dbxp,INVMAP *invp,
101                          int level,PUNT punt,int treecase);
102static void balance_leaves(DBXSTRU *dbxp,INVMAP *invp,int treecase,
103                           PUNT idxpenultimo,PUNT idxultimo,N0STRU *np);
104static void lifp_store_btree(UCHR *key,INFX blk,INFO off,int treecase);
105static IFPBUFFER *lifp_init(INVMAP *invp); /* antes de LKXONLY: (void) */
106static void lifp_close_tree(void);
107#if !LIND
108static void lifp_grava_ifp(void);
109static void lifp_storepst(void);
110static void lifp_init_buff(IFPBUFFER  *p,INFO blk);
111static void write_buffers(BOOLEAN keep_head,BOOLEAN reestrut_buff);
112static void get_room_for (int qt,BOOLEAN opt_keep_head);
113static void lifp_upd_pst_header(IFPSTRU *p,INFO offset,INFO nxtb,INFO nxtp,
114                         INFO totp,INFO segp,INFO segc);
115/*static void lifp_upd_first_rec(IFPAVAILPOS *pn,INFO next_blk,UWORD idxpst); */
116static void lifp_upd_first_rec(IFPAVAILPOS *pn,INFO next_blk,INFO next_post);
117 /*19-02-95*/
118static void lifp_init_ifprec(IFPSTRU *p,INFO blk);
119#endif /* !LIND */
120#else
121static void determina_nova_qtda();
122static void init_invp_roots_nodes_leaves();
123static void balance_nodes();
124static void balance_btree();
125static void balance_leaves();
126static void lifp_store_btree();
127static IFPBUFFER *lifp_init();
128static void lifp_close_tree();
129#if !LIND
130static void lifp_grava_ifp();
131static void lifp_storepst();
132static void lifp_init_buff();
133static void write_buffers();
134static void get_room_for ();
135static void lifp_upd_pst_header();
136static void lifp_upd_first_rec();
137static void lifp_init_ifprec();
138#endif /* !LIND */
139#endif /* ANSI */
140#endif /* CICPP */
141
142#if !CICPP
143#if ANSI
144static int lifp_trans_key(UCHR *keyp, int len, int *treecase);
145#else
146static int lifp_trans_key();
147#endif /* ANSI */
148#endif /* CICPP */
149
150/* -----------------------------------------------------------------------*/
151
152#if !CICPP
153 static TREE_NODES load_idx[2];
154 static PUNT last_root;  /* Guarda a raiz atual antes de criar uma nova raiz
155*/
156 static L0STRU *l0p;
157 static L1STRU *l1p, l1node;
158 static L2STRU *l2p, l2node;
159 static L1IDXE init_leaf_el1;
160 static L2IDXE init_leaf_el2;
161 static N1IDXE init_node_el1;
162 static N2IDXE init_node_el2;
163 static LONGX  print_step=0L;
164#if TRACELOAD
165  UCHR tkey[LE2+1], *ptkey; /* AOT 23/10/93 */
166  int  ti;
167#endif
168 static POSTSTRU pst,pst_ant;
169 static UCHR  *keyp;
170 static LONGX  nlido;
171 static PUNT p_b_punt,
172             key_punt;
173 static INVMAP *invp;
174 static DBXSTRU *dbxp;
175 static N0STRU *n0p;
176 static UWORD isroot,i;
177 static UCHR  *p_b_key,
178              a_p_b_key[LE2+1];
179 static BOOLEAN promoted;
180 static int topo,
181            level,
182            keysize,
183            treecase,
184            treecase_ant;
185 static UCHR key_ant[LE2+1],
186             key[LE2+1];
187 static IFPBUFFER *ifpbuff=NULL; /* AOT - 16/09/93 */
188#if !LIND
189 static INFO key_blk,
190             key_pos;
191 /* static int tag,occ,cnt; */   /* AOT - 26/10/93 */
192 static IFPAVAILPOS pn;
193 static IFPSTRU  *pf,
194                 *ph,
195                 *pb;
196 static INFO next_blk,
197             next_pos;
198 static INFO totp,
199             nxtb,
200             nxtp,
201             segp,
202             segc;
203 static INFO off_f,
204             off_h,
205             npst;
206 static int gbuf;
207 static IFPSTRU current_seghead,
208                first_seghead;
209 static IFPHEAD *currenthead,
210                *firsthead;
211 static BOOLEAN flag_first_seghead,
212                flag_current_seghead;
213 static UWORD idxpst;
214#endif /* !LIND */
215#if LIND
216#include "ciiflh.c"
217#endif /* LIND */
218#if LKXONLY
219 static int lkxonly;    /* AOT - 14/05/98 */
220#endif
221
222/*25/07/97*/
223/* Variaveis para guardar a localizacao ds headers de um segmento */
224/* 128/(5+2) */
225#define IFLmaxhd  IFPmaxhd*MAXIFPMEM + 1   /* headers em memoria */
226#if CNV_PCBINUM
227static int hdn=-1;       /* numero headers de um ifp */
228static INFO hdblk[IFLmaxhd];
229static INFO hdoff[IFLmaxhd];
230#endif
231/* Descricao de Variaveis e Atualizacao do IFP
232  pn - pointer para o primeiro registro do arquivo que contem o apontador
233       para o proximo (blk,off) disponiveis.
234  ph - pointer para o registro onde esta o head do segmento que devera ser
235       atualizado
236  pb - pointer para o bloco onde estao sendo gravados os postings
237  pf - pointer para o primeiro bloco onde e' gravado o total de postings
238       quando uma chave possui mais MAXPSTSSEG e deve ser gravada em dois
239       segmentos diferentes
240  ifpbuff - Buffer de MAXIFPMEM blocos com objetivo de acelerar a atualiacao
241            Nesse buffer devem ser mantidos blocos sequenciais " de disco"
242            de forma em unico acesso gravar variso blocos
243  off_h e off_f - guardam a posicao do header do posting dentro de ph e pf
244                  respectivamente
245  Algoritmo:
246  Em determinado momento  os postings de uma chave podem ser encaixados em
247  uma das seguintes condicoes:
248  1) Todos os postings cabem em um pedaco do ifpbuff. Neste caso temos:
249     ph - aponta para  um bloco do  ifpbuff.
250     A varivavel pf nao dever ser considerada.
251  2) Embora a quantidade de postings seja pequena e menor que MAXPSTSSEG
252     nao cabe nas posicoes disponiveis do ifpbuff. Neste caso devemos:
253     a) Gravar ifpbuff;
254     b) copiar o bloco onde esta o header do segmento (pb) para uma
255        variavel temporaria e apontar ph para essa area. Notar que o
256        embora o header seja gravado seus valores estarao incorretos.
257         ph=endereco de header_temp;
258         copiar: pb para ph;
259         off_h = pb.off;
260     c) Indicar que agora ph nao aponta para  o buffer sequencial
261        flag_current_seghead=true;
262    No final o header devera ser regravado com os valores corretos.
263 3) O numero de postings da chave ultrapassa MAXPSTSSEG. Neste caso
264    sera gerado mais de um segmento.
265    O primeiro segmento devera ser mantido em memoria porque e' nele
266    que e gravado a quantidade correta de postings do segmento
267    Entao havera necessidade de dois apontadores:
268    pf - aponta para o primeiro segmento
269    ph - aponta para o segmento corrente.
270    No memomento que o numero de postings ultrapassa MAXPSTSSEG deve-se
271    a) Copiar ph para pf
272    b) flag_first_seghead =true
273    c)
274
275/*-------------------------------------------------------------------------*/
276/* Este algoritmo determina qual a quantidade de chaves que os nos
277   mais a direita devem ter. Foi feito para que o load ficasse
278   igual ao do ISIS . Acho que nao deveria deste jeito, porque nao
279   separa igualmente a quantidade de chaves.
280   Inicialmente o algoritmo de load, fazia com que, para todos os niveis,
281   os dois nos mais a direita do nivel ficassem desbalanceados. Era possivel
282   termos o penultimo com 10 ocorrencias e o ultimo com uma ocorrencia.
283   Apos o balanceamento dos nos mais a direita de cada nivel fica da
284   seguinte maneira ( a e b sao os dois ultimos nos)
285   a+b       nova qta a   nova qta b
286   11          5             6
287   12          5             7
288   13          5             8
289   14          5             9
290   15          5             10
291   16          8             8
292   17          8             9
293   18          8             10
294   19          9             10
295   20          10            10
296*/
297
298#endif /* CICPP */
299
300#if CICPP
301void CIIFL :: determina_nova_qtda(int  ordem,
302                                  int  a,
303                                  int  b,
304                                  int *n_a,
305                                  int *n_b)
306#else /*CICPP*/
307static void determina_nova_qtda(ordem,a,b,n_a,n_b)
308int ordem;
309int a;
310int b;
311int *n_a;
312int *n_b;
313#endif /*CICPP*/
314{
315 int x,y,soma;
316 soma=a+b;
317 x=ordem;      /* Caso 1 : a=5; b=6,7,8,9,10 */
318 y=soma-x;
319 if (y>2*ordem) {
320   x=(3*ordem+1)/2; /* Caso 2: a=8; b:8,9,10  */
321   y=soma-x;
322   if (y>2*ordem) {  /* Caso 3: a=9; b=9,10 ou
323            Caso 4: a=10; b=10
324             */
325      x=soma/2;
326      y=soma-x;
327   }
328 }
329 *n_a=x;
330 *n_b=y;
331}
332/* #include "leaves.c" */
333/* ------------------------------------------------------------------------*/
334#if CICPP
335void CIIFL :: balance_leaves(DBXSTRU *dbxp,
336                             INVMAP *invp,
337                             int     treecase,
338                             PUNT    idxesq,
339                             PUNT    idxdir,
340                             N0STRU *np)
341#else /*CICPP*/
342static void balance_leaves(dbxp,invp,treecase,idxesq,idxdir,np)
343DBXSTRU *dbxp;
344INVMAP *invp;
345int treecase;
346PUNT idxesq;
347PUNT idxdir;
348N0STRU *np;
349#endif /*CICPP*/
350{
351  UCHR *lbufp;
352  N1STRU *ptmp_pai1;
353  N2STRU *ptmp_pai2;
354  L0STRU *l0p,*pesq0,*pdir0;
355  L1STRU *pesq1,esq1,
356         *pdir1,dir1,
357         *ptmp_esq1,tmp_esq1,
358         *ptmp_dir1,tmp_dir1,
359         trml1buf;
360  L2STRU *pesq2,esq2,
361         *pdir2,dir2,
362         *ptmp_esq2,tmp_esq2,
363         *ptmp_dir2,tmp_dir2,
364         trml2buf;
365  PUNT punt;
366  int n_esq,n_dir,ock,id,nn;
367  keysize=vlex[treecase];
368  if (treecase == 0)
369     lbufp= (UCHR *)(&trml1buf);
370  else
371     lbufp= (UCHR *)(&trml2buf);
372  if (idxesq==0) return;
373  if (idxdir==0) return;
374  punt= -idxesq;
375  if (punt<0) {
376     fatal(" balance_leaves/punt >0");
377  }
378  l0p=(L0STRU *)leafread(lbufp,invp,treecase,punt,0);
379  if (treecase==0) {
380    ptmp_esq1= &tmp_esq1;
381    pesq1= &esq1;
382    memcpy((UCHR *)pesq1,(UCHR *)l0p,sizeof(L1STRU ));
383  } else {
384    ptmp_esq2= &tmp_esq2;
385    pesq2= &esq2;
386    memcpy((UCHR *)pesq2,(UCHR *)l0p,sizeof(L2STRU ));
387  }
388  punt= -idxdir;
389  if (punt<0) {
390    fatal(" balance_leaves/punt >0");
391  }
392  l0p=(L0STRU *)leafread(lbufp,invp,treecase,punt,0);
393  if (treecase==0) {
394    pdir1= &dir1;
395    memcpy((UCHR *)pdir1,(UCHR *)l0p,sizeof(L1STRU ));
396  } else {
397    pdir2= &dir2;
398    memcpy((UCHR *)pdir2,(UCHR *)l0p,sizeof(L2STRU ));
399  }
400  if (treecase==0) {
401     ptmp_pai1=(N1STRU *)np ;
402#if TSTBALANCE
403      printf("\n Antes de balancear ");
404      upif_print_node ((N0STRU *)ptmp_pai1);
405      upif_print_leaf ((L0STRU *)pesq1);
406      upif_print_leaf ((L0STRU *)pdir1);
407#endif
408     determina_nova_qtda(ORDF,pesq1->ock,pdir1->ock,&n_esq,&n_dir);
409     ptmp_esq1= &tmp_esq1;
410     ptmp_dir1= &tmp_dir1;
411     lifp_init_leaf((L0STRU *)ptmp_esq1,treecase);
412     lifp_init_leaf((L0STRU *)ptmp_dir1,treecase);
413  }else {
414     ptmp_pai2=(N2STRU *)np ;
415#if TSTBALANCE
416      printf("\n Antes de balancear ");
417      upif_print_node ((N0STRU *)ptmp_pai2);
418      upif_print_leaf ((L0STRU *)pesq2);
419      upif_print_leaf ((L0STRU *)pdir2);
420#endif
421     determina_nova_qtda(ORDF,pesq2->ock,pdir2->ock,&n_esq,&n_dir);
422     ptmp_esq2= &tmp_esq2;
423     ptmp_dir2= &tmp_dir2;
424     lifp_init_leaf((L0STRU *)ptmp_esq2,treecase);
425     lifp_init_leaf((L0STRU *)ptmp_dir2,treecase);
426  }
427   /* Da forma que o algoritmo de load funciona, a celula da esquerda
428      contera sempre o numero maximo de chaves . Eles deverao ser
429      divididos entre a esquerda e a direita levando em conta o criterio
430      (furado!!!) do ISIS.
431   */
432   /* Atualiza headers.
433     Copia  "n_esq"    nos da esquerda para temporaria
434   */
435  if (treecase == 0) {
436     ock=pesq1->ock;
437     ptmp_esq1->ock=n_esq;
438     ptmp_esq1->pos=pesq1->pos;
439     ptmp_esq1->ps= pesq1->ps;
440#if LIND
441     ptmp_esq1->psb= pesq1->psb;
442#endif /* LIND */
443     ptmp_esq1->it= pesq1->it;
444     ptmp_dir1->ock=n_dir;
445     ptmp_dir1->pos=pdir1->pos;
446     ptmp_dir1->ps= pdir1->ps;
447#if LIND
448     ptmp_dir1->psb= pdir1->psb;
449#endif /* LIND */
450     ptmp_dir1->it= pdir1->it;
451  }else {
452     ock=pesq2->ock;
453     ptmp_esq2->ock=n_esq;
454     ptmp_esq2->pos=pesq2->pos;
455     ptmp_esq2->ps= pesq2->ps;
456#if LIND
457     ptmp_esq2->psb= pesq2->psb;
458#endif /* LIND */
459     ptmp_esq2->it= pesq2->it;
460     ptmp_dir2->ock=n_dir;
461     ptmp_dir2->pos=pdir2->pos;
462     ptmp_dir2->ps= pdir2->ps;
463#if LIND
464     ptmp_dir2->psb= pdir2->psb;
465#endif /* LIND */
466     ptmp_dir2->it= pdir2->it;
467  }
468   for (nn=0;nn<n_esq;nn++){
469     if (treecase==0) {
470         ptmp_esq1->idx[nn] = pesq1->idx[nn];
471     }else {
472        ptmp_esq2->idx[nn] = pesq2->idx[nn];
473     }
474   }
475 /* O resto das chaves sao copiados para o no da direita */
476   id=0;
477   for (;nn<ock;nn++){
478      if (treecase==0) {
479        ptmp_dir1->idx[id]=pesq1->idx[nn];
480      }else {
481        ptmp_dir2->idx[id]=pesq2->idx[nn];
482      }
483      id++;
484   }
485   /* Acrescenta todas as chaves da direita */
486   if (treecase == 0)
487      ock=pdir1->ock;
488   else
489      ock=pdir2->ock;
490   for (nn=0; nn<ock;nn++){
491      if (treecase==0) {
492        ptmp_dir1->idx[id]=pdir1->idx[nn];
493      } else {
494        ptmp_dir2->idx[id]=pdir2->idx[nn];
495      }
496      id++;
497  }
498  /* A primeira chave da direita deve ser promovida para o pai
499     Deve substituir a chave mais a direita do pai
500  */
501   if (treecase == 0){
502      id=ptmp_pai1->ock-1;/* Ultimo elemento */
503      memcpy(ptmp_pai1->idx[id].key,ptmp_dir1->idx[0].key,keysize);
504      /* O punt nao precisa mudar. E o mesmo */
505   }
506   else {
507      id=ptmp_pai2->ock-1;/* Ultimo elemento */
508      memcpy(ptmp_pai2->idx[id].key,ptmp_dir2->idx[0].key,keysize);
509   }
510 if (treecase==0) {
511  n0p=(N0STRU *)ptmp_pai1;
512  pesq0=(L0STRU *)ptmp_esq1;
513  pdir0=(L0STRU *)ptmp_dir1;
514 }else {
515  n0p=(N0STRU *)ptmp_pai2;
516  pesq0=(L0STRU *)ptmp_esq2;
517  pdir0=(L0STRU *)ptmp_dir2;
518 }
519 /* Como a arvore ja foi gravada correntamente, os valores de level e
520    isroot nao tem mais sentido. Estao sendo passados somente para
521    poder usar as rotinas ja prontas
522 */
523  isroot=FALSE;
524#if TSTBALANCE
525  printf("\n Depois de balancear ");
526  upif_print_node (n0p);
527  upif_print_leaf (pesq0);
528  upif_print_leaf (pdir0);
529#endif
530  nodewrit(dbxp,n0p,invp->cn[treecase].liv,isroot);
531  leafwrit(dbxp,pesq0);
532  leafwrit(dbxp,pdir0);
533}
534/* ------------------------------------------------------------------------*/
535#if CICPP
536void  CIIFL :: balance_nodes(DBXSTRU *dbxp,
537                             INVMAP  *invp,
538                             int      treecase,
539                             int      level,
540                             PUNT     idxpenultimo,
541                             PUNT     idxultimo,
542                             N0STRU  *np)
543#else /*CICPP*/
544static void  balance_nodes(dbxp,invp,treecase,level,idxpenultimo,idxultimo,np)
545DBXSTRU *dbxp;
546INVMAP *invp;
547int treecase;
548int level;
549PUNT idxpenultimo;
550PUNT idxultimo;
551N0STRU *np;
552#endif /*CICPP*/
553{
554 static   N0STRU *n0p,*pesq0,*pdir0;
555 static   N1STRU tmp_esq1,tmp_dir1,
556          *ptmp_pai1,*ptmp_esq1,*ptmp_dir1,
557          *pesq1,*pdir1,esq1,dir1;
558 static  N2STRU tmp_esq2,tmp_dir2,
559         *ptmp_pai2,*ptmp_esq2,*ptmp_dir2,
560         *pesq2,*pdir2,esq2,dir2;
561 static  UCHR *char_pesq,
562         *char_pdir;
563 int n_esq,n_dir,ock,id,nn;
564  keysize=vlex[treecase];
565  if (treecase==0) {
566       pesq1= &esq1;
567       pdir1= &dir1;
568       char_pesq=(UCHR *)noderead(invp,treecase,level,idxpenultimo);
569       memcpy((UCHR *)pesq1,char_pesq,sizeof(N1STRU));
570       char_pdir=(UCHR *)noderead(invp,treecase,level,idxultimo);
571       memcpy((UCHR *)pdir1,char_pdir,sizeof(N1STRU));
572  }else {
573       pesq2= &esq2;
574       pdir2= &dir2;
575       char_pesq=(UCHR *)noderead(invp,treecase,level,idxpenultimo);
576       memcpy((UCHR *)pesq2,char_pesq,sizeof(N2STRU));
577       char_pdir=(UCHR *)noderead(invp,treecase,level,idxultimo);
578       memcpy((UCHR *)pdir2,char_pdir,sizeof(N2STRU));
579  }
580  if (treecase==0) {
581     ptmp_pai1=(N1STRU *)np ;
582#if TSTBALANCE
583      printf("\n Antes de balancear ");
584      upif_print_node ((N0STRU *)ptmp_pai1);
585      upif_print_node ((N0STRU *)pesq1);
586      upif_print_node ((N0STRU *)pdir1);
587#endif
588     determina_nova_qtda(ORDN,pesq1->ock,pdir1->ock,&n_esq,&n_dir);
589     ptmp_esq1= &tmp_esq1;
590     ptmp_dir1= &tmp_dir1;
591     lifp_init_node((N0STRU *)ptmp_esq1,treecase);
592     lifp_init_node((N0STRU *)ptmp_dir1,treecase);
593  }else {
594     ptmp_pai2=(N2STRU *)np ;
595#if TSTBALANCE
596      printf("\n Antes de balancear ");
597      upif_print_node ((N0STRU *)ptmp_pai2);
598      upif_print_node ((N0STRU *)pesq2);
599      upif_print_node ((N0STRU *)pdir2);
600#endif
601         determina_nova_qtda(ORDN,pesq2->ock,pdir2->ock,&n_esq,&n_dir);
602     ptmp_esq2= &tmp_esq2;
603     ptmp_dir2= &tmp_dir2;
604     lifp_init_node((N0STRU *)ptmp_esq2,treecase);
605     lifp_init_node((N0STRU *)ptmp_dir2,treecase);
606  }
607   /* Da forma que o algoritmo de load funciona, a celula da esquerda
608      contera sempre o numero maximo de chaves . Eles deverao ser
609      divididos entre a esquerda e a direita levando em conta o criterio
610      (furado!!!) do ISIS.
611   */
612   /* Atualiza headers.
613     Copia  "n_esq:    nos da esquerda para temporaria*/
614  if (treecase == 0) {
615     ock=pesq1->ock;
616     ptmp_esq1->ock=n_esq;
617     ptmp_esq1->pos=pesq1->pos;
618     ptmp_esq1->it=pesq1->it;
619     ptmp_dir1->ock=n_dir;
620     ptmp_dir1->pos=pdir1->pos;
621     ptmp_dir1->it=pdir1->it;
622  }else {
623     ock=pesq2->ock;
624     ptmp_esq2->ock=n_esq;
625     ptmp_esq2->pos=pesq2->pos;
626     ptmp_esq2->it=pesq2->it;
627     ptmp_dir2->ock=n_dir;
628     ptmp_dir2->pos=pdir2->pos;
629     ptmp_dir2->it=pdir2->it;
630  }
631   for (nn=0;nn<n_esq;nn++){
632     if (treecase==0) {
633         ptmp_esq1->idx[nn] = pesq1->idx[nn];
634     }else {
635         ptmp_esq2->idx[nn] = pesq2->idx[nn];
636     }
637  }
638 /* O resto das chaves sao copiados para o no da direita*/
639   id=0;
640   for (;nn<ock;nn++){
641      if (treecase==0) {
642        ptmp_dir1->idx[id]=pesq1->idx[nn];
643      }else {
644        ptmp_dir2->idx[id]=pesq2->idx[nn];
645      }
646      id++;
647   }
648   /* Acrescenta todas as chaves da direita */
649   if (treecase == 0)
650      ock=pdir1->ock;
651   else
652      ock=pdir2->ock;
653   for (nn=0; nn<ock;nn++){
654      if (treecase==0) {
655        ptmp_dir1->idx[id]=pdir1->idx[nn];
656      } else {
657        ptmp_dir2->idx[id]=pdir2->idx[nn];
658      }
659      id++;
660  }
661  /* A primeira chave da direita deve ser promovida para o pai
662     Deve substituir a chave mais a direita do pai
663  */
664   if (treecase == 0){
665      id=ptmp_pai1->ock-1;/* Ultimo elemento */
666      memcpy(ptmp_pai1->idx[id].key,ptmp_dir1->idx[0].key,keysize);
667      /* O punt nao precisa mudar. E o mesmo */
668   }
669   else {
670      id=ptmp_pai2->ock-1;/* Ultimo elemento */
671      memcpy(ptmp_pai2->idx[id].key,ptmp_dir2->idx[0].key,keysize);
672   }
673 if (treecase==0) {
674  n0p=(N0STRU *)ptmp_pai1;
675  pesq0=(N0STRU *)ptmp_esq1;
676  pdir0=(N0STRU *)ptmp_dir1;
677 }else {
678  n0p=(N0STRU *)ptmp_pai2;
679  pesq0=(N0STRU *)ptmp_esq2;
680  pdir0=(N0STRU *)ptmp_dir2;
681 }
682 /* Como a arvore ja foi gravada correntamente, os valores de level e
683    isroot nao tem mais sentido. Estao sendo passados somente para
684    poder usar as rotinas ja prontas
685 */
686  isroot=FALSE;
687#if TSTBALANCE
688  printf("\n Apos de  balancear ");
689  upif_print_node (n0p);
690  upif_print_node (pesq0);
691  upif_print_node (pdir0);
692#endif
693  nodewrit(dbxp,n0p,invp->cn[treecase].liv,isroot);
694  nodewrit(dbxp,pesq0,invp->cn[treecase].liv,isroot);
695  nodewrit(dbxp,pdir0,invp->cn[treecase].liv,isroot);
696}
697/* -----------------------------------------------------------------------*/
698#if CICPP
699void CIIFL :: balance_btree(DBXSTRU *dbxp,
700                            INVMAP  *invp,
701                            int      level,
702                            PUNT     punt,
703                            int      treecase)
704#else /*CICPP*/
705static void balance_btree(dbxp,invp,level,punt,treecase)
706DBXSTRU *dbxp;
707INVMAP *invp;
708int level;
709PUNT punt;
710int treecase;
711#endif /*CICPP*/
712{
713  UCHR  *np;
714  static  N2STRU node2,area_node2;
715  static  N1STRU node1,area_node1;
716  N2STRU *n2p, *keep_node2;
717  N1STRU *n1p, *keep_node1;
718  N0STRU *n0local;
719  int ock;
720  PUNT idxultimo,idxpenultimo;
721  keep_node1= &area_node1;
722  keep_node2= &area_node2;
723
724  if (punt==0) return;
725  if (punt>0) {
726    idxultimo=1; /* so para inicializar while */
727    while (idxultimo > 0) {
728      np=(UCHR *)noderead(invp,treecase,level,punt);
729      if (treecase==0){
730          memcpy((UCHR *)&node1,np,sizeof(N1STRU));
731          np=(UCHR *)&node1;
732      }
733      else {
734          memcpy((UCHR *)&node2,np,sizeof(N2STRU));
735          np=(UCHR *)&node2;
736      }
737      n1p=(N1STRU *)np;
738      n2p=(N2STRU *)np;
739      n0p=(N0STRU *)np;
740      ock=n0p->ock;
741      if(ock <= 1) return; /* nada a reestruturar */
742      if (treecase == 0) {
743         idxpenultimo=n1p->idx[ock-2].punt;
744         idxultimo=n1p->idx[ock-1].punt;
745         memcpy(keep_node1,np,sizeof(N1STRU));
746         n0local=(N0STRU *)keep_node1;
747      } else {
748         idxpenultimo=n2p->idx[ock-2].punt;
749         idxultimo=n2p->idx[ock-1].punt;
750         memcpy(keep_node2,np,sizeof(N2STRU));
751         n0local=(N0STRU *)keep_node2;
752      }
753     if (idxpenultimo < 0) { /* aponta para folha */
754        balance_leaves(dbxp,invp,treecase,
755                       idxpenultimo,idxultimo, n0local);
756     } else {         /* aponta para no */
757        balance_nodes(dbxp,invp,treecase,level,idxpenultimo,idxultimo,
758                 n0local);
759        punt=idxultimo;
760     }
761   }
762  }/* WHILE*/
763}
764#if !LIND
765/*------------------------------------------------------------------------*/
766#if CICPP
767void CIIFL :: lifp_upd_first_rec(IFPAVAILPOS *pn,
768                                 INFO         next_blk,
769                                 INFO         next_pos)
770#else /*CICPP*/
771static void lifp_upd_first_rec(pn,next_blk,next_pos)
772IFPAVAILPOS *pn;
773INFO next_blk;
774INFO next_pos;
775#endif /*CICPP*/
776{
777 pn->ifpblk=1;
778 pn->nxtb=next_blk;
779 pn->nxtp=next_pos;
780}
781/*------------------------------------------------------------------------*/
782#if CICPP
783void CIIFL :: lifp_init_ifprec(IFPSTRU *p,
784                               INFO     blk)
785#else /*CICPP*/
786static void lifp_init_ifprec(p,blk)
787IFPSTRU *p;
788INFO blk;
789#endif /*CICPP*/
790{ int i;
791  p->ifpblk=blk;
792  for (i=0;i<IFMAXTIV;i++){
793     p->ifprec[i]=0;
794  }
795}
796/*------------------------------------------------------------------------*/
797#if CICPP
798void CIIFL :: lifp_init_buff(IFPBUFFER  *q,
799                             INFO        blk)
800#else /*CICPP*/
801static void lifp_init_buff(q,blk)
802IFPBUFFER  *q;
803INFO blk;
804#endif /*CICPP*/
805{ int i;
806  IFPSTRU *p;
807  for (i=0;i<MAXIFPMEM;i++){
808      p=(IFPSTRU *)&q->buff[i];
809      lifp_init_ifprec(p,blk);
810      blk++;
811  }
812}
813#endif /* !LIND */
814/*------------------------------------------------------------------------*/
815#if CICPP
816IFPBUFFER *CIIFL ::lifp_init(INVMAP *invp)
817#else /*CICPP*/
818static IFPBUFFER *lifp_init(invp)
819INVMAP *invp;
820#endif /*CICPP*/
821{
822  IFPBUFFER *ifpb;
823#if !LIND
824  next_blk=(INFO )1;
825  next_pos=(INFO )2;
826#endif /* !LIND */
827#if CICPP
828  try { ifpb = (IFPBUFFER *) new char [sizeof(IFPBUFFER)]; }
829  catch (BAD_ALLOC) { ifpb = (IFPBUFFER *)ALLONULL; }
830#else /* CICPP */
831  ifpb = (IFPBUFFER *)ALLOC(sizeof(IFPBUFFER));
832#endif /* CICPP */
833  if (ifpb == (IFPBUFFER *)ALLONULL) {
834#if CICPP
835        return(NULL);
836#else /* CICPP */
837        fatal("ALLOC/lifp_init");
838#endif /* CICPP */
839  }
840#if !LIND
841  pn.ifpblk=1;
842#if LKXONLY
843  if (lkxonly & 2) {
844    postread((UCHR *)ifpb,invp,1L,0);
845    next_blk=((IFPCTRL *)ifpb)->ifprec1;
846    next_pos=((IFPCTRL *)ifpb)->ifprec2;
847    pn.ifpblk=next_blk;
848  }
849#endif
850  pn.nxtb=next_blk;
851  pn.nxtp=next_pos;
852  lifp_init_buff(ifpb,next_blk);
853  flag_first_seghead=FALSE;
854  flag_current_seghead=FALSE;
855#endif /* !LIND */
856  key_ant[0]='\0';
857  treecase_ant=0;       /* Sindo, esta' ok para LKXONLY?  Thanks, AOT */
858#if !LIND
859  pf=(IFPSTRU *)&first_seghead;
860#endif /* !LIND */
861  key[0]='\0';
862#if !LIND
863  totp=0;
864  nxtb=0;
865  nxtp=0;
866  segp=0;
867  segc=0;
868  idxpst=next_pos;
869  gbuf=0;
870  ph= &ifpb->buff[gbuf];
871  off_h=idxpst;
872  pb=(IFPSTRU *)&ifpb->buff[gbuf];
873  pb->ifprec[0]=next_blk;
874  pb->ifprec[1]=next_pos;
875  memset((char *)&pst_ant,0x00,sizeof(POSTSTRU));
876#endif /* !LIND */
877 return(ifpb);
878}
879#if !LIND
880/*-----------------------------------------------------------------------*/
881#if CICPP
882void CIIFL :: write_buffers(BOOLEAN keep_head,
883                            BOOLEAN reestrut_buff)
884#else /*CICPP*/
885static void write_buffers( keep_head,reestrut_buff)
886BOOLEAN keep_head;
887BOOLEAN reestrut_buff;
888#endif /*CICPP*/
889{
890 IFPSTRU tmp;
891#if CNV_PCBINUM
892 ifpwrit(dbxp,(char *)ifpbuff,(LONGX )sizeof(IFPBUFFER),hdblk,hdoff,hdn);
893 ifp_init_hd(&hdn);
894#else /* CNV_PCBINUM */
895 ifpwrit(dbxp,(char *)ifpbuff,(LONGX )sizeof(IFPBUFFER));
896#endif /* CNV_PCBINUM */ 
897 if (keep_head==TRUE && flag_current_seghead==FALSE) {
898    memcpy((UCHR *)&current_seghead,(UCHR *)ph,sizeof(IFPSTRU));
899    ph= &current_seghead;
900    /* O header  corrente foi convertido para formato UNIX. Como
901       vai continuar em memoria, precisa voltar para DOS
902    */
903#if TRACE_HEADER
904    printf("Convertendo para dos blk=%"_LD_" off=%"_LD_" \n",current_seghead.ifpblk,off_h);
905#endif
906    flag_current_seghead=TRUE;
907 }
908        if (reestrut_buff==TRUE ){
909          memcpy((UCHR *)&tmp,(UCHR *)&ifpbuff->buff[gbuf],sizeof(IFPSTRU));
910          next_blk=tmp.ifpblk;
911          lifp_init_buff(ifpbuff,next_blk);
912          memcpy((UCHR *)&ifpbuff->buff[0],(UCHR *)&tmp,sizeof(IFPSTRU));
913          gbuf=0;
914          pb=(IFPSTRU *)&ifpbuff->buff[gbuf];
915      }
916 if (keep_head==TRUE)gbuf=0;
917}
918/*-----------------------------------------------------------------------*/
919#if CICPP
920void CIIFL :: get_room_for (int     qt,
921                            BOOLEAN opt_keep_head)
922#else /*CICPP*/
923static void get_room_for (qt,opt_keep_head)
924int qt;
925BOOLEAN opt_keep_head;
926#endif /*CICPP*/
927{
928 if (idxpst+qt-1>MAXPSTS+1 ) {
929    if (BUFFER_FULL) {
930       write_buffers(opt_keep_head,TRUE);
931       gbuf++;
932       }else {
933         gbuf++;
934     }
935    next_blk++;
936    idxpst=0;
937    pb=(IFPSTRU *)&ifpbuff->buff[gbuf];
938 }
939}
940/*-----------------------------------------------------------------------*/
941#if CICPP
942void CIIFL :: lifp_upd_pst_header(IFPSTRU *p,
943                                  INFO     offset,
944                                  INFO     nxtb,
945                                  INFO     nxtp,
946                                  INFO     totp,
947                                  INFO     segp,
948                                  INFO     segc)
949#else /*CICPP*/
950static void  lifp_upd_pst_header(p, offset,nxtb,nxtp,totp,segp,segc)
951IFPSTRU *p;
952INFO offset;
953INFO nxtb,nxtp,totp,segp,segc;
954#endif /*CICPP*/
955{
956 IFPHEAD *head;
957 head=(IFPHEAD *)&p->ifprec[offset];
958 head->ifpnxtb=nxtb;
959 head->ifpnxtp=nxtp;
960 head->ifptotp=totp;
961 head->ifpsegp=segp;
962 head->ifpsegc=segc;
963#if CNV_PCBINUM
964    ifp_ins_new_hd(p->ifpblk, offset,hdblk,hdoff, IFLmaxhd,&hdn);
965#endif
966}
967/*-----------------------------------------------------------------------*/
968#if CICPP
969void CIIFL :: lifp_init_counters()
970#else /*CICPP*/
971static void lifp_init_counters()
972#endif /*CICPP*/
973{
974    nxtb=0;
975    nxtp=0;
976    segc=0;
977    segp=0;
978    totp=0;
979    npst=0;
980}
981#endif /* !LIND */
982/*------------------------------------------------------------------------*/
983#if CICPP
984void CIIFL :: init_invp_roots_nodes_leaves(INVMAP *invp)
985#else /*CICPP*/
986static void   init_invp_roots_nodes_leaves(invp)
987INVMAP *invp;
988#endif /*CICPP*/
989{
990  L0STRU *l0p;
991  N0STRU *n0p;
992  char keytmp[1];/* Somente para chamar create_root */
993  int treecase;
994  PUNT esq,dir;
995  keytmp[0]='\0';
996  /* Inicializa elementos "brancos" para os dois tipos de nos e
997     folhas
998 */
999  memset(init_leaf_el1.key,' ',LE1);
1000  init_leaf_el1.info1=(INFO )0;
1001  init_leaf_el1.info2=(INFO )0;
1002  memset(init_leaf_el2.key,' ',LE2);
1003  init_leaf_el2.info1=(INFO )0;
1004  init_leaf_el2.info2=(INFO )0;
1005  memset(init_node_el1.key,' ',LE1);
1006  init_node_el1.punt=(INFO )0;
1007  memset(init_node_el2.key,' ',LE2);
1008  init_node_el2.punt=(INFO )0;
1009  /* Inicializa as duas arvores do dicionario
1010  */
1011  for (treecase=0;treecase<2;treecase++) {
1012#if LKXONLY
1013    if (treecase == 0) if (lkxonly & 2) continue;
1014    if (treecase == 1) if (lkxonly & 1) continue;
1015#endif
1016   if (treecase==0) l0p=(L0STRU *)&l1node;
1017            else    l0p=(L0STRU *)&l2node;
1018   l0p->ock=0;
1019   l0p->ps=0;
1020#if LIND
1021   l0p->psb=0;
1022#endif /* LIND */
1023   l0p->it=treecase+1;
1024   l0p->pos=1;
1025   invp->cn[treecase].fmaxpos=1;
1026 }
1027  /* Cria as duas primeiras raizes das arvores
1028     colocando o primeira chave como Branca e
1029     inicializa a pilha onde aponta para os niveis
1030     da arvore criados
1031  */
1032  for (treecase=0;treecase<2;treecase++) {
1033#if LKXONLY
1034    if (treecase == 0) if (lkxonly & 2) continue;
1035    if (treecase == 1) if (lkxonly & 1) continue;
1036#endif
1037    n0p=(N0STRU *)&load_idx[treecase].idx_node[0];
1038    dir=0;
1039    esq=invp->cn[treecase].fmaxpos;
1040    lifp_create_root(invp,n0p,-esq,(char *)keytmp,dir,treecase,TRUE);
1041    load_idx[treecase].top=0;
1042  }
1043}
1044/*------------------------------------------------------------------------*/
1045#if CICPP
1046void CIIFL :: lifp_init_leaf(L0STRU *lp,
1047                             int     treecase)
1048#else /*CICPP*/
1049static void lifp_init_leaf(lp,treecase)
1050L0STRU *lp;
1051int treecase;
1052#endif /*CICPP*/
1053{
1054  L1STRU *l1p;
1055  L2STRU *l2p;
1056  int i;
1057  l1p=(L1STRU *)lp;
1058  l2p=(L2STRU *)lp;
1059  for (i=0;i<TWORDF;i++){ /* indice comeca de zero*/
1060        if (treecase == 0 ) {
1061      l1p->idx[i]=init_leaf_el1;
1062    }
1063    else {
1064      l2p->idx[i]=init_leaf_el2;
1065        }
1066  }
1067}
1068/*------------------------------------------------------------------------*/
1069#if CICPP
1070void CIIFL :: lifp_init_node(N0STRU *np,
1071                             int     treecase)
1072#else /*CICPP*/
1073static void lifp_init_node(np,treecase)
1074N0STRU *np;
1075int treecase;
1076#endif /*CICPP*/
1077{
1078  N1STRU *n1p;
1079  N2STRU *n2p;
1080  int i;
1081  n1p=(N1STRU *)np;
1082  n2p=(N2STRU *)np;
1083  for (i=0;i<TWORDN;i++){ /* indice comeca de zero*/
1084    if (treecase == 0 ) {
1085      n1p->idx[i]=init_node_el1;
1086    }
1087    else {
1088      n2p->idx[i]=init_node_el2;
1089    }
1090  }
1091}
1092/* -----------------------------------------------------------------------
1093 .Criar uma nova raiz
1094 .Se first=true cria a raiz com apenas um elemento igual a branco
1095   (Isto corresponde a inicializar o arquivo invertido).
1096 .Se first=false cria uma nova raiz que contem oprimeiro elemento branco
1097  e o segundo elemento a chave promovida de elementos de um nivel mais baixo
1098 -------------------------------------------------------------------------*/
1099#if CICPP
1100void CIIFL :: lifp_create_root(INVMAP *invp,
1101                      N0STRU *n0p,
1102                      PUNT    esq,
1103                      char   *key,
1104                      PUNT    dir,
1105                      int     treecase,
1106                      BOOLEAN first)
1107#else /*CICPP*/
1108static void lifp_create_root(invp,n0p,esq,key,dir,treecase,first)
1109INVMAP *invp;
1110N0STRU *n0p;
1111PUNT esq;
1112char *key;
1113PUNT dir;
1114int treecase;
1115BOOLEAN first;
1116#endif /*CICPP*/
1117{
1118 N1STRU *n1p;
1119 N2STRU *n2p;
1120 PUNT nodenumber;
1121 int keysize,ind;
1122 n1p=(N1STRU *)n0p;
1123 n2p=(N2STRU *)n0p;
1124 lifp_init_node(n0p,treecase);
1125 keysize=vlex[treecase];
1126 nodenumber=invp->cn[treecase].nmaxpos+1;
1127 invp->cn[treecase].nmaxpos++;
1128 n0p->it =treecase+1;
1129 n0p->pos = nodenumber;
1130 n0p->ock =2;
1131 if (first==TRUE)n0p->ock=1;
1132 ind=0;
1133 if (treecase == 0) {
1134   n1p->idx[ind]=init_node_el1;    /* Nao e necess. pq foi inicilizado*/
1135   n1p->idx[ind].punt=esq;         /* altera apontador */
1136 }
1137 else {
1138   n2p->idx[ind]=init_node_el2;    /* Nao e necess. pq foi inicilizado*/
1139   n2p->idx[ind].punt=esq;         /* altera apontador */
1140 }
1141 if (first==FALSE) {
1142   ind++;
1143   if (treecase == 0) {
1144     memcpy(n1p->idx[ind].key,key,keysize);
1145     n1p->idx[ind].punt=dir;
1146   }
1147   else {
1148     memcpy(n2p->idx[ind].key,key,keysize);
1149     n2p->idx[ind].punt=dir;
1150   }
1151 }
1152#if  TRACELOAD
1153   printf("\n Vai impirmir a raiz criada ");
1154   upif_print_node(n0p);
1155#endif
1156}
1157/* -----------------------------------------------------------------------*/
1158#if CICPP
1159BOOLEAN CIIFL :: lifp_insert_leaf(DBXSTRU *dbxp,
1160                                  char *key,
1161                                  char *p_b_key,
1162                                  PUNT *p_b_punt,
1163                                  int   treecase,
1164                                  INFX  info1,
1165                                  INFO  info2)
1166#else /*CICPP*/
1167static BOOLEAN lifp_insert_leaf(dbxp,key,p_b_key,p_b_punt,treecase,info1,info2)
1168DBXSTRU *dbxp;
1169char *key;
1170char *p_b_key;
1171PUNT *p_b_punt;
1172 int treecase;
1173INFX info1;
1174INFO info2;
1175#endif /*CICPP*/
1176{
1177 INVMAP *invp;
1178 PUNT leafnumber;
1179 int ock,keysize;
1180 L1IDXE leaf_el1;
1181 L2IDXE leaf_el2;
1182 L0STRU *l0p;
1183 invp=DBXifmap;
1184 keysize=vlex[treecase];
1185 if (treecase == 0) {
1186   memcpy(leaf_el1.key,key,keysize);
1187   leaf_el1.info1=info1;
1188   leaf_el1.info2=info2;
1189#if LIND
1190   leaf_el1.info3info4.info3=tlcinfo3;
1191#endif /* LIND */
1192   l0p=(L0STRU *)&l1node;
1193   l1p=(L1STRU *)&l1node;
1194 }
1195 else {
1196   memcpy(leaf_el2.key,key,keysize);
1197   leaf_el2.info1=info1;
1198   leaf_el2.info2=info2;
1199#if LIND
1200   leaf_el2.info3info4.info3=tlcinfo3;
1201#endif /* LIND */   
1202   l0p=(L0STRU *)&l2node;
1203   l2p=(L2STRU *)&l2node;
1204 }
1205 ock=l0p->ock;
1206 if (ock<TWORDF){
1207   if (treecase == 0) {
1208      l1p->idx[ock] = leaf_el1;    /* indice comeca de 0 */
1209   }
1210   else {
1211      l2p->idx[ock] = leaf_el2;
1212   }
1213   l0p->ock++;                    /* Atualiza ocorrencias       */
1214#if TRACELOAD
1215   printf("\n<insert_leaf> Apos insercao ");
1216   upif_print_leaf(l0p);
1217#endif
1218  return (FALSE);                          /* Nao precisou fazer split   */
1219 }
1220 /* Nao cabe na pagina.
1221    Grava a pagina atual.
1222    Inicializa nova pagina.
1223  */
1224 l0p->ps=invp->cn[treecase].fmaxpos+1;
1225 leafwrit(dbxp,l0p);
1226 invp->cn[treecase].fmaxpos++;
1227 leafnumber=invp->cn[treecase].fmaxpos;
1228 lifp_init_leaf(l0p,treecase);
1229 l0p->ock=1;
1230 l0p->it=treecase+1;
1231 l0p->pos=leafnumber;
1232 l0p->ps=0;                  /* Supoe que e a ultima */
1233#if LIND
1234 l0p->psb=leafnumber-1;
1235#endif /* LIND */
1236 ock=0;                    /* O prinmeiro elemento esta na posicao 0 */
1237 if (treecase == 0 ) {
1238     l1p->idx[ock]=leaf_el1;
1239   }
1240   else {
1241     l2p->idx[ock]=leaf_el2;
1242   }
1243#if TRACELOAD
1244   printf("\n<insert_leaf> Apos insercao na nova ");
1245   upif_print_leaf(l0p);
1246#endif
1247 /* Retorna o primeiro item da nova pagina  ser promovido */
1248 if (treecase == 0) {
1249    memcpy(p_b_key,l1p->idx[0].key,keysize);
1250 }
1251 else {
1252    memcpy(p_b_key,l2p->idx[0].key,keysize);
1253 }
1254 *p_b_punt= -leafnumber;  /* numero da nova folha inserida */
1255 return(TRUE);
1256}
1257/*-------------------------------------------------------------------------
1258 lifp_insert_node:
1259/*-------------------------------------------------------------------------*/
1260#if CICPP
1261BOOLEAN CIIFL :: lifp_insert_node (DBXSTRU *dbxp,
1262                                   N0STRU  *n0p,
1263                                   int      treecase,
1264                                   int      level,
1265                                   int      isroot,
1266                                   UCHR    *b_key,
1267                                   PUNT     b_punt,
1268                                   UCHR    *p_key,
1269                                   PUNT    *p_punt)
1270#else /*CICPP*/
1271static BOOLEAN lifp_insert_node (dbxp,n0p,treecase,level,isroot,
1272                        b_key,b_punt,p_key,p_punt)
1273DBXSTRU *dbxp;
1274N0STRU *n0p;
1275int treecase;
1276int level;
1277int isroot;
1278UCHR *b_key;
1279PUNT b_punt;
1280UCHR *p_key;
1281PUNT *p_punt;
1282#endif /*CICPP*/
1283{
1284 INVMAP *invp;
1285 UWORD ock;
1286 PUNT nodenumber;
1287 int keysize;
1288 static N1STRU *n1p;
1289 static N2STRU *n2p;
1290 N1IDXE no1;
1291 N2IDXE no2;
1292 invp=DBXifmap;
1293 keysize=vlex[treecase];
1294 no1=init_node_el1;
1295 no2=init_node_el2;
1296 if (treecase == 0){
1297   memcpy(no1.key,b_key,keysize);
1298   no1.punt=b_punt;
1299 }
1300 else {
1301   memcpy(no2.key,b_key,keysize);
1302   no2.punt=b_punt;
1303 }
1304 n1p=(N1STRU *)n0p;
1305 n2p=(N2STRU *)n0p;
1306 ock = n0p->ock;        /* Ock comeca de 1 e indice de 0 */
1307 if (ock < TWORDN) {            /* Cabe na pagina */
1308    if (treecase == 0) {
1309      n1p->idx[ock] = no1;
1310   }
1311   else {
1312      n2p->idx[ock] = no2;
1313   }
1314   ock++;
1315   n0p->ock++;         /* Atualiza ocorrencias       */
1316#if TRACELOAD
1317   printf("\n<insert_node> Apos insercao ");
1318   upif_print_node(n0p);
1319#endif
1320   return (FALSE);    /* Nao precisou fazer split   */
1321 }
1322 /* Nao cabe na pagina.
1323    grava a atual e
1324    inicializa uma nova pagina
1325  */
1326 nodenumber= invp->cn[treecase].nmaxpos+1; /* Proxima posicao livre de idx */
1327 invp->cn[treecase].nmaxpos++;
1328 last_root=n0p->pos; /* Sera usada para criar uma nova raiz */
1329 nodewrit(dbxp,n0p,level,isroot);
1330 lifp_init_node(n0p,treecase);
1331 n0p->ock=1;
1332 n0p->it=treecase+1;
1333 n0p->pos=nodenumber;
1334 ock=0; /* indice comeca de zero */
1335 if (treecase == 0) {
1336     n1p->idx[ock] = no1;
1337 }
1338 else {
1339      n2p->idx[ock] = no2;
1340 }
1341#if TRCBTREE
1342  printf("\n<insert_node> Apos insercao ");
1343   upif_print_node(n0p);
1344#endif
1345 /* Retorna o primeiro item da nova pagina  ser promovido */
1346 if (treecase == 0) {
1347    memcpy(p_key,n1p->idx[0].key,keysize);
1348 }
1349 else {
1350    memcpy(p_key,n2p->idx[0].key,keysize);
1351 }
1352 *p_punt=nodenumber;                   /* numero da folha definida  ??*/
1353 return(TRUE);
1354}
1355/*-----------------------------------------------------------------*/
1356#if CICPP
1357void CIIFL :: lifp_store_btree(UCHR *key,
1358                               INFX  blk,
1359                               INFO  off,
1360                               int   treecase)
1361#else /*CICPP*/
1362static void lifp_store_btree(key,blk,off,treecase)
1363UCHR *key;
1364INFX blk;
1365INFO off;
1366int treecase;
1367#endif /*CICPP*/
1368{
1369  keysize=vlex[treecase];
1370   promoted=lifp_insert_leaf(
1371            dbxp,(char *)key,(char *)p_b_key,&p_b_punt,treecase,blk,off);
1372  topo=load_idx[treecase].top;
1373  isroot=FALSE;
1374  /* Sempre que houver uma promocao devera ser inserida sucessivamente
1375     nos nos dos indices.
1376  */
1377  for (level=0; level<=topo && promoted==TRUE; level++){
1378     memcpy(key,p_b_key,keysize);
1379     key_punt=p_b_punt;
1380     n0p=(N0STRU *)&(load_idx[treecase].idx_node[level]);
1381#if TRACELOAD
1382     upif_chgtostr(p_b_key,keysize,tkey); /* AOT 23/10/93 */
1383     printf("\nfnd Vai promover para node=%p keypunt=%"_LD_" key=%s",
1384                                n0p,key_punt,tkey);
1385#endif
1386      promoted=lifp_insert_node(dbxp,n0p,treecase,level,isroot,
1387                                                  key,key_punt,
1388                                                  p_b_key,&p_b_punt);
1389  } /* for  */
1390        /* se houve promocao ate a raiz cria outra raiz           */
1391        /* o ultimo o elemento retirado da pilha a raiz           */
1392  if (promoted==TRUE){
1393    memcpy(key,p_b_key,keysize);
1394    load_idx[treecase].top++;
1395    topo=load_idx[treecase].top;
1396    if (topo>=MAX_TREE_LEVEL) fatal("MAX_TREE_LEVEL/overflow");
1397    level=topo;
1398    n0p=(N0STRU *)&(load_idx[treecase].idx_node[topo]);
1399#if TRACELOAD
1400     upif_chgtostr(p_b_key,keysize,tkey); /* AOT 23/10/93 */
1401     printf("\n[Vai virar raiz]Vai promover para node=%"_LD_" keypunt=%"_LD_" key=%s",
1402                                n0p,key_punt,tkey);
1403#endif
1404    memcpy(key,p_b_key,keysize);
1405    key_punt=p_b_punt;
1406    lifp_create_root(invp,n0p,last_root,(char *)key,key_punt,treecase,FALSE);
1407  }
1408}
1409/*--------------------------------------------------------------------------*/
1410/* Precisa  gravar controles e todos os ultimos registros dos buffers
1411   aqui isroot deve ser true para o topo */
1412/* Precisa testar se foi a folha tem algum dado para gravar e
1413   acertar o CNT .
1414   Inicialmente o fmaxpos e nmaxpos aponta para 1. Porem pode
1415   acontecer dde nao ter tido nenhuma ocorrencia e entao precisa
1416   voltar a pontar par 0.
1417*/
1418#if CICPP
1419void CIIFL :: lifp_close_tree()
1420#else /* CICPP */
1421static void lifp_close_tree()
1422#endif /* CICPP */
1423{
1424   BOOLEAN treecase_occ[2];
1425   for (treecase=0;treecase<2;treecase++) {
1426#if LKXONLY
1427    if (treecase == 0) if (lkxonly & 2) continue;
1428    if (treecase == 1) if (lkxonly & 1) continue;
1429#endif
1430        if (treecase==0){
1431           l0p=(L0STRU *)&l1node;
1432           l1p=(L1STRU *)l0p;
1433          }else {
1434           l0p=(L0STRU *)&l2node;
1435           l2p=(L2STRU *)l0p;
1436        }
1437        treecase_occ[treecase]=TRUE;
1438        if(l0p->ock==0) {
1439          if (invp->cn[treecase].fmaxpos == 1 ) {
1440                invp->cn[treecase].fmaxpos=0;
1441                invp->cn[treecase].nmaxpos=0;
1442                treecase_occ[treecase]=FALSE;
1443          }else {
1444                fatal("lifp_close_tree/1");
1445          }
1446        }else {
1447           leafwrit(dbxp,l0p);
1448        }
1449 }
1450   for (treecase=0;treecase<2 ;treecase++){
1451#if LKXONLY
1452    if (treecase == 0) if (lkxonly & 2) continue;
1453    if (treecase == 1) if (lkxonly & 1) continue;
1454#endif
1455     if(treecase_occ[treecase]==TRUE ){
1456       topo=load_idx[treecase].top;
1457       isroot=FALSE;
1458       for (i=0;i<=topo;i++){
1459          if(i==topo) isroot=TRUE;
1460          n0p=(N0STRU *)&(load_idx[treecase].idx_node[i]);
1461          nodewrit(dbxp,n0p,topo,isroot);
1462       }
1463     }
1464   }
1465}
1466#if !LIND
1467/*--------------------------------------------------------------------*/
1468#if CICPP
1469void CIIFL :: lifp_grava_ifp(void)
1470#else /* CICPP */
1471static void lifp_grava_ifp()
1472#endif /* CICPP */
1473{
1474    BOOLEAN reestrut_buff;
1475      /* Atualiza o primeiro registro do arquivo */
1476        key_blk=pn.nxtb;
1477        key_pos=pn.nxtp;
1478        if (flag_first_seghead==TRUE) {
1479           firsthead=(IFPHEAD *)&pf->ifprec[off_f];
1480           firsthead->ifptotp+=npst;
1481#if CNV_PCBINUM
1482           ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1483#endif
1484        }
1485/*      lifp_upd_pst_header(ph,key_pos,nxtb,nxtp,npst,npst,npst); */
1486        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,npst,npst,npst);  /*19-02-95*/
1487#if TRCPST
1488        printf("\nkey_ant=%s blk=%"_LD_" pos=%"_LD_" pst=%d",key_ant,
1489                key_blk,key_pos,npst);
1490#endif
1491        /* Carrega dicionario passando (key_ant,key_blk,key_pos); */
1492        /* Esta parte esta ineficiente por causa da quebra */
1493        if (*key_ant !='\0')
1494             lifp_store_btree(key_ant,key_blk,key_pos,treecase_ant);
1495        reestrut_buff=FALSE;
1496        if (flag_first_seghead ==TRUE || flag_current_seghead==TRUE) {
1497           if (gbuf>0) reestrut_buff=TRUE;
1498           write_buffers(DONT_KEEP_HEADERS,reestrut_buff);
1499        }
1500        if (flag_current_seghead==TRUE) {
1501#if CNV_PCBINUM
1502#if TRCBUFF
1503 printf("\n [PH]");
1504#endif
1505           ifp_ins_new_hd(ph->ifpblk, off_h,hdblk,hdoff, IFLmaxhd,&hdn);
1506           ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1507#else /* CNV_PCBINUM */
1508           ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU));
1509#endif /* CNV_PCBINUM */ 
1510           flag_current_seghead=FALSE;
1511        }
1512        if (flag_first_seghead==TRUE) {
1513#if CNV_PCBINUM
1514#if TRCBUFF
1515 printf("\n [PF]");
1516#endif
1517           ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1518           ifpwrit(dbxp,(char *)pf,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1519#else /* CNV_PCBINUM */
1520           ifpwrit(dbxp,(char *)pf,(LONGX )sizeof(IFPSTRU));
1521#endif /* CNV_PCBINUM */
1522           flag_first_seghead=FALSE;
1523        }
1524              /* acho que tem zer log no inicio apos setar os pn*/
1525        get_room_for(IDXHEADSIZE + PSTSIZE,DONT_KEEP_HEADERS);
1526       lifp_upd_first_rec(&pn,next_blk,idxpst);
1527}
1528/*------------------------------------------------------------------------*/
1529#if CICPP
1530void CIIFL :: lifp_storepst(void)
1531#else /* CICPP */
1532static void lifp_storepst()
1533#endif /* CICPP */
1534{
1535    if (strcmp((CONST char *)key_ant,(CONST char *)key)!=0 ) {
1536        lifp_grava_ifp();
1537        /* guarda onde comeca o primeiro registro  */
1538       ph= &ifpbuff->buff[gbuf];
1539       off_h=idxpst;
1540       lifp_init_counters();
1541       lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segp,segc);
1542       idxpst=idxpst + IDXHEADSIZE;
1543       treecase_ant=treecase;
1544       strcpy((char *)key_ant,(CONST char *)key);
1545  }
1546 /*  if (npst > MAXPSTSSEG) { */
1547  if (npst > MAXPSTSSEG-1) {    /*19-02-95*/
1548     get_room_for(IDXHEADSIZE + PSTSIZE,KEEP_HEADERS);
1549     nxtb=next_blk;
1550     nxtp=idxpst;
1551     segc=npst;
1552     segp=npst;
1553     totp=npst;
1554     if (flag_first_seghead==FALSE ) {
1555        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segp,segc);
1556        memcpy((UCHR *)pf,(UCHR *)ph,sizeof(IFPSTRU));
1557        flag_first_seghead=TRUE;
1558        flag_current_seghead=FALSE; /*19-02-95*/
1559        off_f=off_h;
1560     }else {
1561        /* atualiza o total de postings do primeiro segmento */
1562        firsthead= (IFPHEAD *)&pf->ifprec[off_f];
1563        firsthead->ifptotp+=npst;
1564#if CNV_PCBINUMxx
1565        ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1566#endif
1567        /* Atualiza apontador do segmento atual */
1568        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segc,segp);
1569        /* Precisa gravar este header porque ele podera estar apontando
1570           para area de memoria temporaria a qual podera ser ncecessaria
1571           por um novo segment header
1572        */
1573#if CNV_PCBINUM
1574#if TRCBUFF
1575 printf("\n [PH2]");
1576#endif
1577        ifp_ins_new_hd(ph->ifpblk, off_h,hdblk,hdoff, IFLmaxhd,&hdn);
1578        ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1579#else /* CNV_PCBINUM */
1580        ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU));
1581#endif /* CNV_PCBINUM */
1582        flag_current_seghead=FALSE; /*19-02-95*/
1583        /* Inicializa o novo header */
1584     }
1585   lifp_init_counters();
1586   ph= &ifpbuff->buff[gbuf];
1587   off_h=idxpst;
1588   currenthead=(IFPHEAD *)&ph->ifprec[off_h];
1589   lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segc,segp);
1590   idxpst=idxpst+IDXHEADSIZE;
1591   }
1592    get_room_for(PSTSIZE,KEEP_HEADERS);
1593    memcpy((UCHR *)&pb->ifprec[idxpst],&pst,sizeof(POSTSTRU));
1594    idxpst=idxpst+PSTSIZE;
1595    npst++;
1596}
1597#endif /* !LIND */
1598
1599/* -----------------------------------------------------------------------*/
1600
1601#if CICPP
1602int CIIFL :: lifp_trans_key(UCHR *keyp,
1603                            int   len,
1604                            int  *treecase)
1605#else /*CICPP*/
1606static int lifp_trans_key(keyp,len,treecase)
1607UCHR *keyp;
1608int len;
1609int *treecase;
1610#endif /*CICPP*/
1611{
1612 int k,max;
1613 if (len <= 0) len=strlen((CONST char *)keyp); /* good */
1614 /* Adapta para tamanho das chaves */
1615 max= (len <= LE1)? LE1 : LE2 ;
1616 *treecase= (max == LE1)? 0: 1;
1617 for (k=len;k<max;k++) keyp[k]=' ';
1618 keyp[max]='\0';
1619 return(len);
1620}
1621/*-------------------------------------------------------------------------*/
1622
1623/*------------------------------------------------------------------------
1624  svdifload
1625  Rotina principal, em que devem ser passados o database e o arquivo que
1626  contem as chaves e atualizar a base de dados.
1627  O arquivo invertido deve estar vazio.
1628----------------------------------------------------------------------------*/
1629/*
1630        30.Nov.1998 - Author: RP
1631   -    Entrada dos dados para carga do arquivo invertido via uma base de dados
1632        ordenada;
1633   -    O parametro tell = -1, indica esta forma;
1634   -    O parametro filekeys_1 indica a base dados ordenada com as chaves curtas
1635        (LE1) primeiro e com as longas (LE2) na sequencia;
1636   -    O parametro filekeys_2 indica os dois tags necessarios para a leitura dos
1637        dados: tagkey e tagpost
1638   -    Para localizar as mudancas procure: load_type
1639*/
1640/*
1641        16.Jun.1999 - Author: RP
1642   -  Ao inv�s de trabalhar com 2 tags agora trabalha s� com 1 no formato fixo.
1643   -  Exemplo:
1644                n|key       |  mfn   | tag | occ| cnt
1645                1|CHAVE10   |12345678|12345|1234|1234
1646         2|CHAVE MAIOR QUE 10            |12345678|12345|1234|1234
1647   -    O parametro filekeys_2 indica o tag necessario para a leitura dos
1648        dados: tagkey
1649   -    Para localizar as mudancas procure: postsize
1650*/
1651
1652#if CIIFLFIX
1653#if !CICPP
1654int ciiflfix=0;                 /* key %8"_LD_" %5d %4d %4d */
1655int ciiflfim=0;                 /* key %8"_LD_" w/ ciiflfix */
1656#endif /* CICPP */
1657#endif
1658
1659#if LIND
1660#if CICPP
1661LONGX CIIFL :: svdiflind (char *dbnp,
1662                         char *filekeys_1,
1663                         char *filekeys_2,
1664                         LONGX  parmxmfn,
1665                         char *parmlogp,
1666                         int   pstflag,
1667                         LONGX  tell)
1668#else /*CICPP*/
1669LONGX svdiflind (dbnp, filekeys_1,filekeys_2,parmxmfn,parmlogp,pstflag,tell)
1670char *dbnp;
1671char *filekeys_1;
1672char *filekeys_2;
1673LONGX parmxmfn;
1674char *parmlogp;
1675int pstflag;
1676LONGX tell;
1677#endif /*CICPP*/
1678#else
1679#if CICPP
1680LONGX CIIFL :: svdifload (char *dbnp,
1681                         char *filekeys_1,
1682                         char *filekeys_2,
1683                         int   pstflag,
1684                         LONGX  tell)
1685#else /*CICPP*/
1686LONGX svdifload (dbnp, filekeys_1,filekeys_2,pstflag,tell)
1687char *dbnp;
1688char *filekeys_1;
1689char *filekeys_2;
1690int pstflag;
1691LONGX tell;
1692#endif /*CICPP*/
1693#endif
1694{
1695#if MPE || UNIX
1696 int fkeys;
1697 int mpei,mpelrecl;
1698 char mpeline[BUFSIZ];
1699 LONGX mpetag,mpeocc,mpecnt;
1700#else
1701 FILE *fkeys;
1702#endif
1703 int mpex;
1704 char *mpep;
1705 char *files[2],*filnamp;
1706 LONGX nregs[2];
1707 int nfile;
1708 LONGX mfn;
1709 unsigned short tag,occ,cnt;
1710 LONGX xtag,xocc,xcnt;  /* AOT&RP 20/05/98 */
1711 char ignora_char;
1712#if !LIND
1713 UWORD idxpst_ant;
1714 INFO next_blk_ant;
1715#endif /* !LIND */
1716 PUNT xroot;
1717 int xliv,cmp,cmp1;
1718/*POSTSTRU pst_ant_loc; */
1719 UCHR key_ant_loc[LE2+1];
1720#if CIIFLFIX
1721 char fixline[LE2+1+10+10+10+10+1+1];
1722 int n;
1723#endif
1724 char xbobk[LE2+1];
1725 int xbobl,xbobn;
1726
1727   LONGX load_type = 0L; /* RP - 30/11/98 */
1728   int tagkey;
1729   RECSTRU *recp=NULL;
1730#if !CICPP
1731   LONGX idx;
1732#endif
1733   LONGX mfnread = 0L;
1734   int dirread;
1735   char auxread[128];
1736   FFI lenread; /* RP - 30/11/98 */
1737   LONGX postsize = 25; /*              |  mfn   | tag | occ| cnt       */
1738                                                        /*      |12345678|12345|1234|1234       */
1739                        /*      1 + 8 + 1 +5+ 1+ 4+1 +4         */
1740
1741#ifdef USE_INFO_SYS
1742        UCHR ansikey[LE2*2];
1743        BOOL oper_canceled=FALSE;
1744        char mess_str[255];
1745//       char mfnstr[10];
1746//    int sys_info_open=0;
1747        UIW_STRING *procstr=NULL;
1748        UIW_PROGRESSBAR *progbar=NULL;
1749        if (wprogress) {
1750                procstr=((UIW_STRING*)wprogress->Get("PROCESSING_STRING"));
1751                progbar=((UIW_PROGRESSBAR*)wprogress->Get("PROG_BAR"));
1752                progbar->Assign(0,0);
1753                progbar->SetColor(2);
1754                }
1755#endif
1756
1757 /* Tudo que tem no arquivo invertido sera perdido.
1758  */
1759
1760   if (tell == -1L) { /* RP - 30/11/98 */
1761      load_type = tell;
1762      tell = 0L;
1763   }
1764   if (load_type == -1L) {
1765      sscanf(filekeys_2,"%d",&tagkey);
1766      if (tagkey < 1) fatal("ciifl/tagkey");
1767      filekeys_2 = filekeys_1;
1768#if CICPP
1769      try { recp = new RECSTRU(cisisxp); }
1770      catch (BAD_ALLOC) { fatal("ciifl/idx"); }
1771#else
1772      for (idx = maxnrec-1; vrecp[idx]; idx--);
1773      if (!idx) fatal("ciifl/idx");
1774      recallok(idx,BUFSIZ); /* posting + chave */
1775      recp=vrecp[idx];
1776#endif
1777   } /* RP - 30/11/98 */
1778
1779  print_step=tell;
1780  files[0]=filekeys_1;
1781  files[1]=filekeys_2;
1782  nregs[0]=0L;
1783  nregs[1]=0L;
1784  key[0]='\0';
1785  /* keyp=(UCHR *)&key; */
1786  keyp=(UCHR *)key;
1787  trmifupd=IFUPDXLD; /* TRMIFLOAD */
1788#if BEFORE_INVFLUSH
1789#else
1790  invflush(dbnp);
1791#endif
1792#if LKXONLY
1793  lkxonly=0;    /* AOT - 14/05/98 */
1794  if (strcmp(filekeys_1,"void") == 0) lkxonly|=2;
1795  if (strcmp(filekeys_2,"void") == 0) lkxonly|=1;
1796#if CICPP
1797  if (!lkxonly || lkxonly & 1) trmisis0(cisisxp, dbnp);
1798#else /* CICPP */
1799  if (!lkxonly || lkxonly & 1) trmisis0(dbnp);
1800#endif /* CICPP */
1801#else
1802  trmisis0(dbnp);
1803#endif
1804  invsetup((unsigned char *)dbnp,0L,0L,0L);
1805  dbxp=dbxstorp(dbnp);
1806  invp=DBXifmap;
1807#if RESUMOLOAD
1808   printf("\n Situacao do Arquivo Invertido Antes de Atualizar ");
1809   lifp_print_cnt(invp);
1810#endif
1811#if !AOT
1812if (tell>0) {
1813   printf("\n Entrada na svdifload tell=%"_LD_" keys1=%s keys2=%s",
1814           tell,files[0],files[1]);
1815}
1816#endif
1817   p_b_key=a_p_b_key;
1818   p_b_punt=0L;
1819   init_invp_roots_nodes_leaves(invp);
1820   ifpbuff=lifp_init(invp);
1821#if CICPP || IFLOADFUN
1822   if (ifpbuff == NULL) return(-9L);
1823#endif /* CICPP || IFLOADFUN */
1824#if LIND
1825    iyp_storinit(parmxmfn,parmlogp);
1826#endif /* LIND */
1827for ( nfile=0;nfile<2;nfile++) {
1828#ifdef USE_INFO_SYS
1829//    sys_info_open=0;
1830#endif
1831#if LKXONLY
1832    if (nfile == 0) if (lkxonly & 2) continue;
1833    if (nfile == 1) if (lkxonly & 1) continue;
1834#endif
1835 /*y*/ if (files[nfile]==NULL) goto no_file;
1836 /*y*/ if (*files[nfile]=='\0') goto no_file;
1837
1838   if (load_type == 0L) { /* RP - 30/11/98 */
1839   filnamp=dbxcipar(ifllk_gidbnp,files[nfile],'=');
1840#if MPE || UNIX
1841   fkeys=OPEN(filnamp,O_RDONLY);
1842#else
1843   fkeys=fopen(filnamp,"r");
1844#endif
1845   if(!fkeys) {
1846#if CICPP || IFLOADFUN
1847     return(-1L);
1848#else /* CICPP || IFLOADFUN */
1849     fatal(filnamp);
1850#endif /* CICPP || IFLOADFUN */
1851   }
1852   if (tell>0) {
1853#if AOT
1854#ifdef USE_INFO_SYS
1855// now in wisis.cpp
1856//     errsys->sys_info(filnamp);
1857//     sys_info_open=1;
1858#else
1859     fprintf(stderr,"+++ %s\n",filnamp);
1860#endif
1861#else
1862     printf("\n-------------------------------------------------------");
1863     printf("\nProcessando arquivo:%s",filnamp);
1864#endif
1865   }
1866   } /* RP - 30/11/98 */
1867   key[0]='\0';
1868   key_ant_loc[0]='\0';
1869   memset((char *)&pst_ant,0x00,sizeof(POSTSTRU));
1870   nlido=0L;
1871
1872#if MPE || UNIX
1873
1874#if UNIX
1875   mpelrecl=25+vlex[nfile]+1; /*        8+1 + 5+1 + 4+1 + 4+1 + LEx + lf */
1876#if CIIFLFIX
1877   if (ciiflfix)
1878      if (ciiflfim) mpelrecl-=16; /*      - ( 5+1 + 4+1 + 4+1 )          */
1879#endif
1880#else /* UNIX */
1881   mpelrecl=25+vlex[nfile]+1; /* null + 8+1 + 5+1 + 4+1 + 4+1 + LEx + lf */
1882#endif /* UNIX */
1883
1884   while (1) {
1885    if (load_type == 0L) { /* RP - 30/11/98 */
1886     mpex=CIREAD(fkeys,mpeline,mpelrecl);
1887     if (mpex == 0) break;
1888     if (mpex != mpelrecl) {
1889#if CICPP || IFLOADFUN
1890        return(-6L);
1891#endif /* CICPP || IFLOADFUN */
1892        fatal("CIIFL/read");
1893     }
1894     mpeline[mpelrecl-1]='\0';
1895     mpep=mpeline;
1896#if UNIX
1897#if CIIFLFIX
1898     if (ciiflfix) {
1899         memcpy(keyp,mpep,mpei=vlex[nfile]); mpep+=mpei;
1900         if (ciiflfim) {
1901            mpex=sscanf(mpep," %8"_LD_,&mfn); mpex+=3; mpetag=mpeocc=mpecnt=1;
1902         } else
1903                        /* por %"_LD_" para mpetag,mpeocc,mpecnt - AOT 21/05/98 */
1904        /*mpex=sscanf(mpep," %8"_LD_" %5"_LD_" %4"_LD_" %4"_LD_,&mfn,&mpetag,&mpeocc,&mpecnt);*/
1905            mpex=sscanf(mpep," %8"_LD_" %5d %4d %4d",&mfn,&mpetag,&mpeocc,&mpecnt);
1906     }
1907     else {
1908#endif
1909     /*mpex=sscanf(mpep,"%8"_LD_" %5"_LD_" %4"_LD_" %4"_LD_" ",&mfn,&mpetag,&mpeocc,&mpecnt);*/
1910         mpex=sscanf(mpep,"%8"_LD_" %5d %4d %4d ",&mfn,&mpetag,&mpeocc,&mpecnt);
1911         memcpy(keyp,mpep+25,vlex[nfile]);
1912#if CIIFLFIX
1913     }
1914#endif
1915#else /* UNIX */ 
1916                        /* por %"_LD_" para mpetag,mpeocc,mpecnt - AOT 21/05/98 */
1917     /* mpex=sscanf(mpep+1,"%8"_LD_" %5"_LD_" %4"_LD_" %4"_LD_" ",&mfn,&mpetag,&mpeocc,&mpecnt); */
1918     mpex=sscanf(mpep+1,"%8"_LD_" %5d %4d %4d ",&mfn,&mpetag,&mpeocc,&mpecnt);
1919     memcpy(keyp,mpep+25,vlex[nfile]);
1920#endif /* UNIX */
1921     if (mpex != 4) {
1922#if CICPP || IFLOADFUN
1923         return(-2L);
1924#endif /* CICPP || IFLOADFUN */
1925         printf("*** File: %s  Rec: %"_LD_" \n",filnamp,nlido+1);
1926         printf("*** %s \n",mpeline);
1927         fatal("CIIFL/invalid link record/mpe");
1928     }
1929     tag=mpetag; occ=mpeocc; cnt=mpecnt;
1930     keyp[vlex[nfile]]='\0';
1931    } else { /* RP - 30/11/98 */
1932#if CICPP
1933      recp->xrecord(files[nfile],++mfnread);
1934      if (recp->recrc == RCEOF) break;
1935      memset(keyp,' ',vlex[nfile]);
1936      dirread = recp->xfieldx(tagkey,1);
1937#else /* CICPP */
1938      record(idx,files[nfile],++mfnread);
1939      if (RECrc == RCEOF) break;
1940      memset(keyp,' ',vlex[nfile]);
1941      dirread = fieldx(idx,tagkey,1);
1942#endif /* CICPP */
1943      if (dirread < 0) fatal("ciifl/fieldx/tagkey");
1944      if (*(FIELDP(dirread)) - '1' > nfile) break;
1945      memcpy(keyp,FIELDP(dirread)+2,vlex[nfile]);
1946      keyp[vlex[nfile]] = '\0';
1947
1948      memcpy(auxread,FIELDP(dirread)+2+vlex[nfile],postsize);
1949      auxread[postsize] = '\0';
1950                sscanf(auxread,"|%8"_LD_"|%5"_LD_"|%4"_LD_"|%4"_LD_,&mfn,&xtag,&xocc,&xcnt);
1951                tag = (unsigned short)xtag;
1952                occ = (unsigned short)xocc;
1953                cnt = (unsigned short)xcnt;
1954    } /* RP - 30/11/98 */
1955     
1956#else /* MPE || UNIX */
1957#ifdef USE_INFO_SYS
1958        progbar->SetColor(nfile+1);
1959        progbar->Assign(0,0);
1960#endif
1961
1962   while (1) {
1963         if (load_type == 0L) { /* RP - 30/11/98 */
1964         if (feof(fkeys)) break;
1965   /* O teste de fim de arquivo nao funciona. Processa um
1966      registro vazio. Precisa testar se o fscanf conseguiu
1967      ler algum campo. Volta -1 quando nao le
1968   */
1969#if CIIFLFIX
1970       if (ciiflfix) {
1971        if (fgets(fixline,sizeof(fixline),fkeys) == NULL) break;
1972        memcpy(keyp,fixline,n=vlex[nfile]); keyp[n]='\0';
1973        if (ciiflfim) {
1974            mpex=sscanf(fixline+n," %8"_LD_,&mfn); mpex+=3; tag=occ=cnt=1;
1975        }
1976        else {
1977            /* %d/unsigned short nao funciona no 32bits - AOT&RP 20/05/98 */
1978            mpex=sscanf(fixline+n," %8"_LD_" %5"_LD_" %4"_LD_" %4"_LD_,&mfn,&xtag,&xocc,&xcnt);
1979        }
1980        if (mpex != 4) {
1981#if CICPP || IFLOADFUN
1982            return(-3L);
1983#else /* CICPP || IFLOADFUN */
1984            printf("*** File: %s  Rec: %"_LD_" \n",filnamp,nlido+1);
1985            printf("*** %s \n",fixline);
1986            fatal("CIIFL/invalid link record/fix");
1987#endif /* CICPP || IFLOADFUN */
1988        }
1989       }
1990       else {
1991#endif /* CIIFLFIX */
1992        if (fscanf(fkeys,"%"_LD_,&mfn) < 1)
1993            if (feof(fkeys)) break;
1994            else {
1995#if CICPP || IFLOADFUN
1996                return(-4L);
1997#else /* CICPP || IFLOADFUN */
1998                fatal("CIIFL/invalid link record/mfn");
1999#endif /* CICPP || IFLOADFUN */
2000            }
2001        fscanf(fkeys,"%"_LD_,&xtag);
2002        fscanf(fkeys,"%"_LD_,&xocc);
2003        fscanf(fkeys,"%"_LD_,&xcnt);
2004        fscanf(fkeys,"%c",&ignora_char);
2005        fscanf(fkeys,"%[^\n]\n",keyp);
2006#if CIIFLFIX
2007       }
2008#endif
2009       tag=(unsigned short)xtag;
2010       occ=(unsigned short)xocc;
2011       cnt=(unsigned short)xcnt;
2012    } else { /* RP - 30/11/98 */
2013#if CICPP
2014      recp->xrecord(files[nfile],++mfnread);
2015      if (recp->recrc == RCEOF) break;
2016      memset(keyp,' ',vlex[nfile]);
2017      dirread = recp->xfieldx(tagkey,1);
2018#else /* CICPP */
2019      record(idx,files[nfile],++mfnread);
2020      if (RECrc == RCEOF) break;
2021      memset(keyp,' ',vlex[nfile]);
2022      dirread = fieldx(idx,tagkey,1);
2023#endif /* CICPP */
2024      if (dirread < 0) fatal("ciifl/fieldx/tagkey");
2025      if (*(FIELDP(dirread)) - '1' > nfile) break;
2026      memcpy(keyp,FIELDP(dirread)+2,vlex[nfile]);
2027      keyp[vlex[nfile]] = '\0';
2028
2029      memcpy(auxread,FIELDP(dirread)+2+vlex[nfile],postsize);
2030      auxread[postsize] = '\0';
2031                sscanf(auxread,"|%8"_LD_"|%5"_LD_"|%4"_LD_"|%4"_LD_,&mfn,&xtag,&xocc,&xcnt);
2032                tag = (unsigned short)xtag;
2033                occ = (unsigned short)xocc;
2034                cnt = (unsigned short)xcnt;
2035    } /* RP - 30/11/98 */
2036#endif /* MPE || UNIX */
2037       xbobl=strlen((CONST char *)keyp); memcpy(xbobk,keyp,xbobl); xbobk[xbobl]='\0';
2038       xbobn=bobkey(xbobk,xbobl,(char *)keyp,LE2,1,1,1);
2039       lifp_trans_key(keyp,xbobn,&treecase);
2040       if (ciiflfix) if (ciiflfim) tag=occ=cnt=0; /* AOT 27/09/2001 */
2041       encodepst(&pst,mfn,tag,occ,cnt);
2042       if (!nfile && treecase || nfile && !treecase || keyp[0] <= ' ') {
2043#if CICPP || IFLOADFUN
2044             return(-5L);
2045#else /* CICPP || IFLOADFUN */
2046             printf("[%c]%s %8"_LD_" %5d %4d %4d\n",keyp[0],keyp,mfn,tag,occ,cnt);
2047             fatal("CIIFL/invalid link record/key");
2048#endif /* CICPP || IFLOADFUN */
2049       }
2050/*   compara post anterior com atual para ver se esta classificado */
2051     cmp=strcmp((CONST char *)keyp,(CONST char *)key_ant_loc);
2052     if (cmp < 0) {
2053#if CICPP || IFLOADFUN
2054        return(-7L);
2055#else /* CICPP || IFLOADFUN */
2056        fatal("CIIFL/keys not sorted");
2057#endif /* CICPP || IFLOADFUN */
2058     }
2059#if !SUNBUG_UNSIGNED
2060     cmp1=memcmp((char *)&pst,(char *)&pst_ant,sizeof(POSTSTRU));
2061     if (cmp ==0 && cmp1<0) {
2062#if CICPP || IFLOADFUN
2063        return(-8L);
2064#else /* CICPP || IFLOADFUN */
2065#if 1
2066        printf("\n+++ key    : %s",keyp);
2067        printf("\n+++ pst    : ");
2068        for (mpep=(char *)&pst,     mpex=sizeof(POSTSTRU); mpex--; mpep++)
2069               printf("%02x ",*mpep);
2070        printf("\n+++ pst_ant: ");
2071        for (mpep=(char *)&pst_ant, mpex=sizeof(POSTSTRU); mpex--; mpep++)
2072               printf("%02x ",*mpep);
2073        printf("\n+++          ");
2074#endif
2075        fatal("CIIFL/keys/postings not sorted");
2076#endif /* CICPP || IFLOADFUN */
2077     }
2078#endif /* SUNBUG_UNSIGNED */
2079#if !LIND
2080     if (pstflag==IFUPDICT) {
2081        if (cmp!=0)
2082           lifp_store_btree(keyp,1L,2L,treecase); /* carrega so chaves dif*/
2083     }else {
2084        lifp_storepst();
2085     }
2086#endif /* !LIND */
2087#if LIND
2088    iyp_storlast(cmp && nregs[nfile],key_ant_loc,pstflag);
2089    iyp_storthis(mfn,parmxmfn,keyp,nregs[nfile]+1,tag,occ,cnt);
2090#endif /* LIND */
2091     nregs[nfile]++;
2092     nlido++;
2093     if (tell > 0)
2094        if (nlido - (nlido/tell*tell)== 0)
2095#if AOT
2096#ifdef USE_INFO_SYS
2097                                {
2098//         errsys->sys_info_data(keyp); //ltoa(mfn,mfnstr,10));
2099                if (wprogress) {
2100                        LONGX int prog_pos=ftell(fkeys);
2101                        int fhandle=fileno(fkeys);
2102                        LONGX fleng=filelength(fhandle);
2103                        ISIS_OemToAnsi(key,ansikey);
2104                        if (!nfile)
2105                                sprintf(mess_str,"%s %s",mess->get(424),keyp);
2106                        else
2107                                sprintf(mess_str,"%s %s",mess->get(425),keyp);
2108                        procstr->DataSet(mess_str);
2109                        progbar->Assign(prog_pos,fleng);
2110        //              ((UIW_STRING*)wprogress->Get("PHASE_STRING"))->DataSet(NULL);
2111                        UI_EVENT event,event1,event2;
2112                        wprogress->eventManager->Get(event1,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2113                        wprogress->windowManager->Event(event1);
2114                        wprogress->eventManager->Get(event2,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2115                        wprogress->windowManager->Event(event2);
2116                        wprogress->eventManager->Get(event,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2117                        if (event.type==10235 || event1.type==10235 || event2.type==10235) {            // EXPORT_CANCEL) {
2118                                        int ok=errsys->ErrorMessage(wprogress->windowManager,WOS_INVALID,mess->get(420));
2119                                        if (ok==WOS_INVALID) {
2120                                                oper_canceled=TRUE;
2121                                                break;
2122                                                }
2123                                        }
2124                        wprogress->windowManager->Event(event);
2125                        }
2126                }
2127#else
2128           fprintf(stderr,"+++ %"_LD_" %s\n",nlido,keyp);
2129#endif
2130#else
2131           printf("\n Rec:%"_LD_" Key:%s",nlido,keyp);
2132#endif
2133     strcpy((char *)key_ant_loc,(CONST char *)keyp);
2134     memcpy((char *)&pst_ant,(char *)&pst,sizeof(POSTSTRU));
2135  }/*while*/
2136#if LIND
2137    iyp_storlast(nregs[nfile],key_ant_loc,pstflag);
2138#endif /* LIND */
2139 if (load_type == 0L) { /* RP - 30/11/98 */
2140#if MPE || UNIX
2141  CLOSE(fkeys);
2142#else
2143  fclose(fkeys);
2144#endif
2145 } else {
2146        mfnread--;
2147 }/* RP - 30/11/98 */
2148  /* Esta parte e para forcar a mudar de segmento quando comeca a arvore do
2149         tipo 2. Isto e para deixar compativel com ISIS. Nao existe nenhum
2150         motivo serio fazer essa compatibilizacao
2151 */
2152 /*y*/ no_file:
2153
2154#ifdef USE_INFO_SYS
2155// now in wisis.cpp
2156//     if (sys_info_open) errsys->sys_info_close();
2157#endif
2158#if !LIND
2159    /* Deve verificar se o arquivo .lk2 nao esta' vazio - AOT 950720 */
2160    if (nfile/*treecase*/==0) {  /* So vale qdo muda da arvore 1 para 2 */
2161       { /* Ainda nao comeca em novo bloco */
2162          if (idxpst+(IDXHEADSIZE + PSTSIZE)-1 > MAXPSTS+1) {
2163            /* O algoritmo ja vai quebrar */
2164          }else {
2165            idxpst=MAXPSTS+1; /* forcar mudanca de bloco */
2166          }
2167       }
2168    }
2169#endif /* !LIND */
2170    ;  /* !LIND - label: ; */
2171#ifdef USE_INFO_SYS
2172        if (oper_canceled)
2173                break;  // exit!!
2174#endif
2175
2176}/*for */
2177
2178#if !LIND
2179/* Serao guardados idxpst e next_blk porque sera forcada a entrada de uma
2180   "falsa chave" para gravar o buffer .
2181   Na gravacao do buffer, next_blk e idxpst serao alterados. Serao guardados
2182   para atualizar o registro de controle [pn].
2183   O que e' feito pelo ISIS parece incoerente. Quando muda de arquivo com
2184   chaves do tipo 1 para o arquivo com chaves do tipo 2  muda
2185   de bloco.   Quando terminar o segundo arquivo acho que tambem deveria
2186   mudar, porem nao faz.
2187*/
2188    idxpst_ant =idxpst;
2189    next_blk_ant=next_blk;
2190    idxpst=MAXPSTS;
2191    gbuf=MAXIFPMEM-1;
2192    lifp_grava_ifp();
2193/*y*/
2194    /* Caso nao teve nenhum link do tipo 2, precisa acertar o next_blk_ant e
2195       idxpst_ant
2196    */
2197    if (idxpst_ant>MAXPSTS){
2198       idxpst_ant=0;
2199       next_blk_ant++;
2200    }
2201/*y*/
2202    lifp_upd_first_rec(&pn,next_blk_ant,idxpst_ant);
2203#if TRACELOAD
2204    printf ("\n pn=%"_LD_" %"_LD_" %"_LD_" ",pn.ifpblk,pn.nxtb,pn.nxtp);
2205#endif
2206#if CNV_PCBINUM
2207    ifpwrit(dbxp,(char *)&pn,(LONGX )sizeof(IFPAVAILPOS),hdblk,hdoff,hdn);
2208#else /* CNV_PCBINUM */ 
2209    ifpwrit(dbxp,(char *)&pn,(LONGX)sizeof(IFPAVAILPOS));
2210#endif /* CNV_PCBINUM */ 
2211#endif /* !LIND */
2212
2213#if CORRECAO_SINDO
2214/*
2215        Nao ativei porque existe a possibilidade de o proprio ifupd/ciifu
2216        gerar (pn.nxtp==0)
2217       
2218        Ja' alterei a postread para retornar um bloco vazio no EOF; mas
2219        mesmo assim a ciifu nao trata a seguinte situacao gerada pelo
2220        MicroISIS:
2221                x com 60 registros
2222                x.fst=1 0 'chave'               -> gera 1 blk cheio
2223                isis/i/x/f                      -> full I/F (ctrl=1/127)
2224                mx tmp append=x now count=1     -> cria #61
2225                ifupd x fst=@x.fst              -> atualiza (errado)
2226                ifkeys x                        -> mostra bug (32 postings!)
2227        AOT
2228*/
2229/* 20-07-95  Inicio */
2230/*Sempre que  a proxima posicao disponivel estiver no inicio
2231 de um   bloco vazio, isto e, (pn.nxtp==0),
2232 e' necessario gravar um registro ifp. Caso contrario
2233 a rotina "postread" da' erro de leitura quando for
2234 ler esse bloco pois nao consegue ler 512 bytes.
2235*/
2236   if (pn.nxtp==0) {
2237     pb=(IFPSTRU *)&ifpbuff->buff[0];
2238     lifp_init_ifprec(pb,pn.nxtb);
2239#if CNV_PCBINUM
2240     /* Nao tem nada para converter */
2241     ifpwrit(dbxp,(char *)pb,(LONGX)sizeof(IFPSTRU),hdblk,hdoff,(-1));
2242#else /* CNV_PCBINUM */ 
2243     ifpwrit(dbxp,(char *)pb,(LONGX)sizeof(IFPSTRU));
2244#endif /* CNV_PCBINUM */ 
2245   }
2246/* 20-07-95  fim */
2247#endif
2248
2249   lifp_close_tree();
2250
2251/* Resumo das operacoes efetuadas */
2252#if RESUMOLOAD
2253   printf("\n Quantidade de Chaves Processadas");
2254   printf("\n   %s:%"_LD_,\n   %s:%"_LD_"\n   Total:%"_LD_"\n",
2255          files[0],nregs[0],files[1],nregs[1],nregs[0]+nregs[1]);
2256   lifp_print_cnt(invp);
2257#endif
2258
2259#if LIND
2260    iyp_storclos();
2261#endif /* LIND */
2262#if CICPP
2263    if (ifpbuff) delete[] ifpbuff;
2264#else /* CICPP */
2265    if (ifpbuff) FREE(ifpbuff); /* AOT - 16/09/93 */
2266#endif /* CICPP */
2267
2268    /* Faz balanceamento da arvore */
2269    if (ifl_balan) {
2270        for (treecase=0;treecase<2;treecase++) {
2271#if LKXONLY
2272    if (treecase == 0) if (lkxonly & 2) continue;
2273    if (treecase == 1) if (lkxonly & 1) continue;
2274#endif
2275            xroot=invp->cn[treecase].posrx;
2276            xliv=invp->cn[treecase].liv;
2277            balance_btree(dbxp,invp,xliv,xroot,treecase);
2278        }
2279    }
2280
2281    cntwrit(dbxp);
2282    invflush(dbnp);
2283
2284    trmifupd=0; /* reset IFUPDXLD */
2285
2286#ifdef USE_INFO_SYS
2287        if (oper_canceled)
2288                return (-100);
2289#endif
2290
2291    if (recp) { /* RP - 30/11/98 */
2292#if CICPP
2293        delete recp;
2294#else /* CICPP */
2295        FREE(vrecp[idx]); vrecp[idx] = NULL; nrecs--;
2296#endif /* CICPP */
2297    }
2298
2299    return(nregs[0]+nregs[1]);
2300}
2301
2302/*---------------------------------------------------------------------------
2303  svdifmerg - I/F merge: load a b-tree from existing I/F's
2304              AOT, 25/11/95
2305----------------------------------------------------------------------------*/
2306#if !CICPP
2307LONGX svdifmerg (dbnp,vifnamp,vifmfns,parmxmfn,parmlogp,pstflag,tell)
2308char *dbnp;
2309char *vifnamp[];
2310LONGX vifmfns[];
2311LONGX parmxmfn;
2312char *parmlogp;
2313int pstflag;
2314LONGX tell;
2315{
2316 LONGX nregs[2];
2317 int nfile;
2318 LONGX mfn;
2319 unsigned short tag,occ,cnt;
2320#if !LIND
2321 UWORD idxpst_ant;
2322 INFO next_blk_ant;
2323#endif /* !LIND */
2324 PUNT xroot;
2325 int xliv,cmp,cmp1;
2326 UCHR key_ant_loc[LE2+1];
2327 char xbobk[LE2+1];
2328 int xbobl,xbobn;
2329
2330 int nifs;                      /* no of I/Fs to merge */
2331 LONGX vifoff[MAXIFMRG];                /* posting's MFN offset */
2332 LONGX vtidx[MAXIFMRG];         /* index of vtrmp[] */
2333 int vkuse[MAXIFMRG];           /* to flag a key is to be merged */
2334 int nkuse;                     /* no of vkuse[] active elements */
2335 char *usekp;                   /* current key ptr */
2336 int xif;                       /* I/F index */
2337
2338 TRMSTRU *trmp;
2339 LONGX itrm;
2340 LONGX nlids[2];
2341 int lex,n;
2342 char *p;
2343
2344#if !LIND
2345  if (!parmlogp) parmlogp=(char *)NULL; /* no wrn - 21/05/98 */
2346#endif
2347
2348 /* setup MFN offset */
2349#if LIND
2350 if (parmxmfn < 1) fatal("svdifmerg/parmxmfn");
2351#endif /* LIND */
2352 for (nifs=0, vifoff[0]=0; vifnamp[nifs]; nifs++) {
2353     if (vifmfns[nifs] < 0) fatal("svdifmerg/vifmfns");
2354     vifoff[nifs+1]=vifoff[nifs]+vifmfns[nifs];
2355#if 1
2356     p=dbxcipar(NULL,vifnamp[nifs],'=');
2357     if (tell) if (dbxcipok) {  /* AOT, 22/06/2001 */
2358         n=trmtrace;
2359         trmtrace=1;
2360         invsetup((unsigned char *)vifnamp[nifs],0L,0L,atol(p));
2361         trmtrace=n;
2362     }
2363#endif
2364 }
2365 if (vifoff[nifs] > parmxmfn) fatal("svdifmerg/vifoff");
2366
2367 /* setup TRMSTRU shelf's */
2368 for (xif=0; xif < nifs; xif++) {
2369    for (vtidx[xif]=EOF, itrm=xif; ; itrm++)
2370        if (!vtrmp[itrm]) { vtidx[xif]=itrm; break; }
2371    if (vtidx[xif] == EOF) fatal("svdifmerg/maxntrm");
2372    if (pstflag == IFUPDICT) trmalloc(itrm,0L); /* don't load .ifp */
2373    else trmalloc(itrm,IFBSIZ); /* use VTRMrcase() before TERM() */ /* AOT, 22/06/2001 */
2374 }
2375
2376  print_step=tell;
2377  nregs[0]=nlids[0]=0L;
2378  nregs[1]=nlids[1]=0L;
2379  key[0]='\0';
2380  keyp=(UCHR *)key;
2381
2382  trmifupd=IFUPDXLD; /* TRMIFLOAD */
2383
2384  invflush(dbnp);
2385  trmisis0(dbnp);
2386  invsetup(dbnp,0L,0L,0L);
2387  dbxp=dbxstorp(dbnp);
2388  invp=DBXifmap;
2389
2390   p_b_key=a_p_b_key;
2391   p_b_punt=0L;
2392   init_invp_roots_nodes_leaves(invp);
2393   ifpbuff=lifp_init(invp);
2394
2395#if LIND
2396    iyp_storinit(parmxmfn,parmlogp);
2397#endif /* LIND */
2398
2399for ( nfile=0;nfile<2;nfile++) {
2400
2401   lex=vlex[nfile];
2402   if (tell>0) {
2403     fprintf(stdout,"+++ merging %d-byte keys \n",vlex[nfile]);
2404   }
2405
2406   /* REWIND(); */
2407   trmifupd=0; /* reset IFUPDXLD */
2408   for (xif=0; xif < nifs; xif++) {
2409        VTRMrcase(vtidx[xif])=nfile+1;
2410        TERM(vtidx[xif],vifnamp[xif],"!");
2411        vkuse[xif]=0;
2412   }
2413   trmifupd=IFUPDXLD; /* TRMIFLOAD */
2414
2415   key[0]='\0';
2416   key_ant_loc[0]='\0';
2417   memset((char *)&pst_ant,0x00,sizeof(POSTSTRU));
2418
2419   while (1) {
2420
2421    /* READ(); */
2422    trmifupd=0; /* reset IFUPDXLD */
2423    for (xif=0; xif < nifs; xif++) {
2424        trmp=vtrmp[itrm=vtidx[xif]];
2425        if (vkuse[xif]) NXTERM(itrm); 
2426        while (TRMlcase != nfile) { NXTERM(itrm); if (TRMrc == RCEOF) break; }
2427        vkuse[xif]=0;
2428#if TRACE_MERGE_KEYS
2429printf("+++keys#%d=%s(%d)\n",xif,TRMkey,TRMrc); 
2430#endif
2431    }
2432    trmifupd=IFUPDXLD; /* TRMIFLOAD */
2433
2434    usekp=highv;   
2435    for (xif=0; xif < nifs; xif++) {
2436        trmp=vtrmp[vtidx[xif]];
2437        if (memcmp(TRMkey,usekp,lex) < 0) usekp=TRMkey;
2438    }
2439     
2440    nkuse=0; 
2441    for (xif=0; xif < nifs; xif++) {
2442        trmp=vtrmp[vtidx[xif]];
2443        if (TRMrc == RCEOF) continue;
2444        if (memcmp(TRMkey,usekp,lex) == 0) {
2445            vkuse[xif]++; 
2446            nkuse++; 
2447            if (pstflag == IFUPDICT) break; /* don't load .ifp */
2448        }
2449    }
2450    if (!nkuse) break;
2451
2452    /* COPY(); */
2453    strcpy(keyp,usekp);
2454   
2455/* key loop */
2456    for (xif=0; xif < nifs; xif++) {
2457        if (!vkuse[xif]) continue;
2458        trmp=vtrmp[itrm=vtidx[xif]];
2459#if TRACE_MERGE_ADDKEY
2460printf("+++add#%d=%s=%s\n",xif,TRMkey,keyp);   
2461#endif
2462
2463/* posting loop */
2464        for (;;) {
2465            if (pstflag == IFUPDICT) {
2466                mfn=tag=occ=cnt=1;
2467            }
2468            else {
2469                trmifupd=0; /* reset IFUPDXLD */
2470                if (posting(itrm,TRMpost+1) <= 0) break;
2471                trmifupd=IFUPDXLD; /* TRMIFLOAD */
2472                if (vifmfns[xif])
2473                    if (TRMpmfn > vifmfns[xif]) fatal("svdifmerg/TRMpmfn");
2474                mfn=TRMpmfn+vifoff[xif];
2475                tag=TRMptag;
2476                occ=TRMpocc;
2477                cnt=TRMpcnt;
2478            }
2479#if TRACE_MERGE_ADDPST
2480printf("+++pst#%d %s#%"_LD_"=%"_LD_,%d,%d,%d\n",xif,keyp,TRMpost,mfn,tag,occ,cnt);
2481#endif
2482
2483       xbobl=strlen((CONST char *)keyp); memcpy(xbobk,keyp,xbobl); xbobk[xbobl]='\0';
2484       xbobn=bobkey(xbobk,xbobl,keyp,LE2,1,1,1);
2485       lifp_trans_key(keyp,xbobn,&treecase);
2486
2487       encodepst(&pst,mfn,tag,occ,cnt);
2488       if (!nfile && treecase || nfile && !treecase || keyp[0] <= ' ') {
2489             printf("%s %8"_LD_" %5d %4d %4d\n",keyp,mfn,tag,occ,cnt);
2490             fatal("CIIFL/invalid link record/key");
2491       }
2492
2493/*   compara post anterior com atual para ver se esta classificado */
2494     cmp=strcmp(keyp,key_ant_loc);
2495     if (cmp < 0) {
2496        fatal("CIIFL/keys not sorted");
2497     }
2498     cmp1=memcmp((char *)&pst,(char *)&pst_ant,sizeof(POSTSTRU));
2499     if (cmp ==0 && cmp1<0) {
2500        fatal("CIIFL/keys/postings not sorted/svdifmerg");
2501     }
2502
2503#if !LIND
2504     if (pstflag==IFUPDICT) {
2505        if (cmp!=0)
2506           lifp_store_btree(keyp,1L,2L,treecase); /* carrega so chaves dif*/
2507     }else {
2508        lifp_storepst();
2509     }
2510#endif /* !LIND */
2511#if LIND
2512    iyp_storlast(cmp && nregs[nfile],key_ant_loc,pstflag);
2513    iyp_storthis(mfn,parmxmfn,keyp,nregs[nfile]+1,tag,occ,cnt);
2514#endif /* LIND */
2515
2516     nregs[nfile]++;
2517     strcpy((char *)key_ant_loc,keyp);
2518     memcpy((char *)&pst_ant,(char *)&pst,sizeof(POSTSTRU));
2519
2520                if (pstflag == IFUPDICT) break;
2521               
2522/* posting loop */
2523            }
2524
2525/* key loop */
2526        }
2527
2528     nlids[nfile]++;
2529     if (tell > 0)
2530        if (nlids[nfile] % tell == 0)
2531           fprintf(stdout,"+++ %"_LD_"/%"_LD_" %s\n",nlids[nfile],nregs[nfile],keyp);
2532
2533  }/*while*/
2534
2535#if LIND
2536    iyp_storlast(nregs[nfile],key_ant_loc,pstflag);
2537#endif /* LIND */
2538
2539#if !LIND
2540    if (nfile/*treecase*/==0) {  /* So vale qdo muda da arvore 1 para 2 */
2541       { /* Ainda nao comeca em novo bloco */
2542          if (idxpst+(IDXHEADSIZE + PSTSIZE)-1 > MAXPSTS+1) {
2543            /* O algoritmo ja vai quebrar */
2544          }else {
2545            idxpst=MAXPSTS+1; /* forcar mudanca de bloco */
2546          }
2547       }
2548    }
2549#endif /* !LIND */
2550
2551}/*for */
2552
2553    /* flush merged I/F's and corresponding vtrmp[] */
2554    for (xif=0; xif < nifs; xif++) {
2555        invflush(vifnamp[xif]);
2556        itrm=vtidx[xif];
2557        FREE(vtrmp[itrm]); vtrmp[itrm]=NULL; ntrms--;
2558    }
2559
2560#if !LIND
2561    idxpst_ant =idxpst;
2562    next_blk_ant=next_blk;
2563    idxpst=MAXPSTS;
2564    gbuf=MAXIFPMEM-1;
2565    lifp_grava_ifp();
2566    if (idxpst_ant>MAXPSTS){
2567       idxpst_ant=0;
2568       next_blk_ant++;
2569    }
2570    lifp_upd_first_rec(&pn,next_blk_ant,idxpst_ant);
2571#if CNV_PCBINUM
2572    ifpwrit(dbxp,(char *)&pn,(LONGX )sizeof(IFPAVAILPOS),hdblk,hdoff,hdn);
2573#else /* CNV_PCBINUM */ 
2574    ifpwrit(dbxp,(char *)&pn,(LONGX)sizeof(IFPAVAILPOS));
2575#endif /* CNV_PCBINUM */ 
2576#endif /* !LIND */
2577
2578   lifp_close_tree();
2579
2580#if LIND
2581    iyp_storclos();
2582#endif /* LIND */
2583
2584    if (ifpbuff) FREE(ifpbuff); /* AOT - 16/09/93 */
2585
2586    /* Faz balanceamento da arvore */
2587    if (ifl_balan) {
2588        for (treecase=0;treecase<2;treecase++) {
2589            xroot=invp->cn[treecase].posrx;
2590            xliv=invp->cn[treecase].liv;
2591            balance_btree(dbxp,invp,xliv,xroot,treecase);
2592        }
2593    }
2594
2595    cntwrit(dbxp);
2596    invflush(dbnp);
2597
2598    trmifupd=0; /* reset IFUPDXLD */
2599   
2600     if (tell > 0) {
2601           fprintf(stdout,"+++ %"_LD_"/%"_LD_" %d-byte keys/postings \n",nlids[0],nregs[0],LE1);
2602           fprintf(stdout,"+++ %"_LD_"/%"_LD_" %d-byte keys/postings \n",nlids[1],nregs[1],LE2);
2603     }
2604
2605    return(nregs[0]+nregs[1]);
2606}
2607#endif /* CICPP */
2608
2609#if CICPP
2610CIIFL :: CIIFL(CISISX * parm_cisisxp)
2611{
2612 cisisxp = parm_cisisxp;
2613 ifllk_gidbnp = NULL;
2614 print_step=0L;
2615 ifpbuff=NULL; 
2616}
2617#endif /* CICPP */
Note: See TracBrowser for help on using the browser.