a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
aicore2.cpp
gehe zur Dokumentation dieser Datei
1 // aicore2.cpp/.c : Kernfunktionen Teil 2; ident. f. c und c++
2 // 1991 / 1995-05-23 aC EA / 2011 Alles interne Funktionen!
3 // Copyright 2011 Universitätsbibliothek Braunschweig, more see bottom
4 
5 // Hinweis: fuer einige Fktnn gibt es SngUser-Versionen in aicore2s.cpp
6 
7 #include "includes.h" // einige Konventionen
8 #include "ai-const.h" // allg. Konstanten
9 #include "aisetup.h" // allg. Einstellungen
10 #include "aierrors.h" // Fehlernummern
11 #include "aistruc.h" // Strukturen
12 #include "aiglobal.h" // glob. Variablen
13 #include "aideclar.h" // Funktionsdeklarationen
14 
15 #include "string.h"
16 
17 //--------------------------------------------------
18 /* aifkno() Sucht einen Knoten, ob Blatt oder nicht.
19  Return: Relative Position des schluessels aikey im Knoten
20  aiG_pos wird auf diesen Wert gesetzt
21  aiG_cpr zeigt die Art des Vergleichs an:
22  Wenn kein Treffer, dann Return -2,
23  wenn aikey jenseits des letzten Schl. im Kn., dann -1
24 */
25 
26 SHORT aifkno(aiTRSTR *aibloc, CHAR *aikey, CHAR ai_str)
27 // aibloc Zeiger zum Knoten
28 // aikey; Zeiger zum Schl., der gesucht werden soll
29 // ai_str; Art der Suche: E == eq L == le S == le
30 {
31  SHORT astrg,estrg,size,poff;
32  aiINDX *aixf;
33 
34  aixf = aiG_ky + aibloc->kynum; // Zeiger zur Schl.Nummer
35 
36  astrg = 1;
37  estrg = aibloc->ckyv;
38  aiG_cpra = poff = 0;
39 
40 // Vergl. mit dem hohen Schl.Wert
41  if((aibloc->lfflg == BLATT &&
42  (compar(aikey,aidathi(aibloc),aixf) /*(strcmp(aikey,aidathi(aibloc))*/ > 0 ||
43  (ai_str == 'S' && !estrg && aibloc->rgtkey))) ||
44  (aibloc->lfflg == NBLATT && !aibloc->cprv &&
45  compar(aikey,aidatpoi(aibloc,estrg),aixf)
46  /* strcmp(aikey,aidatpoi(aibloc,estrg)) */ > 0))
47  {
48 // srcval groesser als groesster im Knoten
49  aiG_cpr = 1;
50  aiG_pos = 0;
51  return(-1);
52  }
53 
54 // Knoten leer?
55  if(!estrg)
56  {
57  aiG_pos = 0;
58  aiG_cpr = -1;
59  return(-2);
60  }
61 
62  if(aibloc->kypst)
63  {
64  if(aibloc->rglfflg & AI_NRML)
65  poff = sizeof(PTRL);
66  aiG_cpra = compar(aikey,aibloc->kyxpns + poff,aixf);
67  aiG_sufc = aibloc->sffct;
68  if(aiG_cpra > 0)
69  astrg = aibloc->kypst + 1;
70  else if(aiG_cpra == 0)
71  {
72  aiG_cpr = 0;
73  aiG_cpra = -1;
74  return(aiG_pos = aibloc->kypst);
75  }
76  else
77  aiG_cpra = 0;
78  }
79 
80 // restliche Faelle sequentiell durchpruefen
81 
82  aiG_pos = astrg;
83  while(aiG_pos <= estrg)
84  {
85  aiG_cpr = compar(aikey,aidatpoi(aibloc,aiG_pos),aixf);
86  if(aiG_cpr > 0)
87  {
88  aiG_cpra = aiG_cpr;
89  aiG_sufc = aibloc->sffct;
90  }
91  else if(aiG_cpr < 0 && ai_str == 'E')
92  return(-2);
93  else
94  return(aiG_pos);
95  aiG_pos++;
96  }
97  if((ai_str == 'S' && aibloc->rgtkey) || (aibloc->cprv && aibloc->lfflg == NBLATT))
98  {
99  aiG_cpr = 1;
100  aiG_pos = 0;
101  return(-1);
102  }
103  else
104  {
105  aiG_cpr = aiG_cpra;
106  aiG_pos = aibloc->ckyv + 1;
107  return(-2);
108  }
109 }
110 
111 /* aiknoget() schaut im Puffer nach dem Knoten knot/aixf.
112  Return: Zeiger zum Puffer.
113  Der am laengsten nicht benutzte Knoten fliegt raus, der angeforderte
114  kommt in den geleerten Puffer, dessen Zeiger wird zurueckgegeben
115 */
116 
118 // knot; Nummer des angeforderten Knotens
119 // aixf; Schluesselzeiger
120 {
121 // aiTRSTR *aidatlru(); // liefert lru knoten
122 // SHORT aiknord(); // liest einen Knoten
123 // void aipraxr(); // Schreiben, wenn Aenderungen passiert sind
124 
125 #ifdef aiIMMED
126  aiDATEI *ainmb;
127 #endif
128  aiTRSTR *aigetf;
129  aiTRSTR *fbloc;
130 
131  SHORT i; // counter
132  uSHORT ailuse; // Speicher fuer den lru Knoten
133 
134  if(knot == aiNODNUL)
135  aiAbort(237);
136  aigetf = fbloc = aiG_tre;
137  ailuse = fbloc->acctr;
138  i = 0;
139  while(i++ < aiG_blocmx)
140  {
141  if(fbloc->knotid == knot && fbloc->kynum == aixf->usrfn)
142  {
143 
144 #ifdef aiIMMED
145  if(fbloc->coruf == 'y')
146  aiAbort(208);
147  ainmb = aixf - aixf->regnm;
148  if((ainmb->fmod & aiMULTI) &&
149  aiknord(fbloc,knot,aixf))
150  return(0);
151 #endif
152 
153  aipraxr(fbloc); // Knoten gefunden, kein Upd.Flag
154  return(fbloc);
155  }
156  if(fbloc->acctr < ailuse) /* aigetf auf aibloc mit
157  niedrigstem acctr setzen */
158  ailuse = (aigetf = fbloc)->acctr;
159  ++fbloc;
160  }
161 
162 // Knoten in aiblocs nicht gefunden. Lese Knoten in den lru aibloc
163 
164  if((fbloc = aidatlru(aigetf)) == 0) // Dann Fehler in aidatlru
165  return(0);
166  if(aiknord(fbloc,knot,aixf)) // Dann Fehler in aiknord
167  return(0);
168  return(fbloc);
169 }
170 
171 
172 /* --------------------------------------------------------------------
173  Liefere Zeiger auf aibloc mit dem Inhalt lru.
174  Wenn lru Block einen upgedatgeten Knoten enthaelg ,schreibe ihn in
175  die zugehoerige Indexdatei
176 */
177 
179 { // falls aigetf!=0, dann Zeiger auf lru aibloc
180  SHORT i; // Zaehler
181  aiTRSTR *fbloc;// Zeiger auf einen aibloc
182  uSHORT ailuse; // Zaehler des aibloc mit der niedrigsten
183  // Knotennummer
184 
185  if(!aigetf) // lru aibloc noch nicht ermittelt
186  {
187  aigetf = fbloc = aiG_tre;
188  ailuse = fbloc->acctr;
189  i = 1; ++fbloc;
190  while(i++ < aiG_blocmx)
191  {
192  if(fbloc->acctr < ailuse)
193  ailuse = (aigetf = fbloc)->acctr;
194  ++fbloc;
195  }
196  }
197 
198 
199  if(aigetf->coruf == 'y') // lru Knoten wurde geaendert. Speichern!
200  if(aiknowri(aigetf)) // Dann Fehlermeldung
201  return((aiTRSTR *)NULL);
202  return(aigetf); // lru aibloc liefern
203 }
204 
205 
206 // ---------------------------------------------
207 // Erhoehe aibloc Alter und pruefe auf Aenderung
208 
209 void aipraxr(aiTRSTR *aibloc)
210 {
211  aiTRSTR *aitemp;
212  SHORT i;
213  STATC uSHORT aimndage;
214 
215  if(++aiG_age) // Dann hat aibloc Alter sich nicht geaendert
216  aibloc->acctr = aiG_age;
217  else // aibloc Alter geaendert. Alle betr. aiblocs aendern
218  {
219  aitemp = aiG_tre;
220  aimndage = aiMXA;
221  i = 0;
222  while(i++ < aiG_blocmx)
223  {
224  if(aitemp->acctr < aimndage && aitemp->acctr)
225  aimndage = aitemp->acctr;
226  ++aitemp;
227  }
228  aiG_age = aiMXA - (--aimndage);
229  aitemp = aiG_tre;
230  i = 0;
231  while(i++ < aiG_blocmx)
232  {
233  if(aitemp->acctr)
234  aitemp->acctr -= aimndage;
235  ++aitemp;
236  }
237  aibloc->acctr = ++aiG_age;
238  }
239 }
240 
241 
242 /* --------------------------------------------------------------------
243  Hole einen Knoten aus der Indexdatei aixf nach aibloc.
244  Liefert Nicht-Null wenn Fehler
245 */
246 
247 SHORT aiknord(aiTRSTR *aibloc,RECNR knot, aiINDX *aixf)
248 {
249  aiDATEI *ainmb;
250 
251 
252 // Aendern der Statuswerte im Header
253 
254  aibloc->knotid = knot;
255  aibloc->kynum = aixf->usrfn;
256  aibloc->coruf = 'n';
257  aibloc->kylg = aixf->kylgth;
258  aibloc->cprv = aixf->ftyf;
259  aibloc->kypst = aibloc->realg = aibloc->fstbyt = 0;
260  aipraxr(aibloc);
261 
262 // Knoten in aibloc einlesen
263 
264  if(aixf->regnm > 0)
265  ainmb = aixf - aixf->regnm;
266  else
267  ainmb = aixf;
268 
269  if(airw(aiREAD,ainmb,knot,aibloc->kntptr,ainmb->knotsz))
270  return(aiG_fhln);
271 
272 // Hole Knotenstatus in den Bereich aiTRSTR
273 
274  aicopy((char *)&aibloc->rgtkey,aibloc->kntptr,aiSTAT);
275 
276 
277 
278 
279 #ifdef HITOLO
280  ai_flip((CHAR *)&aibloc->rgtkey,6);
281  aiwritrv((CHAR *)&aibloc->rgtkey,2);
282 #endif
283 
284 // Registernr pruefenr
285 
286  if(aibloc->regnr != aixf->regnm)
287  aiAbort(231);
288 
289 // ist dieser Knoten ein Blatt?
290  if(aibloc->lfflg == BLATT)
291  {
292  aibloc->mxkeys = aixf->maxkv;
293  aibloc->mxbyt = aixf->kylgmx;
294  aibloc->rglfflg = AI_DBLY;
295  }
296  else
297  {
298  aibloc->mxkeys = aixf->maxkn;
299  aibloc->mxbyt = aixf->kybmx;
300  aibloc->rglfflg = AI_DBLN;
301  }
302 
303  return(FHLNUL);
304 }
305 
306 
307 // -------------------------------------
308 // aigrtrot() liefert Knotennr d. Wurzel
309 
311 {
312 #ifdef aiIMMED
313  aiDATEI *ainmb;
314 
315  ainmb = aixf - aixf->regnm;
316  if((ainmb->fmod & aiMULTI) && aiprefrd(aixf - aixf->regnm))
317  return(aiDRNULL);
318 #endif
319 
320  return(aixf->wurz);
321 }
322 
323 
324 /* --------------------------------------------------------------------
325  Liefert Zeiger auf Schluessel in bestimmter Pos. von aibloc
326 */
327 
329  // aiTRSTR = Tree Structure, s. aistruc.h
330 
331 {
332  return(aivlxpr(aibloc,aiG_pos));
333 }
334 
336 {
337  SHORT i;
338 
339  i = aibloc->kylg+2;
340 
341  if(aibloc->rglfflg & AI_NRML)
342  return(aibloc->knptr + (aibloc->mxkeys - 1) *
343  (i + sizeof(PTRL)) + sizeof(PTRL));
344  else
345  return(aibloc->knptr + (aibloc->mxkeys - 1) * i);
346 }
347 
348 
349 /* -------------------------
350  Liefert Zeiger auf Knoten
351 */
352 
354 
355 {
356  char *tp;
357  if(aibloc->rglfflg == AI_DBLY)
358  aiAbort(209);
359  aicopy((char *)&tp,(aidatpoi(aibloc,aiG_pos)) - sizeof(PTRL),sizeof(PTRL));
360 #ifdef HITOLO
361  ai_exchg((CHAR *)&tp,sizeof(PTRL));
362 #endif
363  return((RECNR) tp);
364 }
365 
366 // ----------------------
367 // Liefert Zeiger auf drn
368 
369 
370 #ifndef HITOLO
371 
373 
374 {
375  CHAR *tp,*pp;
376  SHORT i;
377  PTRL pntr;
378 
379  pp = (CHAR *) &pntr;
380  tp = aidatpoi(aibloc,aiG_pos);
381  if(aibloc->rglfflg & AI_NRML)
382  aicopy(pp,tp - sizeof(PTRL),sizeof(PTRL));
383  else
384  {
385  tp += aibloc->kylg;
386  i = 0;
387  while(i++ < (int)sizeof(PTRL)) *pp++ = *--tp;
388  }
389  return(pntr);
390 }
391 
392 #else
393 
395 
396 {
397  CHAR *tp;
398  PTRL pntr;
399 
400  tp = aidatpoi(aibloc,aiG_pos) - sizeof(PTRL);
401  if(aibloc->rglfflg == AI_DBLY)
402  tp += aibloc->kylg;
403  aicopy(&pntr,tp,sizeof(PTRL));
404  if(aibloc->rglfflg != AI_DBLY)
405  ai_exchg((CHAR *)&pntr,sizeof(PTRL));
406  return(pntr);
407 }
408 
409 #endif
410 
412 {
413  SHORT kl,kls; // key kylgth, - drp suffix
414  SHORT implen,cntsfx;
415  CHAR *ip,*tp;
416  CHAR *rsult;
417 
418  if(n < 1 || n > (bp->ckyv + 1))
419  { /* Unnoetigen Abbruch vermeiden */
420  if (!*bp->knptr) return (CHAR *)"zzzzzz";
421  aiAbort(232);
422  }
423  kl = kls = bp->kylg;
424  rsult = bp->kyxpns;
425  if(bp->rglfflg & AI_NRML)
426  {
427  rsult += sizeof(PTRL);
428  if(bp->rglfflg == AI_DBLN)
429  kls = kl - sizeof(PTRL);
430  }
431  else
432  kls = kl - sizeof(PTRL);
433 
434  if(n == bp->kypst)
435  return(rsult);
436  else
437  ip = bp->knptr;
438 
439  if(n > bp->kypst)
440  {
441  ip += (bp->fstbyt + bp->realg);
442  n -= bp->kypst;
443  }
444  else
445  bp->kypst = bp->realg = bp->fstbyt = 0;
446 
447  while(n > 0)
448  {
449  tp = bp->kyxpns;
450  bp->kypst++;
451  n--;
452  bp->fstbyt += bp->realg;
453 
454  if(bp->rglfflg & AI_NRML)
455  {
456  aicopy(tp,ip,bp->realg = sizeof(PTRL));
457  tp += sizeof(PTRL);
458  ip += sizeof(PTRL);
459  }
460  else
461  bp->realg = 0;
462 
463  implen = 0;
464 // Frontkomprimierung
465  bp->realg++;
466  tp += (implen = (*ip++ & 0x00ff));
467 // Endkomprimierung
468  bp->realg++;
469  implen += (bp->sffct = cntsfx = (*ip++ & 0x00ff));
470 
471  if(implen > kls)
472  aiAbort(233);
473 
474  if(implen < kls)
475  {
476  bp->realg += (implen = kls - implen);
477  aicopy(tp,ip,implen);
478  tp += implen;
479  ip += implen;
480  }
481 
482  while(cntsfx-- > 0)
483  *tp++ = 0;
484  if(kls < kl)
485  {
486  aicopy(tp,ip,sizeof(PTRL));
487  ip += sizeof(PTRL);
488  bp->realg += sizeof(PTRL);
489  }
490  }
491  return(rsult);
492 }
493 
494 /*
495  Copyright 2011 Universitätsbibliothek Braunschweig
496 
497  Licensed under the Apache License, Version 2.0 (the "License");
498  you may not use this file except in compliance with the License.
499  You may obtain a copy of the License at
500 
501  http://www.apache.org/licenses/LICENSE-2.0
502 
503  Unless required by applicable law or agreed to in writing, software
504  distributed under the License is distributed on an "AS IS" BASIS,
505  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
506  See the License for the specific language governing permissions and
507  limitations under the License.
508 */
509