root/tags/5.4.pre05/ciifl.c

Revision 1, 73.4 kB (checked in by heitor.barbieri, 4 years ago)

Criação do svn para Cisis.

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,INFO 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,INFO 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                                  INFO  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;
1173INFO 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                               INFO  blk,
1359                               INFO  off,
1360                               int   treecase)
1361#else /*CICPP*/
1362static void lifp_store_btree(key,blk,off,treecase)
1363UCHR *key;
1364INFO blk,off;
1365int treecase;
1366#endif /*CICPP*/
1367{
1368  keysize=vlex[treecase];
1369   promoted=lifp_insert_leaf(
1370            dbxp,(char *)key,(char *)p_b_key,&p_b_punt,treecase,blk,off);
1371  topo=load_idx[treecase].top;
1372  isroot=FALSE;
1373  /* Sempre que houver uma promocao devera ser inserida sucessivamente
1374     nos nos dos indices.
1375  */
1376  for (level=0; level<=topo && promoted==TRUE; level++){
1377     memcpy(key,p_b_key,keysize);
1378     key_punt=p_b_punt;
1379     n0p=(N0STRU *)&(load_idx[treecase].idx_node[level]);
1380#if TRACELOAD
1381     upif_chgtostr(p_b_key,keysize,tkey); /* AOT 23/10/93 */
1382     printf("\nfnd Vai promover para node=%p keypunt=%ld key=%s",
1383                                n0p,key_punt,tkey);
1384#endif
1385      promoted=lifp_insert_node(dbxp,n0p,treecase,level,isroot,
1386                                                  key,key_punt,
1387                                                  p_b_key,&p_b_punt);
1388  } /* for  */
1389        /* se houve promocao ate a raiz cria outra raiz           */
1390        /* o ultimo o elemento retirado da pilha a raiz           */
1391  if (promoted==TRUE){
1392    memcpy(key,p_b_key,keysize);
1393    load_idx[treecase].top++;
1394    topo=load_idx[treecase].top;
1395    if (topo>=MAX_TREE_LEVEL) fatal("MAX_TREE_LEVEL/overflow");
1396    level=topo;
1397    n0p=(N0STRU *)&(load_idx[treecase].idx_node[topo]);
1398#if TRACELOAD
1399     upif_chgtostr(p_b_key,keysize,tkey); /* AOT 23/10/93 */
1400     printf("\n[Vai virar raiz]Vai promover para node=%ld keypunt=%ld key=%s",
1401                                n0p,key_punt,tkey);
1402#endif
1403    memcpy(key,p_b_key,keysize);
1404    key_punt=p_b_punt;
1405    lifp_create_root(invp,n0p,last_root,(char *)key,key_punt,treecase,FALSE);
1406  }
1407}
1408/*--------------------------------------------------------------------------*/
1409/* Precisa  gravar controles e todos os ultimos registros dos buffers
1410   aqui isroot deve ser true para o topo */
1411/* Precisa testar se foi a folha tem algum dado para gravar e
1412   acertar o CNT .
1413   Inicialmente o fmaxpos e nmaxpos aponta para 1. Porem pode
1414   acontecer dde nao ter tido nenhuma ocorrencia e entao precisa
1415   voltar a pontar par 0.
1416*/
1417#if CICPP
1418void CIIFL :: lifp_close_tree()
1419#else /* CICPP */
1420static void lifp_close_tree()
1421#endif /* CICPP */
1422{
1423   BOOLEAN treecase_occ[2];
1424   for (treecase=0;treecase<2;treecase++) {
1425#if LKXONLY
1426    if (treecase == 0) if (lkxonly & 2) continue;
1427    if (treecase == 1) if (lkxonly & 1) continue;
1428#endif
1429        if (treecase==0){
1430           l0p=(L0STRU *)&l1node;
1431           l1p=(L1STRU *)l0p;
1432          }else {
1433           l0p=(L0STRU *)&l2node;
1434           l2p=(L2STRU *)l0p;
1435        }
1436        treecase_occ[treecase]=TRUE;
1437        if(l0p->ock==0) {
1438          if (invp->cn[treecase].fmaxpos == 1 ) {
1439                invp->cn[treecase].fmaxpos=0;
1440                invp->cn[treecase].nmaxpos=0;
1441                treecase_occ[treecase]=FALSE;
1442          }else {
1443                fatal("lifp_close_tree/1");
1444          }
1445        }else {
1446           leafwrit(dbxp,l0p);
1447        }
1448 }
1449   for (treecase=0;treecase<2 ;treecase++){
1450#if LKXONLY
1451    if (treecase == 0) if (lkxonly & 2) continue;
1452    if (treecase == 1) if (lkxonly & 1) continue;
1453#endif
1454     if(treecase_occ[treecase]==TRUE ){
1455       topo=load_idx[treecase].top;
1456       isroot=FALSE;
1457       for (i=0;i<=topo;i++){
1458          if(i==topo) isroot=TRUE;
1459          n0p=(N0STRU *)&(load_idx[treecase].idx_node[i]);
1460          nodewrit(dbxp,n0p,topo,isroot);
1461       }
1462     }
1463   }
1464}
1465#if !LIND
1466/*--------------------------------------------------------------------*/
1467#if CICPP
1468void CIIFL :: lifp_grava_ifp(void)
1469#else /* CICPP */
1470static void lifp_grava_ifp()
1471#endif /* CICPP */
1472{
1473    BOOLEAN reestrut_buff;
1474      /* Atualiza o primeiro registro do arquivo */
1475        key_blk=pn.nxtb;
1476        key_pos=pn.nxtp;
1477        if (flag_first_seghead==TRUE) {
1478           firsthead=(IFPHEAD *)&pf->ifprec[off_f];
1479           firsthead->ifptotp+=npst;
1480#if CNV_PCBINUM
1481           ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1482#endif
1483        }
1484/*      lifp_upd_pst_header(ph,key_pos,nxtb,nxtp,npst,npst,npst); */
1485        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,npst,npst,npst);  /*19-02-95*/
1486#if TRCPST
1487        printf("\nkey_ant=%s blk=%ld pos=%ld pst=%d",key_ant,
1488                key_blk,key_pos,npst);
1489#endif
1490        /* Carrega dicionario passando (key_ant,key_blk,key_pos); */
1491        /* Esta parte esta ineficiente por causa da quebra */
1492        if (*key_ant !='\0')
1493             lifp_store_btree(key_ant,key_blk,key_pos,treecase_ant);
1494        reestrut_buff=FALSE;
1495        if (flag_first_seghead ==TRUE || flag_current_seghead==TRUE) {
1496           if (gbuf>0) reestrut_buff=TRUE;
1497           write_buffers(DONT_KEEP_HEADERS,reestrut_buff);
1498        }
1499        if (flag_current_seghead==TRUE) {
1500#if CNV_PCBINUM
1501#if TRCBUFF
1502 printf("\n [PH]");
1503#endif
1504           ifp_ins_new_hd(ph->ifpblk, off_h,hdblk,hdoff, IFLmaxhd,&hdn);
1505           ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1506#else /* CNV_PCBINUM */
1507           ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU));
1508#endif /* CNV_PCBINUM */ 
1509           flag_current_seghead=FALSE;
1510        }
1511        if (flag_first_seghead==TRUE) {
1512#if CNV_PCBINUM
1513#if TRCBUFF
1514 printf("\n [PF]");
1515#endif
1516           ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1517           ifpwrit(dbxp,(char *)pf,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1518#else /* CNV_PCBINUM */
1519           ifpwrit(dbxp,(char *)pf,(LONGX )sizeof(IFPSTRU));
1520#endif /* CNV_PCBINUM */
1521           flag_first_seghead=FALSE;
1522        }
1523              /* acho que tem zer log no inicio apos setar os pn*/
1524        get_room_for(IDXHEADSIZE + PSTSIZE,DONT_KEEP_HEADERS);
1525       lifp_upd_first_rec(&pn,next_blk,idxpst);
1526}
1527/*------------------------------------------------------------------------*/
1528#if CICPP
1529void CIIFL :: lifp_storepst(void)
1530#else /* CICPP */
1531static void lifp_storepst()
1532#endif /* CICPP */
1533{
1534    if (strcmp((CONST char *)key_ant,(CONST char *)key)!=0 ) {
1535        lifp_grava_ifp();
1536        /* guarda onde comeca o primeiro registro  */
1537       ph= &ifpbuff->buff[gbuf];
1538       off_h=idxpst;
1539       lifp_init_counters();
1540       lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segp,segc);
1541       idxpst=idxpst + IDXHEADSIZE;
1542       treecase_ant=treecase;
1543       strcpy((char *)key_ant,(CONST char *)key);
1544  }
1545 /*  if (npst > MAXPSTSSEG) { */
1546  if (npst > MAXPSTSSEG-1) {    /*19-02-95*/
1547     get_room_for(IDXHEADSIZE + PSTSIZE,KEEP_HEADERS);
1548     nxtb=next_blk;
1549     nxtp=idxpst;
1550     segc=npst;
1551     segp=npst;
1552     totp=npst;
1553     if (flag_first_seghead==FALSE ) {
1554        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segp,segc);
1555        memcpy((UCHR *)pf,(UCHR *)ph,sizeof(IFPSTRU));
1556        flag_first_seghead=TRUE;
1557        flag_current_seghead=FALSE; /*19-02-95*/
1558        off_f=off_h;
1559     }else {
1560        /* atualiza o total de postings do primeiro segmento */
1561        firsthead= (IFPHEAD *)&pf->ifprec[off_f];
1562        firsthead->ifptotp+=npst;
1563#if CNV_PCBINUMxx
1564        ifp_ins_new_hd(pf->ifpblk, off_f,hdblk,hdoff, IFLmaxhd,&hdn);
1565#endif
1566        /* Atualiza apontador do segmento atual */
1567        lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segc,segp);
1568        /* Precisa gravar este header porque ele podera estar apontando
1569           para area de memoria temporaria a qual podera ser ncecessaria
1570           por um novo segment header
1571        */
1572#if CNV_PCBINUM
1573#if TRCBUFF
1574 printf("\n [PH2]");
1575#endif
1576        ifp_ins_new_hd(ph->ifpblk, off_h,hdblk,hdoff, IFLmaxhd,&hdn);
1577        ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU),hdblk,hdoff,hdn);
1578#else /* CNV_PCBINUM */
1579        ifpwrit(dbxp,(char *)ph,(LONGX )sizeof(IFPSTRU));
1580#endif /* CNV_PCBINUM */
1581        flag_current_seghead=FALSE; /*19-02-95*/
1582        /* Inicializa o novo header */
1583     }
1584   lifp_init_counters();
1585   ph= &ifpbuff->buff[gbuf];
1586   off_h=idxpst;
1587   currenthead=(IFPHEAD *)&ph->ifprec[off_h];
1588   lifp_upd_pst_header(ph,off_h,nxtb,nxtp,totp,segc,segp);
1589   idxpst=idxpst+IDXHEADSIZE;
1590   }
1591    get_room_for(PSTSIZE,KEEP_HEADERS);
1592    memcpy((UCHR *)&pb->ifprec[idxpst],&pst,sizeof(POSTSTRU));
1593    idxpst=idxpst+PSTSIZE;
1594    npst++;
1595}
1596#endif /* !LIND */
1597
1598/* -----------------------------------------------------------------------*/
1599
1600#if CICPP
1601int CIIFL :: lifp_trans_key(UCHR *keyp,
1602                            int   len,
1603                            int  *treecase)
1604#else /*CICPP*/
1605static int lifp_trans_key(keyp,len,treecase)
1606UCHR *keyp;
1607int len;
1608int *treecase;
1609#endif /*CICPP*/
1610{
1611 int k,max;
1612 if (len <= 0) len=strlen((CONST char *)keyp); /* good */
1613 /* Adapta para tamanho das chaves */
1614 max= (len <= LE1)? LE1 : LE2 ;
1615 *treecase= (max == LE1)? 0: 1;
1616 for (k=len;k<max;k++) keyp[k]=' ';
1617 keyp[max]='\0';
1618 return(len);
1619}
1620/*-------------------------------------------------------------------------*/
1621
1622/*------------------------------------------------------------------------
1623  svdifload
1624  Rotina principal, em que devem ser passados o database e o arquivo que
1625  contem as chaves e atualizar a base de dados.
1626  O arquivo invertido deve estar vazio.
1627----------------------------------------------------------------------------*/
1628/*
1629        30.Nov.1998 - Author: RP
1630   -    Entrada dos dados para carga do arquivo invertido via uma base de dados
1631        ordenada;
1632   -    O parametro tell = -1, indica esta forma;
1633   -    O parametro filekeys_1 indica a base dados ordenada com as chaves curtas
1634        (LE1) primeiro e com as longas (LE2) na sequencia;
1635   -    O parametro filekeys_2 indica os dois tags necessarios para a leitura dos
1636        dados: tagkey e tagpost
1637   -    Para localizar as mudancas procure: load_type
1638*/
1639/*
1640        16.Jun.1999 - Author: RP
1641   -  Ao inv�de trabalhar com 2 tags agora trabalha s�m 1 no formato fixo.
1642   -  Exemplo:
1643                n|key       |  mfn   | tag | occ| cnt
1644                1|CHAVE10   |12345678|12345|1234|1234
1645         2|CHAVE MAIOR QUE 10            |12345678|12345|1234|1234
1646   -    O parametro filekeys_2 indica o tag necessario para a leitura dos
1647        dados: tagkey
1648   -    Para localizar as mudancas procure: postsize
1649*/
1650
1651#if CIIFLFIX
1652#if !CICPP
1653int ciiflfix=0;                 /* key %8ld %5d %4d %4d */
1654int ciiflfim=0;                 /* key %8ld w/ ciiflfix */
1655#endif /* CICPP */
1656#endif
1657
1658#if LIND
1659#if CICPP
1660LONGX CIIFL :: svdiflind (char *dbnp,
1661                         char *filekeys_1,
1662                         char *filekeys_2,
1663                         LONGX  parmxmfn,
1664                         char *parmlogp,
1665                         int   pstflag,
1666                         LONGX  tell)
1667#else /*CICPP*/
1668LONGX svdiflind (dbnp, filekeys_1,filekeys_2,parmxmfn,parmlogp,pstflag,tell)
1669char *dbnp;
1670char *filekeys_1;
1671char *filekeys_2;
1672LONGX parmxmfn;
1673char *parmlogp;
1674int pstflag;
1675LONGX tell;
1676#endif /*CICPP*/
1677#else
1678#if CICPP
1679LONGX CIIFL :: svdifload (char *dbnp,
1680                         char *filekeys_1,
1681                         char *filekeys_2,
1682                         int   pstflag,
1683                         LONGX  tell)
1684#else /*CICPP*/
1685LONGX svdifload (dbnp, filekeys_1,filekeys_2,pstflag,tell)
1686char *dbnp;
1687char *filekeys_1;
1688char *filekeys_2;
1689int pstflag;
1690LONGX tell;
1691#endif /*CICPP*/
1692#endif
1693{
1694#if MPE || UNIX
1695 int fkeys;
1696 int mpei,mpelrecl;
1697 char mpeline[BUFSIZ];
1698 LONGX mpetag,mpeocc,mpecnt;
1699#else
1700 FILE *fkeys;
1701#endif
1702 int mpex;
1703 char *mpep;
1704 char *files[2],*filnamp;
1705 LONGX nregs[2];
1706 int nfile;
1707 LONGX mfn;
1708 unsigned short tag,occ,cnt;
1709 LONGX xtag,xocc,xcnt;  /* AOT&RP 20/05/98 */
1710 char ignora_char;
1711#if !LIND
1712 UWORD idxpst_ant;
1713 INFO next_blk_ant;
1714#endif /* !LIND */
1715 PUNT xroot;
1716 int xliv,cmp,cmp1;
1717/*POSTSTRU pst_ant_loc; */
1718 UCHR key_ant_loc[LE2+1];
1719#if CIIFLFIX
1720 char fixline[LE2+1+10+10+10+10+1+1];
1721 int n;
1722#endif
1723 char xbobk[LE2+1];
1724 int xbobl,xbobn;
1725
1726   LONGX load_type = 0L; /* RP - 30/11/98 */
1727   int tagkey;
1728   RECSTRU *recp=NULL;
1729#if !CICPP
1730   LONGX idx;
1731#endif
1732   LONGX mfnread = 0L;
1733   int dirread;
1734   char auxread[128];
1735   FFI lenread; /* RP - 30/11/98 */
1736   LONGX postsize = 25; /*              |  mfn   | tag | occ| cnt       */
1737                                                        /*      |12345678|12345|1234|1234       */
1738                        /*      1 + 8 + 1 +5+ 1+ 4+1 +4         */
1739
1740#ifdef USE_INFO_SYS
1741        UCHR ansikey[LE2*2];
1742        BOOL oper_canceled=FALSE;
1743        char mess_str[255];
1744//       char mfnstr[10];
1745//    int sys_info_open=0;
1746        UIW_STRING *procstr=NULL;
1747        UIW_PROGRESSBAR *progbar=NULL;
1748        if (wprogress) {
1749                procstr=((UIW_STRING*)wprogress->Get("PROCESSING_STRING"));
1750                progbar=((UIW_PROGRESSBAR*)wprogress->Get("PROG_BAR"));
1751                progbar->Assign(0,0);
1752                progbar->SetColor(2);
1753                }
1754#endif
1755
1756 /* Tudo que tem no arquivo invertido sera perdido.
1757  */
1758
1759   if (tell == -1L) { /* RP - 30/11/98 */
1760      load_type = tell;
1761      tell = 0L;
1762   }
1763   if (load_type == -1L) {
1764      sscanf(filekeys_2,"%d",&tagkey);
1765      if (tagkey < 1) fatal("ciifl/tagkey");
1766      filekeys_2 = filekeys_1;
1767#if CICPP
1768      try { recp = new RECSTRU(cisisxp); }
1769      catch (BAD_ALLOC) { fatal("ciifl/idx"); }
1770#else
1771      for (idx = maxnrec-1; vrecp[idx]; idx--);
1772      if (!idx) fatal("ciifl/idx");
1773      recallok(idx,BUFSIZ); /* posting + chave */
1774      recp=vrecp[idx];
1775#endif
1776   } /* RP - 30/11/98 */
1777
1778  print_step=tell;
1779  files[0]=filekeys_1;
1780  files[1]=filekeys_2;
1781  nregs[0]=0L;
1782  nregs[1]=0L;
1783  key[0]='\0';
1784  /* keyp=(UCHR *)&key; */
1785  keyp=(UCHR *)key;
1786  trmifupd=IFUPDXLD; /* TRMIFLOAD */
1787#if BEFORE_INVFLUSH
1788#else
1789  invflush(dbnp);
1790#endif
1791#if LKXONLY
1792  lkxonly=0;    /* AOT - 14/05/98 */
1793  if (strcmp(filekeys_1,"void") == 0) lkxonly|=2;
1794  if (strcmp(filekeys_2,"void") == 0) lkxonly|=1;
1795#if CICPP
1796  if (!lkxonly || lkxonly & 1) trmisis0(cisisxp, dbnp);
1797#else /* CICPP */
1798  if (!lkxonly || lkxonly & 1) trmisis0(dbnp);
1799#endif /* CICPP */
1800#else
1801  trmisis0(dbnp);
1802#endif
1803  invsetup((unsigned char *)dbnp,0L,0L,0L);
1804  dbxp=dbxstorp(dbnp);
1805  invp=DBXifmap;
1806#if RESUMOLOAD
1807   printf("\n Situacao do Arquivo Invertido Antes de Atualizar ");
1808   lifp_print_cnt(invp);
1809#endif
1810#if !AOT
1811if (tell>0) {
1812   printf("\n Entrada na svdifload tell=%ld keys1=%s keys2=%s",
1813           tell,files[0],files[1]);
1814}
1815#endif
1816   p_b_key=a_p_b_key;
1817   p_b_punt=0L;
1818   init_invp_roots_nodes_leaves(invp);
1819   ifpbuff=lifp_init(invp);
1820#if CICPP || IFLOADFUN
1821   if (ifpbuff == NULL) return(-9L);
1822#endif /* CICPP || IFLOADFUN */
1823#if LIND
1824    iyp_storinit(parmxmfn,parmlogp);
1825#endif /* LIND */
1826for ( nfile=0;nfile<2;nfile++) {
1827#ifdef USE_INFO_SYS
1828//    sys_info_open=0;
1829#endif
1830#if LKXONLY
1831    if (nfile == 0) if (lkxonly & 2) continue;
1832    if (nfile == 1) if (lkxonly & 1) continue;
1833#endif
1834 /*y*/ if (files[nfile]==NULL) goto no_file;
1835 /*y*/ if (*files[nfile]=='\0') goto no_file;
1836
1837   if (load_type == 0L) { /* RP - 30/11/98 */
1838   filnamp=dbxcipar(ifllk_gidbnp,files[nfile],'=');
1839#if MPE || UNIX
1840   fkeys=OPEN(filnamp,O_RDONLY);
1841#else
1842   fkeys=fopen(filnamp,"r");
1843#endif
1844   if(!fkeys) {
1845#if CICPP || IFLOADFUN
1846     return(-1L);
1847#else /* CICPP || IFLOADFUN */
1848     fatal(filnamp);
1849#endif /* CICPP || IFLOADFUN */
1850   }
1851   if (tell>0) {
1852#if AOT
1853#ifdef USE_INFO_SYS
1854// now in wisis.cpp
1855//     errsys->sys_info(filnamp);
1856//     sys_info_open=1;
1857#else
1858     fprintf(stderr,"+++ %s\n",filnamp);
1859#endif
1860#else
1861     printf("\n-------------------------------------------------------");
1862     printf("\nProcessando arquivo:%s",filnamp);
1863#endif
1864   }
1865   } /* RP - 30/11/98 */
1866   key[0]='\0';
1867   key_ant_loc[0]='\0';
1868   memset((char *)&pst_ant,0x00,sizeof(POSTSTRU));
1869   nlido=0L;
1870
1871#if MPE || UNIX
1872
1873#if UNIX
1874   mpelrecl=25+vlex[nfile]+1; /*        8+1 + 5+1 + 4+1 + 4+1 + LEx + lf */
1875#if CIIFLFIX
1876   if (ciiflfix)
1877      if (ciiflfim) mpelrecl-=16; /*      - ( 5+1 + 4+1 + 4+1 )          */
1878#endif
1879#else /* UNIX */
1880   mpelrecl=25+vlex[nfile]+1; /* null + 8+1 + 5+1 + 4+1 + 4+1 + LEx + lf */
1881#endif /* UNIX */
1882
1883   while (1) {
1884    if (load_type == 0L) { /* RP - 30/11/98 */
1885     mpex=CIREAD(fkeys,mpeline,mpelrecl);
1886     if (mpex == 0) break;
1887     if (mpex != mpelrecl) {
1888#if CICPP || IFLOADFUN
1889        return(-6L);
1890#endif /* CICPP || IFLOADFUN */
1891        fatal("CIIFL/read");
1892     }
1893     mpeline[mpelrecl-1]='\0';
1894     mpep=mpeline;
1895#if UNIX
1896#if CIIFLFIX
1897     if (ciiflfix) {
1898         memcpy(keyp,mpep,mpei=vlex[nfile]); mpep+=mpei;
1899         if (ciiflfim) {
1900            mpex=sscanf(mpep," %8ld",&mfn); mpex+=3; mpetag=mpeocc=mpecnt=1;
1901         } else
1902                        /* por %ld para mpetag,mpeocc,mpecnt - AOT 21/05/98 */
1903        /*mpex=sscanf(mpep," %8ld %5ld %4ld %4ld",&mfn,&mpetag,&mpeocc,&mpecnt);*/
1904            mpex=sscanf(mpep," %8ld %5d %4d %4d",&mfn,&mpetag,&mpeocc,&mpecnt);
1905     }
1906     else {
1907#endif
1908     /*mpex=sscanf(mpep,"%8ld %5ld %4ld %4ld ",&mfn,&mpetag,&mpeocc,&mpecnt);*/
1909         mpex=sscanf(mpep,"%8ld %5d %4d %4d ",&mfn,&mpetag,&mpeocc,&mpecnt);
1910         memcpy(keyp,mpep+25,vlex[nfile]);
1911#if CIIFLFIX
1912     }
1913#endif
1914#else /* UNIX */ 
1915                        /* por %ld para mpetag,mpeocc,mpecnt - AOT 21/05/98 */
1916     /* mpex=sscanf(mpep+1,"%8ld %5ld %4ld %4ld ",&mfn,&mpetag,&mpeocc,&mpecnt); */
1917     mpex=sscanf(mpep+1,"%8ld %5d %4d %4d ",&mfn,&mpetag,&mpeocc,&mpecnt);
1918     memcpy(keyp,mpep+25,vlex[nfile]);
1919#endif /* UNIX */
1920     if (mpex != 4) {
1921#if CICPP || IFLOADFUN
1922         return(-2L);
1923#endif /* CICPP || IFLOADFUN */
1924         printf("*** File: %s  Rec: %ld \n",filnamp,nlido+1);
1925         printf("*** %s \n",mpeline);
1926         fatal("CIIFL/invalid link record/mpe");
1927     }
1928     tag=mpetag; occ=mpeocc; cnt=mpecnt;
1929     keyp[vlex[nfile]]='\0';
1930    } else { /* RP - 30/11/98 */
1931#if CICPP
1932      recp->xrecord(files[nfile],++mfnread);
1933      if (recp->recrc == RCEOF) break;
1934      memset(keyp,' ',vlex[nfile]);
1935      dirread = recp->xfieldx(tagkey,1);
1936#else /* CICPP */
1937      record(idx,files[nfile],++mfnread);
1938      if (RECrc == RCEOF) break;
1939      memset(keyp,' ',vlex[nfile]);
1940      dirread = fieldx(idx,tagkey,1);
1941#endif /* CICPP */
1942      if (dirread < 0) fatal("ciifl/fieldx/tagkey");
1943      if (*(FIELDP(dirread)) - '1' > nfile) break;
1944      memcpy(keyp,FIELDP(dirread)+2,vlex[nfile]);
1945      keyp[vlex[nfile]] = '\0';
1946
1947      memcpy(auxread,FIELDP(dirread)+2+vlex[nfile],postsize);
1948      auxread[postsize] = '\0';
1949                sscanf(auxread,"|%8ld|%5ld|%4ld|%4ld",&mfn,&xtag,&xocc,&xcnt);
1950                tag = (unsigned short)xtag;
1951                occ = (unsigned short)xocc;
1952                cnt = (unsigned short)xcnt;
1953    } /* RP - 30/11/98 */
1954     
1955#else /* MPE || UNIX */
1956#ifdef USE_INFO_SYS
1957        progbar->SetColor(nfile+1);
1958        progbar->Assign(0,0);
1959#endif
1960
1961   while (1) {
1962         if (load_type == 0L) { /* RP - 30/11/98 */
1963         if (feof(fkeys)) break;
1964   /* O teste de fim de arquivo nao funciona. Processa um
1965      registro vazio. Precisa testar se o fscanf conseguiu
1966      ler algum campo. Volta -1 quando nao le
1967   */
1968#if CIIFLFIX
1969       if (ciiflfix) {
1970        if (fgets(fixline,sizeof(fixline),fkeys) == NULL) break;
1971        memcpy(keyp,fixline,n=vlex[nfile]); keyp[n]='\0';
1972        if (ciiflfim) {
1973            mpex=sscanf(fixline+n," %8ld",&mfn); mpex+=3; tag=occ=cnt=1;
1974        }
1975        else {
1976            /* %d/unsigned short nao funciona no 32bits - AOT&RP 20/05/98 */
1977            mpex=sscanf(fixline+n," %8ld %5ld %4ld %4ld",&mfn,&xtag,&xocc,&xcnt);
1978        }
1979        if (mpex != 4) {
1980#if CICPP || IFLOADFUN
1981            return(-3L);
1982#else /* CICPP || IFLOADFUN */
1983            printf("*** File: %s  Rec: %ld \n",filnamp,nlido+1);
1984            printf("*** %s \n",fixline);
1985            fatal("CIIFL/invalid link record/fix");
1986#endif /* CICPP || IFLOADFUN */
1987        }
1988       }
1989       else {
1990#endif /* CIIFLFIX */
1991        if (fscanf(fkeys,"%ld",&mfn) < 1)
1992            if (feof(fkeys)) break;
1993            else {
1994#if CICPP || IFLOADFUN
1995                return(-4L);
1996#else /* CICPP || IFLOADFUN */
1997                fatal("CIIFL/invalid link record/mfn");
1998#endif /* CICPP || IFLOADFUN */
1999            }
2000        fscanf(fkeys,"%ld",&xtag);
2001        fscanf(fkeys,"%ld",&xocc);
2002        fscanf(fkeys,"%ld",&xcnt);
2003        fscanf(fkeys,"%c",&ignora_char);
2004        fscanf(fkeys,"%[^\n]\n",keyp);
2005#if CIIFLFIX
2006       }
2007#endif
2008       tag=(unsigned short)xtag;
2009       occ=(unsigned short)xocc;
2010       cnt=(unsigned short)xcnt;
2011    } else { /* RP - 30/11/98 */
2012#if CICPP
2013      recp->xrecord(files[nfile],++mfnread);
2014      if (recp->recrc == RCEOF) break;
2015      memset(keyp,' ',vlex[nfile]);
2016      dirread = recp->xfieldx(tagkey,1);
2017#else /* CICPP */
2018      record(idx,files[nfile],++mfnread);
2019      if (RECrc == RCEOF) break;
2020      memset(keyp,' ',vlex[nfile]);
2021      dirread = fieldx(idx,tagkey,1);
2022#endif /* CICPP */
2023      if (dirread < 0) fatal("ciifl/fieldx/tagkey");
2024      if (*(FIELDP(dirread)) - '1' > nfile) break;
2025      memcpy(keyp,FIELDP(dirread)+2,vlex[nfile]);
2026      keyp[vlex[nfile]] = '\0';
2027
2028      memcpy(auxread,FIELDP(dirread)+2+vlex[nfile],postsize);
2029      auxread[postsize] = '\0';
2030                sscanf(auxread,"|%8ld|%5ld|%4ld|%4ld",&mfn,&xtag,&xocc,&xcnt);
2031                tag = (unsigned short)xtag;
2032                occ = (unsigned short)xocc;
2033                cnt = (unsigned short)xcnt;
2034    } /* RP - 30/11/98 */
2035#endif /* MPE || UNIX */
2036       xbobl=strlen((CONST char *)keyp); memcpy(xbobk,keyp,xbobl); xbobk[xbobl]='\0';
2037       xbobn=bobkey(xbobk,xbobl,(char *)keyp,LE2,1,1,1);
2038       lifp_trans_key(keyp,xbobn,&treecase);
2039       if (ciiflfix) if (ciiflfim) tag=occ=cnt=0; /* AOT 27/09/2001 */
2040       encodepst(&pst,mfn,tag,occ,cnt);
2041       if (!nfile && treecase || nfile && !treecase || keyp[0] <= ' ') {
2042#if CICPP || IFLOADFUN
2043             return(-5L);
2044#else /* CICPP || IFLOADFUN */
2045             printf("[%c]%s %8ld %5d %4d %4d\n",keyp[0],keyp,mfn,tag,occ,cnt);
2046             fatal("CIIFL/invalid link record/key");
2047#endif /* CICPP || IFLOADFUN */
2048       }
2049/*   compara post anterior com atual para ver se esta classificado */
2050     cmp=strcmp((CONST char *)keyp,(CONST char *)key_ant_loc);
2051     if (cmp < 0) {
2052#if CICPP || IFLOADFUN
2053        return(-7L);
2054#else /* CICPP || IFLOADFUN */
2055        fatal("CIIFL/keys not sorted");
2056#endif /* CICPP || IFLOADFUN */
2057     }
2058#if !SUNBUG_UNSIGNED
2059     cmp1=memcmp((char *)&pst,(char *)&pst_ant,sizeof(POSTSTRU));
2060     if (cmp ==0 && cmp1<0) {
2061#if CICPP || IFLOADFUN
2062        return(-8L);
2063#else /* CICPP || IFLOADFUN */
2064#if 1
2065        printf("\n+++ key    : %s",keyp);
2066        printf("\n+++ pst    : ");
2067        for (mpep=(char *)&pst,     mpex=sizeof(POSTSTRU); mpex--; mpep++)
2068               printf("%02x ",*mpep);
2069        printf("\n+++ pst_ant: ");
2070        for (mpep=(char *)&pst_ant, mpex=sizeof(POSTSTRU); mpex--; mpep++)
2071               printf("%02x ",*mpep);
2072        printf("\n+++          ");
2073#endif
2074        fatal("CIIFL/keys/postings not sorted");
2075#endif /* CICPP || IFLOADFUN */
2076     }
2077#endif /* SUNBUG_UNSIGNED */
2078#if !LIND
2079     if (pstflag==IFUPDICT) {
2080        if (cmp!=0)
2081           lifp_store_btree(keyp,1L,2L,treecase); /* carrega so chaves dif*/
2082     }else {
2083        lifp_storepst();
2084     }
2085#endif /* !LIND */
2086#if LIND
2087    iyp_storlast(cmp && nregs[nfile],key_ant_loc,pstflag);
2088    iyp_storthis(mfn,parmxmfn,keyp,nregs[nfile]+1,tag,occ,cnt);
2089#endif /* LIND */
2090     nregs[nfile]++;
2091     nlido++;
2092     if (tell > 0)
2093        if (nlido - (nlido/tell*tell)== 0)
2094#if AOT
2095#ifdef USE_INFO_SYS
2096                                {
2097//         errsys->sys_info_data(keyp); //ltoa(mfn,mfnstr,10));
2098                if (wprogress) {
2099                        LONGX int prog_pos=ftell(fkeys);
2100                        int fhandle=fileno(fkeys);
2101                        LONGX fleng=filelength(fhandle);
2102                        ISIS_OemToAnsi(key,ansikey);
2103                        if (!nfile)
2104                                sprintf(mess_str,"%s %s",mess->get(424),keyp);
2105                        else
2106                                sprintf(mess_str,"%s %s",mess->get(425),keyp);
2107                        procstr->DataSet(mess_str);
2108                        progbar->Assign(prog_pos,fleng);
2109        //              ((UIW_STRING*)wprogress->Get("PHASE_STRING"))->DataSet(NULL);
2110                        UI_EVENT event,event1,event2;
2111                        wprogress->eventManager->Get(event1,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2112                        wprogress->windowManager->Event(event1);
2113                        wprogress->eventManager->Get(event2,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2114                        wprogress->windowManager->Event(event2);
2115                        wprogress->eventManager->Get(event,Q_NO_BLOCK|Q_BEGIN|Q_DESTROY|Q_POLL);
2116                        if (event.type==10235 || event1.type==10235 || event2.type==10235) {            // EXPORT_CANCEL) {
2117                                        int ok=errsys->ErrorMessage(wprogress->windowManager,WOS_INVALID,mess->get(420));
2118                                        if (ok==WOS_INVALID) {
2119                                                oper_canceled=TRUE;
2120                                                break;
2121                                                }
2122                                        }
2123                        wprogress->windowManager->Event(event);
2124                        }
2125                }
2126#else
2127           fprintf(stderr,"+++ %ld %s\n",nlido,keyp);
2128#endif
2129#else
2130           printf("\n Rec:%ld Key:%s",nlido,keyp);
2131#endif
2132     strcpy((char *)key_ant_loc,(CONST char *)keyp);
2133     memcpy((char *)&pst_ant,(char *)&pst,sizeof(POSTSTRU));
2134  }/*while*/
2135#if LIND
2136    iyp_storlast(nregs[nfile],key_ant_loc,pstflag);
2137#endif /* LIND */
2138 if (load_type == 0L) { /* RP - 30/11/98 */
2139#if MPE || UNIX
2140  CLOSE(fkeys);
2141#else
2142  fclose(fkeys);
2143#endif
2144 } else {
2145        mfnread--;
2146 }/* RP - 30/11/98 */
2147  /* Esta parte e para forcar a mudar de segmento quando comeca a arvore do
2148         tipo 2. Isto e para deixar compativel com ISIS. Nao existe nenhum
2149         motivo serio fazer essa compatibilizacao
2150 */
2151 /*y*/ no_file:
2152
2153#ifdef USE_INFO_SYS
2154// now in wisis.cpp
2155//     if (sys_info_open) errsys->sys_info_close();
2156#endif
2157#if !LIND
2158    /* Deve verificar se o arquivo .lk2 nao esta' vazio - AOT 950720 */
2159    if (nfile/*treecase*/==0) {  /* So vale qdo muda da arvore 1 para 2 */
2160       { /* Ainda nao comeca em novo bloco */
2161          if (idxpst+(IDXHEADSIZE + PSTSIZE)-1 > MAXPSTS+1) {
2162            /* O algoritmo ja vai quebrar */
2163          }else {
2164            idxpst=MAXPSTS+1; /* forcar mudanca de bloco */
2165          }
2166       }
2167    }
2168#endif /* !LIND */
2169    ;  /* !LIND - label: ; */
2170#ifdef USE_INFO_SYS
2171        if (oper_canceled)
2172                break;  // exit!!
2173#endif
2174
2175}/*for */
2176
2177#if !LIND
2178/* Serao guardados idxpst e next_blk porque sera forcada a entrada de uma
2179   "falsa chave" para gravar o buffer .
2180   Na gravacao do buffer, next_blk e idxpst serao alterados. Serao guardados
2181   para atualizar o registro de controle [pn].
2182   O que e' feito pelo ISIS parece incoerente. Quando muda de arquivo com
2183   chaves do tipo 1 para o arquivo com chaves do tipo 2  muda
2184   de bloco.   Quando terminar o segundo arquivo acho que tambem deveria
2185   mudar, porem nao faz.
2186*/
2187    idxpst_ant =idxpst;
2188    next_blk_ant=next_blk;
2189    idxpst=MAXPSTS;
2190    gbuf=MAXIFPMEM-1;
2191    lifp_grava_ifp();
2192/*y*/
2193    /* Caso nao teve nenhum link do tipo 2, precisa acertar o next_blk_ant e
2194       idxpst_ant
2195    */
2196    if (idxpst_ant>MAXPSTS){
2197       idxpst_ant=0;
2198       next_blk_ant++;
2199    }
2200/*y*/
2201    lifp_upd_first_rec(&pn,next_blk_ant,idxpst_ant);
2202#if TRACELOAD
2203    printf ("\n pn=%ld %ld %ld ",pn.ifpblk,pn.nxtb,pn.nxtp);
2204#endif
2205#if CNV_PCBINUM
2206    ifpwrit(dbxp,(char *)&pn,(LONGX )sizeof(IFPAVAILPOS),hdblk,hdoff,hdn);
2207#else /* CNV_PCBINUM */ 
2208    ifpwrit(dbxp,(char *)&pn,(LONGX)sizeof(IFPAVAILPOS));
2209#endif /* CNV_PCBINUM */ 
2210#endif /* !LIND */
2211
2212#if CORRECAO_SINDO
2213/*
2214        Nao ativei porque existe a possibilidade de o proprio ifupd/ciifu
2215        gerar (pn.nxtp==0)
2216       
2217        Ja' alterei a postread para retornar um bloco vazio no EOF; mas
2218        mesmo assim a ciifu nao trata a seguinte situacao gerada pelo
2219        MicroISIS:
2220                x com 60 registros
2221                x.fst=1 0 'chave'               -> gera 1 blk cheio
2222                isis/i/x/f                      -> full I/F (ctrl=1/127)
2223                mx tmp append=x now count=1     -> cria #61
2224                ifupd x fst=@x.fst              -> atualiza (errado)
2225                ifkeys x                        -> mostra bug (32 postings!)
2226        AOT
2227*/
2228/* 20-07-95  Inicio */
2229/*Sempre que  a proxima posicao disponivel estiver no inicio
2230 de um   bloco vazio, isto e, (pn.nxtp==0),
2231 e' necessario gravar um registro ifp. Caso contrario
2232 a rotina "postread" da' erro de leitura quando for
2233 ler esse bloco pois nao consegue ler 512 bytes.
2234*/
2235   if (pn.nxtp==0) {
2236     pb=(IFPSTRU *)&ifpbuff->buff[0];
2237     lifp_init_ifprec(pb,pn.nxtb);
2238#if CNV_PCBINUM
2239     /* Nao tem nada para converter */
2240     ifpwrit(dbxp,(char *)pb,(LONGX)sizeof(IFPSTRU),hdblk,hdoff,(-1));
2241#else /* CNV_PCBINUM */ 
2242     ifpwrit(dbxp,(char *)pb,(LONGX)sizeof(IFPSTRU));
2243#endif /* CNV_PCBINUM */ 
2244   }
2245/* 20-07-95  fim */
2246#endif
2247
2248   lifp_close_tree();
2249
2250/* Resumo das operacoes efetuadas */
2251#if RESUMOLOAD
2252   printf("\n Quantidade de Chaves Processadas");
2253   printf("\n   %s:%ld,\n   %s:%ld\n   Total:%ld\n",
2254          files[0],nregs[0],files[1],nregs[1],nregs[0]+nregs[1]);
2255   lifp_print_cnt(invp);
2256#endif
2257
2258#if LIND
2259    iyp_storclos();
2260#endif /* LIND */
2261#if CICPP
2262    if (ifpbuff) delete[] ifpbuff;
2263#else /* CICPP */
2264    if (ifpbuff) FREE(ifpbuff); /* AOT - 16/09/93 */
2265#endif /* CICPP */
2266
2267    /* Faz balanceamento da arvore */
2268    if (ifl_balan) {
2269        for (treecase=0;treecase<2;treecase++) {
2270#if LKXONLY
2271    if (treecase == 0) if (lkxonly & 2) continue;
2272    if (treecase == 1) if (lkxonly & 1) continue;
2273#endif
2274            xroot=invp->cn[treecase].posrx;
2275            xliv=invp->cn[treecase].liv;
2276            balance_btree(dbxp,invp,xliv,xroot,treecase);
2277        }
2278    }
2279
2280    cntwrit(dbxp);
2281    invflush(dbnp);
2282
2283    trmifupd=0; /* reset IFUPDXLD */
2284
2285#ifdef USE_INFO_SYS
2286        if (oper_canceled)
2287                return (-100);
2288#endif
2289
2290    if (recp) { /* RP - 30/11/98 */
2291#if CICPP
2292        delete recp;
2293#else /* CICPP */
2294        FREE(vrecp[idx]); vrecp[idx] = NULL; nrecs--;
2295#endif /* CICPP */
2296    }
2297
2298    return(nregs[0]+nregs[1]);
2299}
2300
2301/*---------------------------------------------------------------------------
2302  svdifmerg - I/F merge: load a b-tree from existing I/F's
2303              AOT, 25/11/95
2304----------------------------------------------------------------------------*/
2305#if !CICPP
2306LONGX svdifmerg (dbnp,vifnamp,vifmfns,parmxmfn,parmlogp,pstflag,tell)
2307char *dbnp;
2308char *vifnamp[];
2309LONGX vifmfns[];
2310LONGX parmxmfn;
2311char *parmlogp;
2312int pstflag;
2313LONGX tell;
2314{
2315 LONGX nregs[2];
2316 int nfile;
2317 LONGX mfn;
2318 unsigned short tag,occ,cnt;
2319#if !LIND
2320 UWORD idxpst_ant;
2321 INFO next_blk_ant;
2322#endif /* !LIND */
2323 PUNT xroot;
2324 int xliv,cmp,cmp1;
2325 UCHR key_ant_loc[LE2+1];
2326 char xbobk[LE2+1];
2327 int xbobl,xbobn;
2328
2329 int nifs;                      /* no of I/Fs to merge */
2330 LONGX vifoff[MAXIFMRG];                /* posting's MFN offset */
2331 LONGX vtidx[MAXIFMRG];         /* index of vtrmp[] */
2332 int vkuse[MAXIFMRG];           /* to flag a key is to be merged */
2333 int nkuse;                     /* no of vkuse[] active elements */
2334 char *usekp;                   /* current key ptr */
2335 int xif;                       /* I/F index */
2336
2337 TRMSTRU *trmp;
2338 LONGX itrm;
2339 LONGX nlids[2];
2340 int lex,n;
2341 char *p;
2342
2343#if !LIND
2344  if (!parmlogp) parmlogp=(char *)NULL; /* no wrn - 21/05/98 */
2345#endif
2346
2347 /* setup MFN offset */
2348#if LIND
2349 if (parmxmfn < 1) fatal("svdifmerg/parmxmfn");
2350#endif /* LIND */
2351 for (nifs=0, vifoff[0]=0; vifnamp[nifs]; nifs++) {
2352     if (vifmfns[nifs] < 0) fatal("svdifmerg/vifmfns");
2353     vifoff[nifs+1]=vifoff[nifs]+vifmfns[nifs];
2354#if 1
2355     p=dbxcipar(NULL,vifnamp[nifs],'=');
2356     if (tell) if (dbxcipok) {  /* AOT, 22/06/2001 */
2357         n=trmtrace;
2358         trmtrace=1;
2359         invsetup((unsigned char *)vifnamp[nifs],0L,0L,atol(p));
2360         trmtrace=n;
2361     }
2362#endif
2363 }
2364 if (vifoff[nifs] > parmxmfn) fatal("svdifmerg/vifoff");
2365
2366 /* setup TRMSTRU shelf's */
2367 for (xif=0; xif < nifs; xif++) {
2368    for (vtidx[xif]=EOF, itrm=xif; ; itrm++)
2369        if (!vtrmp[itrm]) { vtidx[xif]=itrm; break; }
2370    if (vtidx[xif] == EOF) fatal("svdifmerg/maxntrm");
2371    if (pstflag == IFUPDICT) trmalloc(itrm,0L); /* don't load .ifp */
2372    else trmalloc(itrm,IFBSIZ); /* use VTRMrcase() before TERM() */ /* AOT, 22/06/2001 */
2373 }
2374
2375  print_step=tell;
2376  nregs[0]=nlids[0]=0L;
2377  nregs[1]=nlids[1]=0L;
2378  key[0]='\0';
2379  keyp=(UCHR *)key;
2380
2381  trmifupd=IFUPDXLD; /* TRMIFLOAD */
2382
2383  invflush(dbnp);
2384  trmisis0(dbnp);
2385  invsetup(dbnp,0L,0L,0L);
2386  dbxp=dbxstorp(dbnp);
2387  invp=DBXifmap;
2388
2389   p_b_key=a_p_b_key;
2390   p_b_punt=0L;
2391   init_invp_roots_nodes_leaves(invp);
2392   ifpbuff=lifp_init(invp);
2393
2394#if LIND
2395    iyp_storinit(parmxmfn,parmlogp);
2396#endif /* LIND */
2397
2398for ( nfile=0;nfile<2;nfile++) {
2399
2400   lex=vlex[nfile];
2401   if (tell>0) {
2402     fprintf(stdout,"+++ merging %d-byte keys \n",vlex[nfile]);
2403   }
2404
2405   /* REWIND(); */
2406   trmifupd=0; /* reset IFUPDXLD */
2407   for (xif=0; xif < nifs; xif++) {
2408        VTRMrcase(vtidx[xif])=nfile+1;
2409        TERM(vtidx[xif],vifnamp[xif],"!");
2410        vkuse[xif]=0;
2411   }
2412   trmifupd=IFUPDXLD; /* TRMIFLOAD */
2413
2414   key[0]='\0';
2415   key_ant_loc[0]='\0';
2416   memset((char *)&pst_ant,0x00,sizeof(POSTSTRU));
2417
2418   while (1) {
2419
2420    /* READ(); */
2421    trmifupd=0; /* reset IFUPDXLD */
2422    for (xif=0; xif < nifs; xif++) {
2423        trmp=vtrmp[itrm=vtidx[xif]];
2424        if (vkuse[xif]) NXTERM(itrm); 
2425        while (TRMlcase != nfile) { NXTERM(itrm); if (TRMrc == RCEOF) break; }
2426        vkuse[xif]=0;
2427#if TRACE_MERGE_KEYS
2428printf("+++keys#%d=%s(%d)\n",xif,TRMkey,TRMrc); 
2429#endif
2430    }
2431    trmifupd=IFUPDXLD; /* TRMIFLOAD */
2432
2433    usekp=highv;   
2434    for (xif=0; xif < nifs; xif++) {
2435        trmp=vtrmp[vtidx[xif]];
2436        if (memcmp(TRMkey,usekp,lex) < 0) usekp=TRMkey;
2437    }
2438     
2439    nkuse=0; 
2440    for (xif=0; xif < nifs; xif++) {
2441        trmp=vtrmp[vtidx[xif]];
2442        if (TRMrc == RCEOF) continue;
2443        if (memcmp(TRMkey,usekp,lex) == 0) {
2444            vkuse[xif]++; 
2445            nkuse++; 
2446            if (pstflag == IFUPDICT) break; /* don't load .ifp */
2447        }
2448    }
2449    if (!nkuse) break;
2450
2451    /* COPY(); */
2452    strcpy(keyp,usekp);
2453   
2454/* key loop */
2455    for (xif=0; xif < nifs; xif++) {
2456        if (!vkuse[xif]) continue;
2457        trmp=vtrmp[itrm=vtidx[xif]];
2458#if TRACE_MERGE_ADDKEY
2459printf("+++add#%d=%s=%s\n",xif,TRMkey,keyp);   
2460#endif
2461
2462/* posting loop */
2463        for (;;) {
2464            if (pstflag == IFUPDICT) {
2465                mfn=tag=occ=cnt=1;
2466            }
2467            else {
2468                trmifupd=0; /* reset IFUPDXLD */
2469                if (posting(itrm,TRMpost+1) <= 0) break;
2470                trmifupd=IFUPDXLD; /* TRMIFLOAD */
2471                if (vifmfns[xif])
2472                    if (TRMpmfn > vifmfns[xif]) fatal("svdifmerg/TRMpmfn");
2473                mfn=TRMpmfn+vifoff[xif];
2474                tag=TRMptag;
2475                occ=TRMpocc;
2476                cnt=TRMpcnt;
2477            }
2478#if TRACE_MERGE_ADDPST
2479printf("+++pst#%d %s#%ld=%ld,%d,%d,%d\n",xif,keyp,TRMpost,mfn,tag,occ,cnt);
2480#endif
2481
2482       xbobl=strlen((CONST char *)keyp); memcpy(xbobk,keyp,xbobl); xbobk[xbobl]='\0';
2483       xbobn=bobkey(xbobk,xbobl,keyp,LE2,1,1,1);
2484       lifp_trans_key(keyp,xbobn,&treecase);
2485
2486       encodepst(&pst,mfn,tag,occ,cnt);
2487       if (!nfile && treecase || nfile && !treecase || keyp[0] <= ' ') {
2488             printf("%s %8ld %5d %4d %4d\n",keyp,mfn,tag,occ,cnt);
2489             fatal("CIIFL/invalid link record/key");
2490       }
2491
2492/*   compara post anterior com atual para ver se esta classificado */
2493     cmp=strcmp(keyp,key_ant_loc);
2494     if (cmp < 0) {
2495        fatal("CIIFL/keys not sorted");
2496     }
2497     cmp1=memcmp((char *)&pst,(char *)&pst_ant,sizeof(POSTSTRU));
2498     if (cmp ==0 && cmp1<0) {
2499        fatal("CIIFL/keys/postings not sorted/svdifmerg");
2500     }
2501
2502#if !LIND
2503     if (pstflag==IFUPDICT) {
2504        if (cmp!=0)
2505           lifp_store_btree(keyp,1L,2L,treecase); /* carrega so chaves dif*/
2506     }else {
2507        lifp_storepst();
2508     }
2509#endif /* !LIND */
2510#if LIND
2511    iyp_storlast(cmp && nregs[nfile],key_ant_loc,pstflag);
2512    iyp_storthis(mfn,parmxmfn,keyp,nregs[nfile]+1,tag,occ,cnt);
2513#endif /* LIND */
2514
2515     nregs[nfile]++;
2516     strcpy((char *)key_ant_loc,keyp);
2517     memcpy((char *)&pst_ant,(char *)&pst,sizeof(POSTSTRU));
2518
2519                if (pstflag == IFUPDICT) break;
2520               
2521/* posting loop */
2522            }
2523
2524/* key loop */
2525        }
2526
2527     nlids[nfile]++;
2528     if (tell > 0)
2529        if (nlids[nfile] % tell == 0)
2530           fprintf(stdout,"+++ %ld/%ld %s\n",nlids[nfile],nregs[nfile],keyp);
2531
2532  }/*while*/
2533
2534#if LIND
2535    iyp_storlast(nregs[nfile],key_ant_loc,pstflag);
2536#endif /* LIND */
2537
2538#if !LIND
2539    if (nfile/*treecase*/==0) {  /* So vale qdo muda da arvore 1 para 2 */
2540       { /* Ainda nao comeca em novo bloco */
2541          if (idxpst+(IDXHEADSIZE + PSTSIZE)-1 > MAXPSTS+1) {
2542            /* O algoritmo ja vai quebrar */
2543          }else {
2544            idxpst=MAXPSTS+1; /* forcar mudanca de bloco */
2545          }
2546       }
2547    }
2548#endif /* !LIND */
2549
2550}/*for */
2551
2552    /* flush merged I/F's and corresponding vtrmp[] */
2553    for (xif=0; xif < nifs; xif++) {
2554        invflush(vifnamp[xif]);
2555        itrm=vtidx[xif];
2556        FREE(vtrmp[itrm]); vtrmp[itrm]=NULL; ntrms--;
2557    }
2558
2559#if !LIND
2560    idxpst_ant =idxpst;
2561    next_blk_ant=next_blk;
2562    idxpst=MAXPSTS;
2563    gbuf=MAXIFPMEM-1;
2564    lifp_grava_ifp();
2565    if (idxpst_ant>MAXPSTS){
2566       idxpst_ant=0;
2567       next_blk_ant++;
2568    }
2569    lifp_upd_first_rec(&pn,next_blk_ant,idxpst_ant);
2570#if CNV_PCBINUM
2571    ifpwrit(dbxp,(char *)&pn,(LONGX )sizeof(IFPAVAILPOS),hdblk,hdoff,hdn);
2572#else /* CNV_PCBINUM */ 
2573    ifpwrit(dbxp,(char *)&pn,(LONGX)sizeof(IFPAVAILPOS));
2574#endif /* CNV_PCBINUM */ 
2575#endif /* !LIND */
2576
2577   lifp_close_tree();
2578
2579#if LIND
2580    iyp_storclos();
2581#endif /* LIND */
2582
2583    if (ifpbuff) FREE(ifpbuff); /* AOT - 16/09/93 */
2584
2585    /* Faz balanceamento da arvore */
2586    if (ifl_balan) {
2587        for (treecase=0;treecase<2;treecase++) {
2588            xroot=invp->cn[treecase].posrx;
2589            xliv=invp->cn[treecase].liv;
2590            balance_btree(dbxp,invp,xliv,xroot,treecase);
2591        }
2592    }
2593
2594    cntwrit(dbxp);
2595    invflush(dbnp);
2596
2597    trmifupd=0; /* reset IFUPDXLD */
2598   
2599     if (tell > 0) {
2600           fprintf(stdout,"+++ %ld/%ld %d-byte keys/postings \n",nlids[0],nregs[0],LE1);
2601           fprintf(stdout,"+++ %ld/%ld %d-byte keys/postings \n",nlids[1],nregs[1],LE2);
2602     }
2603
2604    return(nregs[0]+nregs[1]);
2605}
2606#endif /* CICPP */
2607
2608#if CICPP
2609CIIFL :: CIIFL(CISISX * parm_cisisxp)
2610{
2611 cisisxp = parm_cisisxp;
2612 ifllk_gidbnp = NULL;
2613 print_step=0L;
2614 ifpbuff=NULL; 
2615}
2616#endif /* CICPP */
Note: See TracBrowser for help on using the browser.