00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include <memory.h>
00084 #include <stdlib.h>
00085 #include "udanax.h"
00086
00087 extern int noishouldbother;
00088 extern int notakenephewnd;
00089 extern int noeatbrosnd;
00090
00091 typegranf granf;
00092 typespanf spanf;
00093
00094 typediskloaf zzzeroloaf;
00095 typeuberdiskloaf zzzerouberloaf;
00096
00097 static void subtreewriterecurs(Session *sess, typecuc *father);
00098 static void orglwritepart2(Session *sess, typecbc *orglcbcptr);
00099
00100 extern bool decrementusers();
00101
00109
00110 static void
00111 indiskexit()
00112 {
00113 if (decrementusers())
00114 return;
00115
00116 writeenfilades();
00117 closediskfile();
00118
00119 exit(0);
00120 }
00121
00129 void
00130 diskexit()
00131 {
00132 indiskexit();
00133 }
00134
00142
00143 void
00144 diskflush()
00145 {
00146 writeenfilades();
00147 initkluge((typecuc **) &granf, (typecuc **) &spanf);
00148 }
00149
00157
00158 void
00159 writeenfilades()
00160 {
00161 L("entering writeenfilades()\n");
00162
00163 typecbc temporgl;
00164
00165 temporgl.leftbroorfather = NULL;
00166 temporgl.modified = true;
00167 temporgl.cinfo.granstuff.orglstuff.orglincore = true;
00168 temporgl.cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber = GRANFDISKLOCATION;
00169 temporgl.cinfo.granstuff.orglstuff.diskorglptr.insidediskblocknumber = 0;
00170 temporgl.cinfo.granstuff.orglstuff.orglptr = (typecuc *) granf;
00171 ((typecuc *) granf)->leftbroorfather = (typecorecrum *) &temporgl;
00172
00173 L("about to orglwrite() GRANF\n");
00174 orglwrite(&temporgl);
00175 L("returned from orglwrite() GRANF\n");
00176
00177 temporgl.modified = true;
00178 temporgl.cinfo.granstuff.orglstuff.orglincore = true;
00179 temporgl.cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber = SPANFDISKLOCATION;
00180 temporgl.cinfo.granstuff.orglstuff.diskorglptr.insidediskblocknumber = 0;
00181 temporgl.cinfo.granstuff.orglstuff.orglptr = (typecuc *) spanf;
00182 ((typecuc *) spanf)->leftbroorfather = (typecorecrum *) &temporgl;
00183
00184 L("about to orglwrite() SPANF\n");
00185 orglwrite(&temporgl);
00186 L("returned from orglwrite() SPANF\n");
00187
00188 L("leaving writeenfilades()\n");
00189 }
00190
00191 #define hputinloaf(hp,lp,tp) ((void)humberput((int)(hp),(humber)(lp),(unsigned int *)(tp)),(lp)=((char*)lp)+*(tp))
00192
00193
00194
00195
00203 static void
00204 hputwiddsp(
00205 typecuc *ptr,
00206 char **loafptrptr)
00207 {
00208 unsigned int temp;
00209
00210 int nstreams = widsize(ptr->cenftype);
00211 typewid *wptr = &ptr->cdsp;
00212
00213 int i;
00214 for (i = 0; i < nstreams; ++i) {
00215 temp = tumblerfixedtoptr(&wptr->dsas[i], (humber) *loafptrptr);
00216 *loafptrptr += temp;
00217 }
00218
00219 wptr = &ptr->cwid;
00220
00221 for (i = 0; i < nstreams; ++i) {
00222 temp = tumblerfixedtoptr(&wptr->dsas[i], (humber) *loafptrptr);
00223 *loafptrptr += temp;
00224 }
00225 }
00226
00227
00228
00229
00230
00238 static void
00239 hputinfo(
00240 typecbc *ptr,
00241 char **loafptrptr)
00242 {
00243 unsigned int temp;
00244
00245 if (!is2dcrum((typecorecrum *) ptr)) {
00246 (void)humberput(ptr->cinfo.infotype, (humber) * loafptrptr, &temp);
00247 *loafptrptr += temp;
00248 if (ptr->cinfo.infotype == GRANTEXT) {
00249 (void)humberput((int) ptr->cinfo.granstuff.textstuff.textlength, (humber) * loafptrptr, &temp);
00250 *loafptrptr += temp;
00251
00252 movmem(ptr->cinfo.granstuff.textstuff.textstring, (*loafptrptr), ptr->cinfo.granstuff.textstuff.textlength);
00253 *loafptrptr += ptr->cinfo.granstuff.textstuff.textlength;
00254 return;
00255 } else if (ptr->cinfo.infotype == GRANORGL) {
00256 (void)humberput(ptr->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber, (humber) * loafptrptr, &temp);
00257 *loafptrptr += temp;
00258 (void)humberput(ptr->cinfo.granstuff.orglstuff.diskorglptr.insidediskblocknumber, (humber) * loafptrptr,
00259 &temp);
00260 *loafptrptr += temp;
00261
00262 return;
00263 } else if (ptr->cinfo.infotype == GRANNULL) {
00264 return;
00265 } else {
00266 L("weird infotype in hputinfo %d \n", ptr->cinfo.infotype);
00267 assert(0);
00268 return;
00269 }
00270 } else {
00271 if (ptr->height) {
00272
00273 } else {
00274 temp = tumblerfixedtoptr(&((type2dcbc *) ptr)->c2dinfo.homedoc, (humber) * loafptrptr);
00275 (*loafptrptr) += temp;
00276 }
00277 }
00278 }
00279
00280
00281
00289 static int
00290 varpackloaf(
00291 typecuc *father,
00292 typediskloaf *xloafptr,
00293 int refcount,
00294 int flag)
00295 {
00296 typecorecrum *ptr;
00297 int ret;
00298 unsigned int temp;
00299
00300 char *loafptr = (char *) xloafptr;
00301
00302 if (!flag) {
00303 if (!father || father->height == 0 || !loafptr) {
00304 dump((typecorecrum *) father);
00305 assert(0);
00306 }
00307
00308 assert(!father->leftson || !toomanysons(father));
00309
00310
00311 loafptr += 3;
00312 hputinloaf(false, loafptr, &temp);
00313 hputinloaf(father->height - 1, loafptr, &temp);
00314 hputinloaf(father->cenftype, loafptr, &temp);
00315 hputinloaf(father->numberofsons, loafptr, &temp);
00316 hputinloaf(refcount, loafptr, &temp);
00317
00318 } else {
00319
00320 loafptr += 3;
00321 hputinloaf(true, loafptr, &temp);
00322 hputinloaf(father->height, loafptr, &temp);
00323 hputinloaf(father->cenftype, loafptr, &temp);
00324 hputinloaf(1, loafptr, &temp);
00325 hputinloaf(refcount, loafptr, &temp);
00326
00327 hputwiddsp(father, &loafptr);
00328 hputinloaf(father->sonorigin.diskblocknumber, loafptr, &temp);
00329 hputinloaf(father->sonorigin.insidediskblocknumber, loafptr, &temp);
00330
00331 if (father->sonorigin.diskblocknumber == 0) {
00332
00333 assert(0);
00334 }
00335 if (father->sonorigin.diskblocknumber == DISKPTRNULL) {
00336
00337 assert(0);
00338 }
00339
00340 return (int) loafptr - (int) xloafptr;
00341 }
00342
00343 for (ptr = (typecorecrum *) findleftson(father); ptr; ptr = ptr->rightbro) {
00344 hputwiddsp((typecuc *) ptr, (char **)&loafptr);
00345 if (ptr->height != 0) {
00346 hputinloaf(((typecuc *) ptr)->sonorigin.diskblocknumber, loafptr, &temp);
00347 hputinloaf(((typecuc *) ptr)->sonorigin.insidediskblocknumber, loafptr, &temp);
00348
00349 if (((typecuc *) ptr)->sonorigin.diskblocknumber == 0) {
00350 dump(ptr);
00351 assert(0);
00352 }
00353
00354 if (((typecuc *) ptr)->sonorigin.diskblocknumber == DISKPTRNULL) {
00355 dump(ptr);
00356 assert(0);
00357 }
00358 } else
00359 hputinfo((typecbc *) ptr, &loafptr);
00360 }
00361
00362 ret = (int) loafptr - (int) xloafptr;
00363 humber3put(ret, (humber) xloafptr, &temp);
00364 return ret;
00365 }
00366
00374 static int
00375 packloaf(
00376 typecuc *father,
00377 typediskloaf *loafptr,
00378 int refcount,
00379 int flag)
00380 {
00381 return varpackloaf(father, loafptr, refcount, flag);
00382 }
00383
00391 static void
00392 uniqueoutloaf(
00393 typecuc *father,
00394 int refcount)
00395 {
00396 assert(father->modified);
00397
00398 typeuberdiskloaf loaf = zzzerouberloaf;
00399 if ((!father->leftson) && father->sonorigin.diskblocknumber != DISKPTRNULL) {
00400 findleftson(father);
00401
00402 }
00403
00404 int size = packloaf(father, (typediskloaf *) &loaf, refcount, 0);
00405
00406 int newloaf;
00407 father->sonorigin = partialdiskalloc(size, &newloaf);
00408
00409 unsigned int temp;
00410 humber3put(size, (humber) &loaf, &temp);
00411
00412
00413
00414 if (false && newloaf) {
00415 addallocatedloaftopartialallocedtables(father->sonorigin, size);
00416 }
00417
00418 writeloaf((typediskloaf *) &loaf, father->sonorigin, newloaf);
00419 father->modified = false;
00420 }
00421
00429 static void
00430 checkmodifiednotthere(
00431 typecuc *father,
00432 char *string)
00433 {
00434 return;
00435
00436 #ifndef DISTRIBUTION
00437 #ifdef UnDeFineD
00438 if (father->modified && (!father->leftson) ) {
00439 dump(father);
00440 L("in %s subtreewrite", string);
00441 assert(0);
00442 }
00443 #endif
00444 #endif
00445 }
00446
00454 static void
00455 subtreewriterecurs(
00456 Session *sess,
00457 typecuc *father)
00458 {
00459 if (!father || !father->height)
00460 assert(0);
00461
00462
00463 if (!father->modified) {
00464 if (father->sonorigin.diskblocknumber == DISKPTRNULL) {
00465 L("insubtreewriterecurs sonorigin == -1\n");
00466 dumpsubtree(father);
00467 assert(0);
00468 }
00469 loaffree(father);
00470 return;
00471 }
00472
00473
00474
00475 checkmodifiednotthere(father, "A");
00476 typecbc *ptr;
00477 for (ptr = (typecbc *) father->leftson; ptr; ptr = (typecbc *) ptr->rightbro) {
00478 if (ptr->height == 0 && ptr->cenftype == GRAN && ptr->cinfo.infotype != GRANTEXT && ptr->cinfo.infotype != GRANORGL && ptr->cinfo.infotype != GRANORGL && ptr->cinfo.infotype != GRANNULL) {
00479 L("bad infotypein subtreewriterecursive = %d\n", ptr->cinfo.infotype);
00480 dump((typecorecrum *) ptr);
00481 assert(0);
00482 }
00483
00484 if (ptr->height != 0)
00485 subtreewriterecurs(sess, (typecuc *) ptr);
00486 else if (ptr->cenftype == GRAN && ptr->height == 0 && ((typecbc *) ptr)->cinfo.infotype == GRANORGL)
00487 orglwritepart2(sess, ptr);
00488
00489 ptr->modified = false;
00490 }
00491
00492 if (father->modified) {
00493 checkmodifiednotthere(father, "B");
00494
00495 for (ptr = (typecbc *) father->leftson; ptr; ptr = (typecbc *) ptr->rightbro) {
00496 if (ptr->height > 0 && ((typecuc *) ptr)->sonorigin.diskblocknumber != DISKPTRNULL)
00497 changerefcount(((typecuc *) ptr)->sonorigin, 1);
00498 }
00499
00500 checkmodifiednotthere(father, "C");
00501 uniqueoutloaf(father, 0);
00502 }
00503
00504
00505 loaffree(father);
00506 }
00507
00515 static void
00516 deletewithgarbageddescendents(
00517 typediskloafptr diskptr,
00518 typecuc *father,
00519 bool deletefullcrumflag);
00520
00528 static void
00529 deletefullcrumandgarbageddescendents(
00530 typediskloafptr diskptr,
00531 bool deletefullcrumflag,
00532 typediskloaf *loafp,
00533 typediskloafptr newdiskptr)
00534 {
00535 if (diskptr.diskblocknumber == DISKPTRNULL)
00536 return;
00537
00538
00539
00540
00541 typecbc crum;
00542 typecbc *tempcbc = &crum;
00543 initcrum(0, GRAN, (typecorecrum *) &crum);
00544
00545 tempcbc->cinfo.infotype = GRANORGL;
00546 tempcbc->cinfo.granstuff.orglstuff.diskorglptr = diskptr;
00547
00548 typeuberrawdiskloaf crum2;
00549 if (deletefullcrumflag) {
00550 inorglinternal(tempcbc, &crum2);
00551
00552 } else {
00553 inorglinternal(tempcbc, &crum2);
00554
00555 diskset(newdiskptr.diskblocknumber);
00556 writeloaf(loafp, newdiskptr, false);
00557 }
00558
00559 tempcbc->cinfo.granstuff.orglstuff.orglptr->leftbroorfather = NULL;
00560 deletewithgarbageddescendents(diskptr, (typecuc *) tempcbc, deletefullcrumflag);
00561
00562 }
00563
00571 static void
00572 deletewithgarbageddescendents(
00573 typediskloafptr diskptr,
00574 typecuc *father,
00575 bool deletefullcrumflag)
00576 {
00577 typecbc *ptr;
00578 typediskloafptr ignoreddiskptr;
00579
00580 if (father->height > 0)
00581 ptr = (typecbc *) findleftson(father);
00582
00583
00584 if (!deletefullcrumflag || !changerefcount(diskptr, -1)) {
00585 if (father->height > 0) {
00586 for (; ptr; ptr = (typecbc *) findrightbro((typecorecrum *) ptr)) {
00587 if (ptr->height > 0)
00588 deletewithgarbageddescendents(((typecuc *) ptr)->sonorigin, (typecuc *) ptr, true);
00589 }
00590 } else if (father->cenftype == GRAN && ((typecbc *) father)->cinfo.infotype == GRANORGL
00591 && ((typecbc *) father)->cinfo.granstuff.orglstuff.orglincore
00592 && ((typecbc *) father)->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber != GRANFDISKLOCATION
00593 && ((typecbc *) father)->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber !=
00594 SPANFDISKLOCATION) {
00595 deletefullcrumandgarbageddescendents(((typecbc *) father)->cinfo.granstuff.orglstuff.diskorglptr, true,
00596
00597 (typediskloaf *) NULL, ignoreddiskptr);
00598 }
00599 }
00600
00601 }
00602
00610 static void
00611 orglwritepart2(
00612 Session *sess,
00613 typecbc *orglcbcptr)
00614 {
00615 L("beginning orglwritepart2()\n");
00616 assert(orglcbcptr != NULL);
00617
00618 typediskloaf loaf = zzzeroloaf;
00619
00620 typegranbottomcruminfo *infoptr = &orglcbcptr->cinfo;
00621 typecuc *orglptr = infoptr->granstuff.orglstuff.orglptr;
00622
00623 if (!orglcbcptr->modified && orglptr) {
00624 orglfree(orglptr);
00625 return;
00626 }
00627
00628 if (infoptr->granstuff.orglstuff.orglincore) {
00629 L("orglincore\n");
00630
00631 L("calling reserve()\n");
00632 reserve((typecorecrum *) orglcbcptr);
00633 L("returned from calling reserve()\n");
00634
00635 typediskloafptr olddiskptr = infoptr->granstuff.orglstuff.diskorglptr;
00636 L("calling subtreewriterecurs()\n");
00637 subtreewriterecurs(sess, orglptr);
00638 L("returned from calling subtreewriterecurs()\n");
00639
00640
00641
00642 int size = packloaf(orglptr, &loaf, 1, 1);
00643 unsigned int dummy;
00644 humber3put(size, (humber) &loaf, &dummy);
00645
00646 if (orglptr->cenftype == POOM) {
00647 L("cenftype == POOM\n");
00648
00649 int newloaf;
00650 typediskloafptr temploaf = partialdiskalloc(size, &newloaf);
00651 writeloaf(&loaf, temploaf, newloaf);
00652 changerefcount(temploaf, 1);
00653
00654 infoptr->granstuff.orglstuff.diskorglptr = temploaf;
00655
00656 deletefullcrumandgarbageddescendents(olddiskptr, true, (typediskloaf *) NULL, olddiskptr);
00657
00658 } else {
00659 L("cenftype != POOM\n");
00660
00661 if (diskheader.hasenftops) {
00662 deletefullcrumandgarbageddescendents(olddiskptr, false, &loaf, infoptr->granstuff.orglstuff.diskorglptr);
00663
00664 } else {
00665 writeloaf(&loaf, infoptr->granstuff.orglstuff.diskorglptr, true);
00666 }
00667 }
00668
00669
00670
00671 rejuvinate((typecorecrum *) orglcbcptr);
00672 orglfree(orglptr);
00673 }
00674 }
00675
00683 void
00684 orglwrite(
00685 typecbc *orglcbcptr)
00686 {
00687 assert(orglcbcptr != NULL);
00688
00689
00690 Session sess;
00691 orglwritepart2(&sess, orglcbcptr);
00692 sess.free();
00693 }
00694
00702 void
00703 subtreewrite(
00704 typecuc *father)
00705 {
00706 Session sess;
00707
00708
00709 subtreewriterecurs(&sess, father);
00710
00711 sess.free();
00712 }