Exemplo n.º 1
0
int
dbm_delete(DBM *db, datum key)
{
	int i;

	if (dbm_error(db))
		return (-1);
	if (dbm_rdonly(db)) {
		errno = EPERM;
		return (-1);
	}
	dbm_access(db, dcalchash(key));
	if ((i = finddatum(db->dbm_pagbuf, key)) < 0)
		return (-1);
	if (!delitem(db->dbm_pagbuf, i))
		goto err;
	db->dbm_pagbno = db->dbm_blkno;
	if (dbm_defwrite(db)) {
		dbm_setdirty(db);
	}
	else {
	(void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET);
	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
	err:
		db->dbm_flags |= _DBM_IOERR;
		return (-1);
	}
	}
	return (0);
}
Exemplo n.º 2
0
/* check the block number in pag file */
long dbm_forder(DBM *db, datum key){
  long hash;
  hash = dcalchash(key);
  for(db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1){
    db->dbm_blkno = hash & db->dbm_hmask;
    db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
    if(getbit(db) == 0)
      break;
  }
  return (db->dbm_blkno);
}
Exemplo n.º 3
0
/* retrieve a record */
datum dbm_fetch(DBM *db, datum key){
  int i;
  datum item;
  if(dbm_error(db))
    goto err;
  dbm_access(db, dcalchash(key));
  if((i = finddatum(db->dbm_pagbuf, key)) >= 0){
    item = makdatum(db->dbm_pagbuf, i+1);
    if(item.dptr != NULL)
      return (item);
  }
 err:
  item.dptr = NULL;
  item.dsize = 0;
  return (item);
}
Exemplo n.º 4
0
/* store a record */
int dbm_store(DBM *db, datum key, datum dat, int replace){
  int i;
  datum item, item1;
  char ovfbuf[PBLKSIZ];
  if(dbm_error(db))
    return (-1);
  if(dbm_rdonly(db)){
    errno = EPERM;
    return (-1);
  }
 loop:
  dbm_access(db, dcalchash(key));
  if((i = finddatum(db->dbm_pagbuf, key)) >= 0){
    if(!replace)
      return (1);
    if(!delitem(db->dbm_pagbuf, i)){
      db->dbm_flags |= _DBM_IOERR;
      return (-1);
    }
  }
  if(!additem(db->dbm_pagbuf, key, dat))
    goto split;
  db->dbm_pagbno = db->dbm_blkno;
  (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, SEEK_SET);
  if(write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ){
    db->dbm_flags |= _DBM_IOERR;
    return (-1);
  }
  return (0);
 split:
  if(key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ){
    db->dbm_flags |= _DBM_IOERR;
    errno = ENOSPC;
    return (-1);
  }
  memset(ovfbuf, 0, PBLKSIZ);
  for(i=0;;){
    item = makdatum(db->dbm_pagbuf, i);
    if(item.dptr == NULL)
      break;
    if(dcalchash(item) & (db->dbm_hmask+1)){
      item1 = makdatum(db->dbm_pagbuf, i+1);
      if(item1.dptr == NULL){
        db->dbm_flags |= _DBM_IOERR;
        break;
      }
      if(!additem(ovfbuf, item, item1) ||
         !delitem(db->dbm_pagbuf, i)){
        db->dbm_flags |= _DBM_IOERR;
        return (-1);
      }
      continue;
    }
    i += 2;
  }
  db->dbm_pagbno = db->dbm_blkno;
  (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, SEEK_SET);
  if(write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ){
    db->dbm_flags |= _DBM_IOERR;
    return (-1);
  }
  (void) lseek(db->dbm_pagf, (db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ, SEEK_SET);
  if(write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ){
    db->dbm_flags |= _DBM_IOERR;
    return (-1);
  }
  setbit(db);
  goto loop;
}
Exemplo n.º 5
0
datum
dbm_do_nextkey(DBM *db, datum inkey)
{
	datum item,bitem;
	long hash;
	datum key;
	int f;
	int i;
	int j;
	short *sp;
	int n;
	char *p1, *p2;

	if ( dbm_error(db) ) {
		item.dptr = NULL;
		item.dsize = 0;
		return (item);
	}

	/*user has supplied lastkey*/

	if(inkey.dptr != NULL) {
	       dbm_access(db, (hash=dcalchash(inkey)));
	       if ((i = finddatum(db->dbm_pagbuf, inkey)) >= 0) {
		       db->dbm_keyptr = i + 2;
		       db->dbm_blkptr = db->dbm_blkno;
	       }
	       key=inkey;
       }
       else  {
		/*is this a manual firstkey request? */

		if (db->dbm_blkptr == 0L &&
			db->dbm_keyptr == 0)
			return (dbm_firsthash(db, 0L));

		/*no -- get lastkey this is like dbm_access by blkptr*/

		if (db->dbm_blkptr != db->dbm_pagbno) {

			if (dbm_dirty(db)) dbm_flushpag(db);
			db->dbm_pagbno = db->dbm_blkptr;
			(void) lseek(db->dbm_pagf, (long)(db->dbm_blkptr*PBLKSIZ), L_SET);
			if (read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
				bzero(db->dbm_pagbuf, PBLKSIZ);
#ifdef DEBUG
			else if (chkblk(db->dbm_pagbuf) < 0)
			db->dbm_flags |= _DBM_IOERR;
#endif
		}
		/*now just make up last key datum*/
		if (db->dbm_keyptr >=2) key= makdatum(db->dbm_pagbuf,(db->dbm_keyptr-2));
		else key=nullkey;

	/* the keyptr pagbuf have failed us, the user must
	be an extra clever moron who depends on 
	these variables and their former meaning.
	If we set the variables this would have got
	us the key for sure! So give him the old algorithm.*/
		if (key.dptr == NULL) return (dbm_slow_nextkey(db));
	}

	/*at this point the last key is paged in and
	we can proceed as in old dbm -- like Ken did his. */

	f = 1;
	j=0;
	sp = (short *)db->dbm_pagbuf;

	for(i=0;; i+=2) {

		/*begin put makdatum inline*/

		if ((unsigned)i >= sp[0]) {
			item.dptr = NULL;
			item.dsize = 0;
			break; /*from below*/
		}
		else { 
			if (i > 0) item.dsize = sp[i] - sp[i+1];
			else item.dsize = PBLKSIZ - sp[i+1];
			item.dptr = db->dbm_pagbuf+sp[i+1];
		}

		/*	item = makdatum(db->dbm_pagbuf, i);*/
		/*end put makdatum inline*/

		if(item.dptr == NULL)
			break;
/*inline cmpdatum*/


		n = key.dsize;
		if(n != item.dsize)
			if( (n - item.dsize) <= 0 ) continue;
			else { }
		else {
			if(n == 0) continue;
			p1 = key.dptr;
			p2 = item.dptr;
			do
				if(*p1++ != *p2++)
					if((*--p1 - *--p2) > 0) goto keep_going; 
					else continue;
			while(--n);
			continue;
			}

keep_going:

/*end inline cmpdatum*/
		/*if(cmpdatum(key, item) <= 0)
			continue;*/
		if (f) {
			bitem = item;
			j=i;	
			f = 0;
		}
		else {

/*		if(cmpdatum(bitem, item) < 0)*/

		n = bitem.dsize;
		if(n != item.dsize)
			{
			if((n - item.dsize) <0) {
					bitem = item;
					j=i;	
				}
			}
			else  if (n != 0) {
				p1 = bitem.dptr;
				p2 = item.dptr;
				do
				if(*p1++ != *p2++) {
					if((*--p1 - *--p2) <0) {
						bitem = item;
						j=i;	
					}
					break;
				}
				while(--n);
			}
		}
	}

	if(f == 0) {
	        db->dbm_keyptr = j + 2;
	        db->dbm_blkptr = db->dbm_blkno;
		return (bitem);
	}

	/*really need hash at this point*/
	/*if he gave us a key we have already calculated the hash*/
	/*if not get it*/
	if (inkey.dptr == NULL) hash=dcalchash(key);
	hash = dbm_hashinc(db,hash);

	if(hash == 0)
		return (item); /*null*/
	/*get first item on next page in hash table order*/
	return (dbm_firsthash(db, hash));


}
Exemplo n.º 6
0
int
dbm_store(DBM *db, datum key, datum dat, int replace)
{
	int i;
	datum item, item1;
	char ovfbuf[PBLKSIZ];

	if (dbm_error(db))
		return (-1);
	if (dbm_rdonly(db)) {
		errno = EPERM;
		return (-1);
	}
loop:
	dbm_access(db, dcalchash(key));
	if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) {
		if (!replace)
			return (1);
		if (!delitem(db->dbm_pagbuf, i)) {
			db->dbm_flags |= _DBM_IOERR;
			return (-1);
		}
	}
	if (!additem(db->dbm_pagbuf, key, dat))
		goto split;
	db->dbm_pagbno = db->dbm_blkno;
	if (dbm_defwrite(db)) {
		dbm_setdirty(db);
	}
	else {

		(void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET);
		if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
			db->dbm_flags |= _DBM_IOERR;
			return (-1);
		}
	}
	return (0);

split:
	if (key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ) {
		db->dbm_flags |= _DBM_IOERR;
		errno = ENOSPC;
		return (-1);
	}
	bzero(ovfbuf, PBLKSIZ);
	for (i=0;;) {
		item = makdatum(db->dbm_pagbuf, i);
		if (item.dptr == NULL)
			break;
		if (dcalchash(item) & (db->dbm_hmask+1)) {
			item1 = makdatum(db->dbm_pagbuf, i+1);
			if (item1.dptr == NULL) {
				/*(void) fprintf(stderr, "ndbm: split not paired\n");*/
				db->dbm_flags |= _DBM_IOERR;
				break;
			}
			if (!additem(ovfbuf, item, item1) ||
			    !delitem(db->dbm_pagbuf, i)) {
				db->dbm_flags |= _DBM_IOERR;
				return (-1);
			}
			continue;
		}
		i += 2;
	}
	db->dbm_pagbno = db->dbm_blkno;
	(void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET);
	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
		db->dbm_flags |= _DBM_IOERR;
		return (-1);
	}
	dbm_clrdirty(db); /*clear dirty*/
	(void) lseek(db->dbm_pagf, 
		(long)((db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ), L_SET);
	if (write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ) {
		db->dbm_flags |= _DBM_IOERR;
		return (-1);
	}
	if (setbit(db) < 0) {
		db->dbm_flags |= _DBM_IOERR;
		return (-1);
	}
	goto loop;
}