struct GBD *DB_ViewGet(int vol, int block) // return gbd for blk { short s; // for func if ((block < 1) || (block > systab->vol[vol-1]->vollab->max_block)) { return NULL; // validate } level = 0; // where it goes volnum = vol; // need this writing = 0; // clear this s = SemOp(SEM_GLOBAL, READ); // write lock if (s < 0) // check error { return NULL; // quit if so } s = Get_block(block); // get it if (s >= 0) { blk[level]->last_accessed = MTIME(0)+86400; // push last access } if (curr_lock) { SemOp( SEM_GLOBAL, -curr_lock); // unlock the globals } return (s < 0) ? NULL : blk[level]; // return whatever }
short DB_Compress(mvar *var, int flags) // Compress global { int i; short s; int retlevel; // the ACTUAL level flags &= 15; // clear high bits s = Copy2local(var); // get local copy if (s < 0) { return s; // exit on error } bzero(rekey_blk, MAXREKEY * sizeof(u_int)); // clear that table bzero(rekey_lvl, MAXREKEY * sizeof(int)); // and that table bcopy(&db_var, var, sizeof(mvar)); // copy the data back s = Get_data(flags); // get to level 'flags' retlevel = level; // save real level if (!level) { return -ERRM7; // give up if nosuch } chunk = (cstring *) &iidx[idx[10]]; // point at the first bcopy(&chunk->buf[1], &var->slen, chunk->buf[1]+1); // save the real key while (TRUE) { bcopy(var, &db_var, sizeof(mvar)); // get next key writing = 0; // flag we are reading while (systab->vol[volnum - 1]->writelock) // check for write lock { i = sleep(5); // wait a bit if (partab.jobtab->attention) { return -(ERRZLAST+ERRZ51); // for <Control><C> } } // end writelock check if (partab.jobtab->attention) { return -(ERRZLAST+ERRZ51); // for <Control><C> } s = Get_data(retlevel); // get the block if ((s == -ERRM7) && (!db_var.slen)) // if first node { s = 0; // it exists } if (s == -ERRM7) // if key changed { if (blk[level]->mem->right_ptr) // if more { chunk = (cstring *) &iidx[idx[10]]; // point at the first bcopy(&chunk->buf[1], &db_var.slen, chunk->buf[1]+1); // save real key SemOp( SEM_GLOBAL, -curr_lock); // release global lock continue; // go again } SemOp( SEM_GLOBAL, -curr_lock); // release global lock return retlevel; // all done, exit } if (s < 0) { SemOp( SEM_GLOBAL, -curr_lock); // release global lock return s; // exit on error } if (!blk[level]->mem->right_ptr) // if no more { SemOp( SEM_GLOBAL, -curr_lock); // release global lock if ((retlevel == 2) && (!db_var.slen)) // if only block lvl 2 { s = Compress1(); // do that SemOp( SEM_GLOBAL, -curr_lock); // release write lock if (s < 0) { return s; // exit on error } } return retlevel; // all done, exit } level++; s = Get_block(blk[level - 1]->mem->right_ptr); if (s < 0) // if error { SemOp( SEM_GLOBAL, -curr_lock); // release global lock return s; // exit on error } i = ((blk[level-1]->mem->last_free*2 + 1 - blk[level-1]->mem->last_idx)*2) + ((blk[level]->mem->last_free*2 + 1 - blk[level]->mem->last_idx)*2); if (i < 1024) // if REALLY not enough space (btw: make this a param) { chunk = (cstring *) &iidx[idx[10]]; // point at first in RL bcopy(&chunk->buf[1], &var->slen, chunk->buf[1]+1); // save the real key SemOp( SEM_GLOBAL, -curr_lock); // release global lock continue; // go again } level = retlevel; SemOp( SEM_GLOBAL, -curr_lock); // release read lock s = Compress1(); // do that SemOp( SEM_GLOBAL, -curr_lock); // release write lock if (s < 0) { return s; // exit on error } if (!var->volset) // if done { return retlevel; } } }
short Set_key(u_int ptr_blk, int this_level) // set a block# { short s; // for returns u_char tmp[8]; // some space u_char gtmp[16]; // to find glob int i; // a handy int u_int *ui; // an int ptr cstring *ptr; // spare ptr int rs; // reqd space int ts; // trailing size int rls; // RL space int trailings; // ptr to orig trail gbd *cblk[3]; // current level blks u_int tgb; // top blk in GD DB_Block *btmp; // ditto ptr = (cstring *) tmp; // point at this ptr->len = 4; // always ui = (u_int *) ptr->buf; // for pointers *ui = ptr_blk; // copy this here level = this_level; // set current level if (!this_level) // top level split { gtmp[1] = 128; // start string key for (i=0; i<8; i++) // for each char { if (db_var.name.var_cu[i] == '\0') // check for null { break; // break if found } gtmp[i+2] = db_var.name.var_cu[i]; // copy char } i +=2; // correct count gtmp[i] = '\0'; // null terminate gtmp[0] = (u_char) i; // add the count s=Get_block(systab->vol[db_var.volset-1]->vollab->uci[db_var.uci-1].global); if (s < 0) // failed? { return s; // return error } s = Locate(gtmp); // search for it if (s < 0) // failed? { return s; // return error } Allign_record(); // if not alligned tgb = *(u_int *) record; // get block# level = 1; // at top level s = New_block(); // get a new block if (s < 0) // if that failed { return s; // return error } blk[level]->mem->type = db_var.uci; // pointer block blk[level]->mem->last_idx = 10; // first Index blk[level]->mem->last_free = (systab->vol[volnum-1]->vollab->block_size >> 2) - 3; // use 2 words bcopy(&db_var.name.var_cu[0], &blk[level]->mem->global, 8); idx[10] = blk[level]->mem->last_free + 1; // the data chunk = (cstring *) &iidx[idx[10]]; // point at it chunk->len = 8; // used two words chunk->buf[0] = 0; // ccc chunk->buf[1] = 0; // ucc record = (cstring *) &chunk->buf[chunk->buf[1]+2]; // setup record ptr *( (u_int *) record) = tgb; // first entry s = Insert(&db_var.slen, ptr); // insert this one if (s < 0) // failed? { return s; // return error } level = 0; // point at GD s = Locate(gtmp); // search for it if (s < 0) // failed? { return s; // return error } Allign_record(); // if not alligned *( (u_int *) record) = blk[1]->block; // new top level blk level = 1; blk[level]->dirty = blk[level]; // hook to self if (blk[0]->dirty == (gbd *) 1) // if not queued { blk[0]->dirty = blk[level]; // hook it level = 0; // and clear level } Queit(); // que to write return 0; // end of level == 0 }