GnuCOBOL  2.0
A free COBOL compiler
vbnodememio.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Trevor van Bremen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1,
7  * or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; see the file COPYING.LIB. If
16  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
17  * Boston, MA 02110-1301 USA
18  */
19 
20 #include "isinternal.h"
21 
22 #define TCC (' ') /* Trailing Compression Character */
23 
24 static char cvbnodetmp[VB_NODE_MAX];
25 
26 static int
27 iquicknodesave (const int ihandle, struct VBTREE *pstree, const off_t tnodenumber,
28  struct keydesc *pskeydesc, const int imode, const int iposn)
29 {
30  int idupslength = 0;
31  int ikeylength = pskeydesc->k_len;
32  int ilength, iposition, iresult;
33 
34  /* Sanity checks */
35  if (!pstree || !pstree->pskeylist[iposn]) {
36  return -1;
37  }
38  if (imode == 1 && !pstree->pskeylist[iposn]->iisnew) {
39  return -1;
40  }
41  /* Read in the node (hopefully from the cache too!) */
42  iresult = ivbblockread (ihandle, 1, tnodenumber, cvbnodetmp);
43  if (iresult) {
44  return iresult;
45  }
46  if (pskeydesc->k_flags & ISDUPS) {
47  idupslength = QUADSIZE;
48  }
49  ilength = inl_ldint (cvbnodetmp);
50  /* Is there enough free space in the node for an insertion? */
51  if (imode == 1
52  && ilength + 3 + ikeylength + idupslength + QUADSIZE >=
53  psvbfile[ihandle]->inodesize) {
54  return -1;
55  }
56  inl_stint (ilength + (imode * (ikeylength + idupslength + QUADSIZE)), cvbnodetmp);
57  /* Calculate position for insertion / deletion of key */
58 #if ISAMMODE == 1
59  iposition = INTSIZE + QUADSIZE + (iposn * (ikeylength + idupslength + QUADSIZE));
60 #else
61  iposition = INTSIZE + (iposn * (ikeylength + idupslength + QUADSIZE));
62 #endif
63  if (imode == 1) {
64  memmove (cvbnodetmp + iposition + ikeylength + idupslength + QUADSIZE,
65  cvbnodetmp + iposition, (size_t)(ilength - iposition));
66  memcpy (cvbnodetmp + iposition, pstree->pskeylist[iposn]->ckey, (size_t)ikeylength);
67  if (pskeydesc->k_flags & ISDUPS) {
68  inl_stquad (pstree->pskeylist[iposn]->tdupnumber,
69  cvbnodetmp + iposition + ikeylength);
70  }
71  inl_stquad (pstree->pskeylist[iposn]->trownode,
72  cvbnodetmp + iposition + ikeylength + idupslength);
73  } else {
74  if (ilength - (iposition + ikeylength + idupslength + QUADSIZE) > 0) {
75  memmove (cvbnodetmp + iposition,
76  cvbnodetmp + iposition + ikeylength + idupslength + QUADSIZE,
77  (size_t)(ilength - (iposition + ikeylength + idupslength + QUADSIZE)));
78  }
79  memset (cvbnodetmp + ilength - (ikeylength + QUADSIZE), 0,
80  (size_t)(ikeylength + idupslength + QUADSIZE));
81  }
82  iresult = ivbblockwrite (ihandle, 1, tnodenumber, cvbnodetmp);
83  if (iresult) {
84  return iresult;
85  }
86  return 0;
87 }
88 
89 static int
90 inewroot (const int ihandle, const int ikeynumber, struct VBTREE *pstree,
91  struct VBTREE *psnewtree, struct VBTREE *psroottree,
92  struct VBKEY *psrootkey[], off_t tnewnode1, off_t tnewnode2)
93 {
94  struct DICTINFO *psvbptr;
95  struct VBKEY *pskey;
96  int iresult;
97 
98  psvbptr = psvbfile[ihandle];
99  /* Fill in the content for the new root node */
100  psrootkey[0]->psnext = psrootkey[1];
101  psrootkey[1]->psnext = psrootkey[2];
102  psrootkey[2]->psprev = psrootkey[1];
103  psrootkey[1]->psprev = psrootkey[0];
104  psrootkey[0]->psparent = psrootkey[1]->psparent = psrootkey[2]->psparent = psroottree;
105  psrootkey[0]->pschild = pstree;
106  psrootkey[1]->pschild = psnewtree;
107  psrootkey[0]->trownode = tnewnode2;
108  psrootkey[1]->trownode = tnewnode1;
109  psrootkey[1]->iishigh = 1;
110  psrootkey[2]->iisdummy = 1;
111  memcpy (psrootkey[0]->ckey, pstree->pskeylast->psprev->ckey,
112  (size_t)psvbptr->pskeydesc[ikeynumber]->k_len);
113  psrootkey[0]->tdupnumber = pstree->pskeylast->psprev->tdupnumber;
114  vvbkeyvalueset (1, psvbptr->pskeydesc[ikeynumber], psrootkey[1]->ckey);
115  /*
116  * psroottree is the new ROOT node
117  * psnewtree is the new LEAF node
118  * pstree is the original node (saved in a new place)
119  */
120  psroottree->pskeyfirst = psrootkey[0];
121  psroottree->pskeycurr = psrootkey[0];
122  psroottree->pskeylast = psrootkey[2];
123  psroottree->tnodenumber = pstree->tnodenumber;
124  psroottree->ilevel = pstree->ilevel + 1;
125  psroottree->iisroot = 1;
126  psroottree->iistof = 1;
127  psroottree->iiseof = 1;
128  pstree->psparent = psroottree;
129  pstree->tnodenumber = tnewnode2;
130  psnewtree->psparent = psroottree;
131  psnewtree->tnodenumber = tnewnode1;
132  psnewtree->ilevel = pstree->ilevel;
133  psnewtree->pskeycurr = psnewtree->pskeyfirst;
134  psvbptr->pstree[ikeynumber] = psroottree;
135  for (pskey = pstree->pskeyfirst; pskey; pskey = pskey->psnext) {
136  if (pskey->pschild) {
137  pskey->pschild->psparent = pstree;
138  }
139  }
140  for (pskey = psnewtree->pskeyfirst; pskey; pskey = pskey->psnext) {
141  if (pskey->pschild) {
142  pskey->pschild->psparent = psnewtree;
143  }
144  }
145  iresult = ivbnodesave (ihandle, ikeynumber, psnewtree, psnewtree->tnodenumber, 0, 0);
146  if (iresult) {
147  return iresult;
148  }
149  iresult = ivbnodesave (ihandle, ikeynumber, pstree, pstree->tnodenumber, 0, 0);
150  if (iresult) {
151  return iresult;
152  }
153  pstree->iisroot = 0;
154  psnewtree->iisroot = 0;
155  pstree->iistof = 1;
156  psnewtree->iistof = 0;
157  pstree->iiseof = 0;
158  psnewtree->iiseof = 1;
159  return ivbnodesave (ihandle, ikeynumber, psroottree, psroottree->tnodenumber, 0, 0);
160 }
161 
162 static int
163 inodesplit (const int ihandle, const int ikeynumber, struct VBTREE *pstree,
164  struct VBKEY *pskeyhalfway)
165 {
166  struct DICTINFO *psvbptr;
167  struct VBKEY *pskey, *pskeytemp, *psholdkeycurr, *psnewkey;
168  struct VBKEY *psrootkey[3];
169  struct VBTREE *psnewtree, *psroottree = NULL;
170  off_t tnewnode1, tnewnode2 = 0;
171  int iresult;
172 
173  psnewtree = psvbtreeallocate (ihandle);
174  if (!psnewtree) {
175  return errno;
176  }
177  psnewtree->psparent = pstree;
178  psnewkey = psvbkeyallocate (ihandle, ikeynumber);
179  if (!psnewkey) {
180  return errno;
181  }
182  psvbptr = psvbfile[ihandle];
183  psrootkey[0] = NULL;
184  psrootkey[1] = NULL;
185  psrootkey[2] = NULL;
186  if (pstree->iisroot) {
187  psroottree = psvbtreeallocate (ihandle);
188  if (!psroottree) {
189  return errno;
190  }
191  psrootkey[0] = psvbkeyallocate (ihandle, ikeynumber);
192  if (!psrootkey[0]) {
193  return errno;
194  }
195  psrootkey[1] = psvbkeyallocate (ihandle, ikeynumber);
196  if (!psrootkey[1]) {
197  return errno;
198  }
199  psrootkey[2] = psvbkeyallocate (ihandle, ikeynumber);
200  if (!psrootkey[2]) {
201  return errno;
202  }
203  tnewnode2 = tvbnodeallocate (ihandle);
204  if (tnewnode2 == -1) {
205  return iserrno;
206  }
207  }
208  tnewnode1 = tvbnodeallocate (ihandle);
209  if (tnewnode1 == -1) {
210  return iserrno;
211  }
212 
213  if (pstree->iisroot) {
214  psnewtree->pskeylast = pstree->pskeylast;
215  pskey = pskeyhalfway->psnext;
216  psnewkey->psprev = pskey->psprev;
217  psnewkey->psparent = pskey->psparent;
218  psnewkey->iisdummy = 1;
219  pskey->psprev->psnext = psnewkey;
220  pskey->psprev = NULL;
221  pstree->pskeylast = psnewkey;
222  pstree->pskeycurr = pstree->pskeyfirst;
223  psnewtree->pskeyfirst = psnewtree->pskeycurr = pskey;
224  psnewtree->ilevel = pstree->ilevel;
225  psnewtree->psparent = pstree->psparent;
226  psnewtree->iiseof = pstree->iiseof;
227  pstree->iiseof = 0;
228  for (pskeytemp = pskey; pskeytemp; pskeytemp = pskeytemp->psnext) {
229  pskeytemp->psparent = psnewtree;
230  }
231  return inewroot (ihandle, ikeynumber, pstree, psnewtree, psroottree, psrootkey,
232  tnewnode1, tnewnode2);
233  } else {
234  psnewtree->pskeyfirst = psnewtree->pskeycurr = pstree->pskeyfirst;
235  psnewtree->pskeylast = psnewkey;
236  pstree->pskeyfirst = pstree->pskeycurr = pskeyhalfway->psnext;
237  pskeyhalfway->psnext->psprev = NULL;
238  pskeyhalfway->psnext = psnewkey;
239  psnewkey->psprev = pskeyhalfway;
240  psnewkey->psnext = NULL;
241  psnewkey->psparent = psnewtree; /* Doubtful */
242  psnewkey->iisdummy = 1;
243  for (pskey = psnewtree->pskeyfirst; pskey; pskey = pskey->psnext) {
244  pskey->psparent = psnewtree;
245  if (pskey->pschild) {
246  pskey->pschild->psparent = psnewtree;
247  }
248  }
249  psnewtree->ilevel = pstree->ilevel;
250  psnewtree->psparent = pstree->psparent;
251  /*
252  * psnewtree is the new LEAF node but is stored in the OLD node
253  * pstree is the original node and contains the HIGH half
254  */
255  psnewtree->tnodenumber = tnewnode1;
256  iresult = ivbnodesave (ihandle, ikeynumber, psnewtree, psnewtree->tnodenumber, 0, 0);
257  if (iresult) {
258  return iresult;
259  }
260  psnewtree->iistof = pstree->iistof;
261  iresult = ivbnodesave (ihandle, ikeynumber, pstree, pstree->tnodenumber, 0, 0);
262  if (iresult) {
263  return iresult;
264  }
265  pstree->iistof = 0;
266  psholdkeycurr = psvbptr->pskeycurr[ikeynumber];
267  psvbptr->pskeycurr[ikeynumber] =
268  psnewkey->psparent->psparent->pskeycurr;
269  iresult =
270  ivbkeyinsert (ihandle, pskeyhalfway->psparent->psparent, ikeynumber,
271  pskeyhalfway->ckey, tnewnode1, pskeyhalfway->tdupnumber,
272  psnewtree);
273  psvbptr->pskeycurr[ikeynumber] = psholdkeycurr;
274  if (iresult) {
275  return iresult;
276  }
277  psholdkeycurr->psparent->pskeycurr = psholdkeycurr;
278  }
279  return 0;
280 }
281 
282 /* Global functions */
283 
284 int
285 ivbnodeload (const int ihandle, const int ikeynumber, struct VBTREE *pstree,
286  const off_t tnodenumber, const int iprevlvl)
287 {
288  struct DICTINFO *psvbptr;
289  struct VBKEY *pskey, *pskeynext;
290  struct keydesc *pskeydesc;
291  char *pcnodeptr;
292 #if ISAMMODE == 1
293  off_t ttransnumber;
294 #endif
295  int icountlc = 0; /* Leading compression */
296  int icounttc = 0; /* Trailing compression */
297  int idups = 0, inodelen, iresult;
298  unsigned char cprevkey[VB_MAX_KEYLEN];
299  unsigned char chighkey[VB_MAX_KEYLEN];
300 
301  psvbptr = psvbfile[ihandle];
302  pskeydesc = psvbptr->pskeydesc[ikeynumber];
303  vvbkeyvalueset (0, pskeydesc, cprevkey);
304  vvbkeyvalueset (1, pskeydesc, chighkey);
305  iresult = ivbblockread (ihandle, 1, tnodenumber, cvbnodetmp);
306  if (iresult) {
307  return iresult;
308  }
309  if (iprevlvl != -1) {
310  if (*(cvbnodetmp + psvbptr->inodesize - 2) != iprevlvl - 1) {
311  return EBADFILE;
312  }
313  }
314  pstree->tnodenumber = tnodenumber;
315  pstree->ilevel = *(cvbnodetmp + psvbptr->inodesize - 2);
316  inodelen = inl_ldint (cvbnodetmp);
317 #if ISAMMODE == 1
318  pcnodeptr = cvbnodetmp + INTSIZE + QUADSIZE;
319  ttransnumber = inl_ldquad (cvbnodetmp + INTSIZE);
320  if (ttransnumber == pstree->ttransnumber) {
321  return 0;
322  }
323 #else
324  pcnodeptr = cvbnodetmp + INTSIZE;
325 #endif
326  for (pskey = pstree->pskeyfirst; pskey; pskey = pskeynext) {
327  if (pskey->pschild) {
328  vvbtreeallfree (ihandle, ikeynumber, pskey->pschild);
329  }
330  pskey->pschild = NULL;
331  pskeynext = pskey->psnext;
332  vvbkeyfree (ihandle, ikeynumber, pskey);
333  }
334  pstree->pskeyfirst = pstree->pskeycurr = pstree->pskeylast = NULL;
335  pstree->ikeysinnode = 0;
336  while (pcnodeptr - cvbnodetmp < inodelen) {
337  pskey = psvbkeyallocate (ihandle, ikeynumber);
338  if (!pskey) {
339  return errno;
340  }
341  if (!idups) {
342  if (pskeydesc->k_flags & LCOMPRESS) {
343 #if ISAMMODE == 1
344  icountlc = inl_ldint (pcnodeptr);
345  pcnodeptr += INTSIZE;
346 #else
347  icountlc = *(pcnodeptr);
348  pcnodeptr++;
349 #endif
350  }
351  if (pskeydesc->k_flags & TCOMPRESS) {
352 #if ISAMMODE == 1
353  icounttc = inl_ldint (pcnodeptr);
354  pcnodeptr += INTSIZE;
355 #else
356  icounttc = *(pcnodeptr);
357  pcnodeptr++;
358 #endif
359  }
360  memcpy (cprevkey + icountlc, pcnodeptr,
361  (size_t)(pskeydesc->k_len - (icountlc + icounttc)));
362  memset (cprevkey + pskeydesc->k_len - icounttc, TCC, (size_t)icounttc);
363  pcnodeptr += pskeydesc->k_len - (icountlc + icounttc);
364  }
365  if (pskeydesc->k_flags & ISDUPS) {
366  pskey->tdupnumber = inl_ldquad (pcnodeptr);
367  pcnodeptr += QUADSIZE;
368  } else {
369  pskey->tdupnumber = 0;
370  }
371  if (pskeydesc->k_flags & DCOMPRESS) {
372  if (*pcnodeptr & 0x80) {
373  idups = 1;
374  } else {
375  idups = 0;
376  }
377  *pcnodeptr &= ~0x80;
378  }
379  pskey->trownode = inl_ldquad (pcnodeptr);
380  pcnodeptr += QUADSIZE;
381  pskey->psparent = pstree;
382  if (pstree->pskeyfirst) {
383  pstree->pskeylast->psnext = pskey;
384  } else {
385  pstree->pskeyfirst = pstree->pskeycurr = pskey;
386  }
387  pstree->pskeylist[pstree->ikeysinnode] = pskey;
388  pstree->ikeysinnode++;
389  pskey->psprev = pstree->pskeylast;
390  pstree->pskeylast = pskey;
391  memcpy (pskey->ckey, cprevkey, (size_t)pskeydesc->k_len);
392  }
393  if (pstree->ilevel) {
394  pstree->pskeylast->iishigh = 1;
395  memcpy (pstree->pskeylast->ckey, chighkey, (size_t)pskeydesc->k_len);
396  }
397  pskey = psvbkeyallocate (ihandle, ikeynumber);
398  if (!pskey) {
399  return errno;
400  }
401  pskey->psparent = pstree;
402  pskey->iisdummy = 1;
403  if (pstree->pskeyfirst) {
404  pstree->pskeylast->psnext = pskey;
405  } else {
406  pstree->pskeyfirst = pstree->pskeycurr = pskey;
407  }
408  pskey->psprev = pstree->pskeylast;
409  pstree->pskeylast = pskey;
410  pstree->pskeylist[pstree->ikeysinnode] = pskey;
411  pstree->ikeysinnode++;
412  return 0;
413 }
414 
415 int
416 ivbnodesave (const int ihandle, const int ikeynumber, struct VBTREE *pstree,
417  const off_t tnodenumber, const int imode, const int iposn)
418 {
419  struct DICTINFO *psvbptr;
420  unsigned char *pckeyendptr, *pcnodeptr, *pcnodehalfway;
421  unsigned char *pcnodeend, *pcprevkey = NULL;
422  struct VBKEY *pskey, *pskeyhalfway = NULL;
423  struct keydesc *pskeydesc;
424  int icountlc = 0, /* Leading compression */
425  icounttc = 0, /* Trailing compression */
426  ilasttc = 0, ikeylen, imaxtc, iresult;
427 
428  psvbptr = psvbfile[ihandle];
429  pskeydesc = psvbptr->pskeydesc[ikeynumber];
430  /*
431  * If it's an INSERT into a node or a DELETE from a node
432  * *AND*
433  * there's no compression
434  * *THEN*
435  * We can *TRY* to do a quick and dirty insertion / deletion instead!
436  * However, it's still possible that we have insufficient free space
437  * so we *MAY* still need to continue.
438  */
439  if (pstree->ilevel) {
440  if (pstree->pskeylast->psprev) {
441  pstree->pskeylast->psprev->iishigh = 1;
442  }
443  }
444  if (imode && !(pskeydesc->k_flags & (DCOMPRESS | TCOMPRESS | LCOMPRESS))) {
445  if (iquicknodesave (ihandle, pstree, tnodenumber, pskeydesc, imode, iposn) == 0) {
446  return 0;
447  }
448  }
449  pcnodehalfway = (ucharptr)cvbnodetmp + (psvbptr->inodesize / 2);
450  pcnodeend = (ucharptr)cvbnodetmp + psvbptr->inodesize - 2;
451  memset (cvbnodetmp, 0, VB_NODE_MAX);
452 #if ISAMMODE == 1
454  cvbnodetmp + INTSIZE);
455  pcnodeptr = (ucharptr)cvbnodetmp + INTSIZE + QUADSIZE;
456 #else
457  pcnodeptr = (ucharptr)cvbnodetmp + INTSIZE;
458 #endif
459  *pcnodeend = pstree->ilevel;
460  pstree->ikeysinnode = 0;
461  for (pskey = pstree->pskeyfirst; pskey && !pskey->iisdummy;
462  pskey = pskey->psnext) {
463  pstree->pskeylist[pstree->ikeysinnode] = pskey;
464  pstree->ikeysinnode++;
465  if (!pskeyhalfway) {
466  if (pcnodeptr >= pcnodehalfway) {
467  pskeyhalfway = pskey->psprev;
468  }
469  }
470  ikeylen = pskeydesc->k_len;
471  if (pskeydesc->k_flags & TCOMPRESS) {
472  ilasttc = icounttc;
473  icounttc = 0;
474  pckeyendptr = pskey->ckey + ikeylen - 1;
475  while (*pckeyendptr-- == TCC && pckeyendptr != pskey->ckey) {
476  icounttc++;
477  }
478 #if ISAMMODE == 1
479  ikeylen += INTSIZE - icounttc;
480 #else
481  ikeylen += 1 - icounttc;
482 #endif
483  }
484  if (pskeydesc->k_flags & LCOMPRESS) {
485  icountlc = 0;
486  if (pskey != pstree->pskeyfirst) {
487  imaxtc = pskeydesc->k_len - (icounttc >
488  ilasttc ? icounttc : ilasttc);
489  for (; pskey->ckey[icountlc] == pcprevkey[icountlc]
490  && icountlc < imaxtc; icountlc++) ;
491  }
492 #if ISAMMODE == 1
493  ikeylen += INTSIZE - icountlc;
494 #else
495  ikeylen += 1 - icountlc;
496 #endif
497  if (pskey->iishigh && pskeydesc->k_flags && LCOMPRESS) {
498  icountlc = pskeydesc->k_len;
499  icounttc = 0;
500 #if ISAMMODE == 1
501  if (pskeydesc->k_flags && TCOMPRESS) {
502  ikeylen = INTSIZE * 2;
503  } else {
504  ikeylen = INTSIZE;
505  }
506 #else
507  if (pskeydesc->k_flags && TCOMPRESS) {
508  ikeylen = 2;
509  } else {
510  ikeylen = 1;
511  }
512 #endif
513  if (pskeydesc->k_flags & DCOMPRESS) {
514  ikeylen = 0;
515  }
516  }
517  }
518  if (pskeydesc->k_flags & ISDUPS) {
519  ikeylen += QUADSIZE;
520  /* If the key is a duplicate and it's not first in node */
521  if (pskey->iishigh || (pskey != pstree->pskeyfirst
522  && !memcmp (pskey->ckey, pcprevkey, (size_t)pskeydesc->k_len))) {
523  if (pskeydesc->k_flags & DCOMPRESS) {
524  ikeylen = QUADSIZE;
525  }
526  }
527  }
528  ikeylen += QUADSIZE;
529  /* Split? */
530  if (pcnodeptr + ikeylen >= pcnodeend - 1) {
531  if (pstree->pskeylast->psprev->iisnew) {
532  pskeyhalfway = pstree->pskeylast->psprev->psprev;
533  }
534  if (pstree->pskeylast->psprev->iishigh
535  && pstree->pskeylast->psprev->psprev->iisnew) {
536  pskeyhalfway = pstree->pskeylast->psprev->psprev->psprev;
537  }
538  iresult = inodesplit (ihandle, ikeynumber, pstree, pskeyhalfway);
539  return iresult;
540  }
541  if (((ikeylen == (QUADSIZE * 2))
542  && ((pskeydesc->k_flags & (DCOMPRESS | ISDUPS)) == (DCOMPRESS | ISDUPS)))
543  || (pskeydesc->k_flags & DCOMPRESS && !(pskeydesc->k_flags & ISDUPS)
544  && ikeylen == QUADSIZE)) {
545  *(pcnodeptr - QUADSIZE) |= 0x80;
546  } else {
547  if (pskeydesc->k_flags & LCOMPRESS) {
548 #if ISAMMODE == 1
549  inl_stint (icountlc, pcnodeptr);
550  pcnodeptr += INTSIZE;
551 #else
552  *pcnodeptr++ = icountlc;
553 #endif
554  }
555  if (pskeydesc->k_flags & TCOMPRESS) {
556 #if ISAMMODE == 1
557  inl_stint (icounttc, pcnodeptr);
558  pcnodeptr += INTSIZE;
559 #else
560  *pcnodeptr++ = icounttc;
561 #endif
562  }
563  if (icountlc != pskeydesc->k_len) {
564  pcprevkey = pskey->ckey + icountlc;
565  imaxtc = pskeydesc->k_len - (icountlc + icounttc);
566  while (imaxtc--) {
567  *pcnodeptr++ = *pcprevkey++;
568  }
569  }
570  pcprevkey = pskey->ckey;
571  }
572  if (pskeydesc->k_flags & ISDUPS) {
573  inl_stquad (pskey->tdupnumber, pcnodeptr);
574  pcnodeptr += QUADSIZE;
575  }
576  inl_stquad (pskey->trownode, pcnodeptr);
577  pcnodeptr += QUADSIZE;
578  }
579  if (pskey && pskey->iisdummy) {
580  pstree->pskeylist[pstree->ikeysinnode] = pskey;
581  pstree->ikeysinnode++;
582  }
583  inl_stint ((int)((ucharptr)pcnodeptr - (ucharptr)cvbnodetmp), cvbnodetmp);
584  return ivbblockwrite (ihandle, 1, tnodenumber, cvbnodetmp);
585 }
unsigned char iishigh
Definition: isinternal.h:331
static int inl_ldint(void *pclocation)
Definition: isinternal.h:170
static char cvbnodetmp[4096]
Definition: vbnodememio.c:24
void vvbkeyvalueset(const int ihigh, struct keydesc *pskeydesc, unsigned char *pckeyvalue)
Definition: vbkeysio.c:659
struct VBTREE * psvbtreeallocate(const int ihandle)
Definition: vbmemio.c:88
struct VBTREE * pschild
Definition: isinternal.h:327
struct VBKEY * pskeylast
Definition: isinternal.h:341
int ivbblockread(const int ihandle, const int iisindex, const off_t tblocknumber, char *cbuffer)
Definition: vblowlevel.c:137
unsigned char ckey[1]
Definition: isinternal.h:334
struct VBKEY * psvbkeyallocate(const int ihandle, const int ikeynumber)
Definition: vbmemio.c:120
unsigned char iisroot
Definition: isinternal.h:347
int ivbnodeload(const int ihandle, const int ikeynumber, struct VBTREE *pstree, const off_t tnodenumber, const int iprevlvl)
Definition: vbnodememio.c:285
unsigned char iisdummy
Definition: isinternal.h:332
unsigned char * ucharptr
Definition: isinternal.h:150
static int inodesplit(const int ihandle, const int ikeynumber, struct VBTREE *pstree, struct VBKEY *pskeyhalfway)
Definition: vbnodememio.c:163
#define VB_NODE_MAX
Definition: isinternal.h:288
static void inl_stint(int ivalue, void *pclocation)
Definition: isinternal.h:190
struct VBTREE * psparent
Definition: isinternal.h:326
struct VBKEY * pskeycurr
Definition: isinternal.h:342
EC ARGUMENT EC EC BOUND EC BOUND EC BOUND EC BOUND TABLE EC DATA EC DATA EC DATA PTR NULL
Definition: exception.def:95
off_t tnodenumber
Definition: isinternal.h:343
off_t ttransnumber
Definition: isinternal.h:344
static int iquicknodesave(const int ihandle, struct VBTREE *pstree, const off_t tnodenumber, struct keydesc *pskeydesc, const int imode, const int iposn)
Definition: vbnodememio.c:27
struct VBKEY * pskeycurr[32]
Definition: isinternal.h:448
struct DICTNODE sdictnode
Definition: isinternal.h:444
off_t trownode
Definition: isinternal.h:328
#define TCC
Definition: vbnodememio.c:22
unsigned char iiseof
Definition: isinternal.h:349
unsigned int ikeysinnode
Definition: isinternal.h:346
void vvbkeyfree(const int ihandle, const int ikeynumber, struct VBKEY *pskey)
Definition: vbmemio.c:172
struct VBKEY * psprev
Definition: isinternal.h:325
struct DICTINFO * psvbfile[128+1]
Definition: vblowlevel.c:23
#define QUADSIZE
Definition: isinternal.h:108
char ctransnumber[8]
Definition: isinternal.h:377
off_t tdupnumber
Definition: isinternal.h:329
int ivbkeyinsert(const int ihandle, struct VBTREE *pstree, const int ikeynumber, unsigned char *pckeyvalue, off_t trownode, off_t tdupnumber, struct VBTREE *pschild)
Definition: vbkeysio.c:727
int ivbblockwrite(const int ihandle, const int iisindex, const off_t tblocknumber, const char *cbuffer)
Definition: vblowlevel.c:167
void vvbtreeallfree(const int ihandle, const int ikeynumber, struct VBTREE *pstree)
Definition: vbmemio.c:105
struct VBKEY * pskeylist[512]
Definition: isinternal.h:352
static void inl_stquad(off_t tvalue, void *pclocation)
Definition: isinternal.h:260
int ivbnodesave(const int ihandle, const int ikeynumber, struct VBTREE *pstree, const off_t tnodenumber, const int imode, const int iposn)
Definition: vbnodememio.c:416
unsigned int ilevel
Definition: isinternal.h:345
struct VBTREE * pstree[32]
Definition: isinternal.h:446
struct VBKEY * pskeyfirst
Definition: isinternal.h:340
struct VBTREE * psparent
Definition: isinternal.h:339
unsigned char iisnew
Definition: isinternal.h:330
struct keydesc * pskeydesc[32]
Definition: isinternal.h:445
unsigned char iistof
Definition: isinternal.h:348
static off_t inl_ldquad(void *pclocation)
Definition: isinternal.h:238
struct VBKEY * psnext
Definition: isinternal.h:324
static int inewroot(const int ihandle, const int ikeynumber, struct VBTREE *pstree, struct VBTREE *psnewtree, struct VBTREE *psroottree, struct VBKEY *psrootkey[], off_t tnewnode1, off_t tnewnode2)
Definition: vbnodememio.c:90
off_t tvbnodeallocate(const int ihandle)
Definition: vbindexio.c:221
int iserrno
Definition: vbmemio.c:27
int inodesize
Definition: isinternal.h:402