Esempio n. 1
0
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
}
Esempio n. 2
0
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;
    }
  }
}
Esempio n. 3
0
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
  }