Пример #1
0
void freesuffixarray(Suffixarray *suffixarray)
{
  gt_fa_xmunmap((void *) suffixarray->suftab);
  suffixarray->suftab = NULL;
  gt_fa_xmunmap((void *) suffixarray->lcptab);
  suffixarray->lcptab = NULL;
  gt_fa_xmunmap((void *) suffixarray->llvtab);
  suffixarray->llvtab = NULL;
  gt_fa_xmunmap((void *) suffixarray->bwttab);
  suffixarray->bwttab = NULL;
  gt_fa_xfclose(suffixarray->suftabstream.fp);
  suffixarray->suftabstream.fp = NULL;
  FREESPACE(suffixarray->suftabstream.bufferedfilespace);
  gt_fa_xfclose(suffixarray->lcptabstream.fp);
  suffixarray->lcptabstream.fp = NULL;
  FREESPACE(suffixarray->lcptabstream.bufferedfilespace);
  gt_fa_xfclose(suffixarray->llvtabstream.fp);
  suffixarray->llvtabstream.fp = NULL;
  FREESPACE(suffixarray->llvtabstream.bufferedfilespace);
  gt_fa_xfclose(suffixarray->bwttabstream.fp);
  suffixarray->bwttabstream.fp = NULL;
  FREESPACE(suffixarray->bwttabstream.bufferedfilespace);
  encodedsequence_free(&suffixarray->encseq);
  if (suffixarray->bcktab != NULL)
  {
    bcktab_delete(&suffixarray->bcktab);
  }
}
Пример #2
0
void gt_multimappowerfree(GtCodetype ***multimappower)
{
  if (*multimappower != NULL)
  {
    FREESPACE((*multimappower)[0]);
    FREESPACE((*multimappower));
    *multimappower = NULL;
  }
}
Пример #3
0
static void freeconstructedfmindex(Fmindex *fm)
{
  GT_FREEARRAY (&fm->specpos, GtPairBwtidx);
  FREESPACE (fm->bfreq);
  FREESPACE (fm->superbfreq);
  FREESPACE (fm->tfreq);
  FREESPACE (fm->markpostable);
  if (fm->suffixlength > 0)
  {
    FREESPACE(fm->boundarray);
  }
}
Пример #4
0
void gt_makeitmthresholds(Profilematrix *prof,
                              ProfScore minscore)
{
  unsigned long d, a;
  long ddown;
  ProfScore partsum,
            score,
            *maxscore;

  ALLOCASSIGNSPACE(maxscore,NULL,ProfScore,prof->dimension);
  for (d=0; d<prof->dimension; d++)
  {
    for (a=0; a<prof->numofcharacters; a++)
    {
      score = GETPROFSCORE(prof,a,d);
      if (a == 0 || maxscore[d] < score)
      {
        maxscore[d] = score;
      }
    }
  }
  partsum = (ProfScore) 0;
  gt_assert(prof->itmthreshold != NULL);
  for (ddown = (long) (prof->dimension-1); ddown>=0; ddown--)
  {
    prof->itmthreshold[ddown] = minscore - partsum;
    partsum += maxscore[ddown];
  }
  FREESPACE(maxscore);
}
Пример #5
0
/*
 * Given the buffer pointer of the first overflow page of a big pair,
 * find the end of the big pair
 *
 * This will set bpp to the buffer header of the last page of the big pair.
 * It will return the pageno of the overflow page following the last page
 * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
 * bucket)
 */
uint16_t
__find_last_page(HTAB *hashp, BUFHEAD **bpp)
{
	BUFHEAD *bufp;
	uint16_t *bp, pageno;
	int n;

	bufp = *bpp;
	bp = (uint16_t *)(void *)bufp->page;
	for (;;) {
		n = bp[0];

		/*
		 * This is the last page if: the tag is FULL_KEY_DATA and
		 * either only 2 entries OVFLPAGE marker is explicit there
		 * is freespace on the page.
		 */
		if (bp[2] == FULL_KEY_DATA &&
		    ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
			break;

		pageno = bp[n - 1];
		bufp = __get_buf(hashp, (uint32_t)pageno, bufp, 0);
		if (!bufp)
			return (0);	/* Need to indicate an error! */
		bp = (uint16_t *)(void *)bufp->page;
	}

	*bpp = bufp;
	if (bp[0] > 2)
		return (bp[3]);
	else
		return (0);
}
Пример #6
0
/*
 * Add the given pair to the page
 *
 * Returns:
 *	0 ==> OK
 *	1 ==> failure
 */
extern int
__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
	u_int16_t *bp, *sop;
	int do_expand;

	bp = (u_int16_t *)bufp->page;
	do_expand = 0;
	while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
		/* Exception case */
		if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
			/* This is the last page of a big key/data pair
			   and we need to add another page */
			break;
		else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
			bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
			if (!bufp)
				return (-1);
			bp = (u_int16_t *)bufp->page;
		} else
			/* Try to squeeze key on this page */
			if (FREESPACE(bp) > PAIRSIZE(key, val)) {
				squeeze_key(bp, key, val);
				return (0);
			} else {
				bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
				if (!bufp)
					return (-1);
				bp = (u_int16_t *)bufp->page;
			}

	if (PAIRFITS(bp, key, val))
		putpair(bufp->page, key, val);
	else {
		do_expand = 1;
		bufp = __add_ovflpage(hashp, bufp);
		if (!bufp)
			return (-1);
		sop = (u_int16_t *)bufp->page;

		if (PAIRFITS(sop, key, val))
			putpair((char *)sop, key, val);
		else
			if (__big_insert(hashp, bufp, key, val))
				return (-1);
	}
	bufp->flags |= BUF_MOD;
	/*
	 * If the average number of keys per bucket exceeds the fill factor,
	 * expand the table.
	 */
	hashp->NKEYS++;
	if (do_expand ||
	    (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
		return (__expand_table(hashp));
	return (0);
}
Пример #7
0
static void freesimpleoption(Cmppairwiseopt *cmppairwise)
{
  gt_str_array_delete(cmppairwise->strings);
  gt_str_array_delete(cmppairwise->files);
  gt_str_delete(cmppairwise->text);
  if (cmppairwise->charlistlen != NULL)
  {
    gt_str_delete(cmppairwise->charlistlen->charlist);
    FREESPACE(cmppairwise->charlistlen);
  }
}
Пример #8
0
GtCodetype *gt_initfilltable(unsigned int numofchars,unsigned int prefixlength)
{
  unsigned int i;
  GtCodetype *filltable, *basepower;

  basepower = gt_initbasepower(numofchars,prefixlength);
  ALLOCASSIGNSPACE(filltable,NULL,GtCodetype,prefixlength);
  for (i=0; i<prefixlength; i++)
  {
    filltable[i] = basepower[prefixlength-i]-1;
  }
  FREESPACE(basepower);
  return filltable;
}
Пример #9
0
static unsigned long squarededistunit2 (const GtUchar *u, unsigned long m,
                                        const GtUchar *v, unsigned long n)
{
  unsigned long val, we, nw, *ecol, *ecolptr;
  const GtUchar *uptr, *vptr;

  ALLOCASSIGNSPACE(ecol,NULL,unsigned long,m+1);
  for (*ecol = 0, ecolptr = ecol+1, uptr = u; uptr < u + m; ecolptr++, uptr++)
  {
    *ecolptr = *(ecolptr-1) + 1;
  }
  for (vptr = v; vptr < v + n; vptr++)
  {
    nw = *ecol;
    *ecol = nw + 1;
    for (ecolptr = ecol+1, uptr = u; uptr < u + m; ecolptr++, uptr++)
    {
      we = *ecolptr;
      *ecolptr = *(ecolptr-1) + 1;
      if (*uptr == *vptr)
      {
        val = nw;
      } else
      {
        val = nw + 1;
      }
      if (val < *ecolptr)
      {
        *ecolptr = val;
      }
      if ((val = we + 1) < *ecolptr)
      {
        *ecolptr = val;
      }
      nw = we;
    }
  }
  val = *(ecolptr-1);
  FREESPACE(ecol);
  return val;
}
Пример #10
0
/*
 * Given the buffer pointer of the first overflow page of a big pair,
 * find the end of the big pair
 *
 * This will set bpp to the buffer header of the last page of the big pair.
 * It will return the pageno of the overflow page following the last page
 * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
 * bucket)
 */
extern uint16
dbm_find_last_page(HTAB *hashp, BUFHEAD **bpp)
{
    BUFHEAD *bufp;
    uint16 *bp, pageno;
    uint n;

    bufp = *bpp;
    bp = (uint16 *)bufp->page;
    for (;;) {
        n = bp[0];

        /*
         * This is the last page if: the tag is FULL_KEY_DATA and
         * either only 2 entries OVFLPAGE marker is explicit there
         * is freespace on the page.
         */
        if (bp[2] == FULL_KEY_DATA &&
            ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
            break;

        /* LJM bound the size of n to reasonable limits
         */
        if (n > hashp->BSIZE / sizeof(uint16))
            return (0);

        pageno = bp[n - 1];
        bufp = dbm_get_buf(hashp, pageno, bufp, 0);
        if (!bufp)
            return (0); /* Need to indicate an error! */
        bp = (uint16 *)bufp->page;
    }

    *bpp = bufp;
    if (bp[0] > 2)
        return (bp[3]);
    else
        return (0);
}
Пример #11
0
void gt_lookaheadsearchPSSM(const GtEncseq *encseq,
                            const Profilematrix *prof)
{
  unsigned long firstpos, bufsize;
  GtUchar currentchar;
  unsigned long pos;
  GtEncseqReader *esr;
  unsigned long totallength = gt_encseq_total_length(encseq);
  GtUchar *buffer;

  esr = gt_encseq_create_reader_with_readmode(encseq,GT_READMODE_FORWARD,0);
  ALLOCASSIGNSPACE(buffer,NULL,GtUchar,prof->dimension);
  firstpos = bufsize = 0;
  for (pos=0; pos < totallength; pos++)
  {
    currentchar = gt_encseq_reader_next_encoded_char(esr);
    if (ISSPECIAL(currentchar))
    {
      bufsize = firstpos = 0;
    } else
    {
      if (bufsize < prof->dimension)
      {
        buffer[bufsize++] = currentchar;
      } else
      {
        buffer[firstpos++] = currentchar;
        if (firstpos == prof->dimension)
        {
          firstpos = 0;
        }
      }
    }
  }
  gt_encseq_reader_delete(esr);
  FREESPACE(buffer);
}
Пример #12
0
void freeTurningwheel(Turningwheel **tw)
{
  FREESPACE(*tw);
}
Пример #13
0
/*
 * Big_insert
 *
 * You need to do an insert and the key/data pair is too big
 *
 * Returns:
 * 0 ==> OK
 *-1 ==> ERROR
 */
int
__big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
	uint16_t *p, n;
	size_t key_size, val_size;
	uint16_t space, move_bytes, off;
	char *cp, *key_data, *val_data;
	size_t temp;

	cp = bufp->page;		/* Character pointer of p. */
	p = (uint16_t *)(void *)cp;

	key_data = (char *)key->data;
	_DBFIT(key->size, int);
	key_size = key->size;
	val_data = (char *)val->data;
	_DBFIT(val->size, int);
	val_size = val->size;

	/* First move the Key */
	
	temp = FREESPACE(p) - BIGOVERHEAD;
	_DBFIT(temp, uint16_t);
	space = (uint16_t)temp;
	while (key_size) {
		move_bytes = MIN(space, key_size);
		off = OFFSET(p) - move_bytes;
		memmove(cp + off, key_data, (size_t)move_bytes);
		key_size -= move_bytes;
		key_data += move_bytes;
		n = p[0];
		p[++n] = off;
		p[0] = ++n;
		temp = off - PAGE_META(n);
		_DBFIT(temp, uint16_t);
		FREESPACE(p) = (uint16_t)temp;
		OFFSET(p) = off;
		p[n] = PARTIAL_KEY;
		bufp = __add_ovflpage(hashp, bufp);
		if (!bufp)
			return (-1);
		n = p[0];
		if (!key_size) {
			space = FREESPACE(p);
			if (space) {
				move_bytes = MIN(space, val_size);
				/*
				 * If the data would fit exactly in the
				 * remaining space, we must overflow it to the
				 * next page; otherwise the invariant that the
				 * data must end on a page with FREESPACE
				 * non-zero would fail.
				 */
				if (space == val_size && val_size == val->size)
					goto toolarge;
				off = OFFSET(p) - move_bytes;
				memmove(cp + off, val_data, (size_t)move_bytes);
				val_data += move_bytes;
				val_size -= move_bytes;
				p[n] = off;
				p[n - 2] = FULL_KEY_DATA;
				FREESPACE(p) = FREESPACE(p) - move_bytes;
				OFFSET(p) = off;
			} else {
			toolarge:
				p[n - 2] = FULL_KEY;
			}
		}
		p = (uint16_t *)(void *)bufp->page;
		cp = bufp->page;
		bufp->flags |= BUF_MOD;
		temp = FREESPACE(p) - BIGOVERHEAD;
		_DBFIT(temp, uint16_t);
		space = (uint16_t)temp;
	}

	/* Now move the data */
	temp = FREESPACE(p) - BIGOVERHEAD;
	_DBFIT(temp, uint16_t);
	space = (uint16_t)temp;
	while (val_size) {
		move_bytes = MIN(space, val_size);
		/*
		 * Here's the hack to make sure that if the data ends on the
		 * same page as the key ends, FREESPACE is at least one.
		 */
		if (space == val_size && val_size == val->size)
			move_bytes--;
		off = OFFSET(p) - move_bytes;
		memmove(cp + off, val_data, (size_t)move_bytes);
		val_size -= move_bytes;
		val_data += move_bytes;
		n = p[0];
		p[++n] = off;
		p[0] = ++n;
		temp = off - PAGE_META(n);
		_DBFIT(temp, uint16_t);
		FREESPACE(p) = (uint16_t)temp;
		OFFSET(p) = off;
		if (val_size) {
			p[n] = FULL_KEY;
			bufp = __add_ovflpage(hashp, bufp);
			if (!bufp)
				return (-1);
			cp = bufp->page;
			p = (uint16_t *)(void *)cp;
		} else
			p[n] = FULL_KEY_DATA;
		bufp->flags |= BUF_MOD;
		temp = FREESPACE(p) - BIGOVERHEAD;
		_DBFIT(temp, uint16_t);
		space = (uint16_t)temp;
	}
	return (0);
}
Пример #14
0
/*
 * Returns:
 *  0 => OK
 * -1 => error
 */
int
__big_split(
	HTAB *hashp,
	BUFHEAD *op,	/* Pointer to where to put keys that go in old bucket */
	BUFHEAD *np,	/* Pointer to new bucket page */
			/* Pointer to first page containing the big key/data */
	BUFHEAD *big_keyp,
	int addr,	/* Address of big_keyp */
	uint32_t   obucket,/* Old Bucket */
	SPLIT_RETURN *ret
)
{
	BUFHEAD *tmpp;
	uint16_t *tp;
	BUFHEAD *bp;
	DBT key, val;
	uint32_t change;
	uint16_t free_space, n, off;
	size_t temp;

	bp = big_keyp;

	/* Now figure out where the big key/data goes */
	if (__big_keydata(hashp, big_keyp, &key, &val, 0))
		return (-1);
	change = (__call_hash(hashp, key.data, (int)key.size) != obucket);

	if ((ret->next_addr = __find_last_page(hashp, &big_keyp)) != 0) {
		if (!(ret->nextp =
		    __get_buf(hashp, (uint32_t)ret->next_addr, big_keyp, 0)))
			return (-1);
	} else
		ret->nextp = NULL;

	/* Now make one of np/op point to the big key/data pair */
	_DIAGASSERT(np->ovfl == NULL);
	if (change)
		tmpp = np;
	else
		tmpp = op;

	tmpp->flags |= BUF_MOD;
#ifdef DEBUG1
	(void)fprintf(stderr,
	    "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
	    (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
#endif
	tmpp->ovfl = bp;	/* one of op/np point to big_keyp */
	tp = (uint16_t *)(void *)tmpp->page;
	_DIAGASSERT(FREESPACE(tp) >= OVFLSIZE);
	n = tp[0];
	off = OFFSET(tp);
	free_space = FREESPACE(tp);
	tp[++n] = (uint16_t)addr;
	tp[++n] = OVFLPAGE;
	tp[0] = n;
	OFFSET(tp) = off;
	temp = free_space - OVFLSIZE;
	_DBFIT(temp, uint16_t);
	FREESPACE(tp) = (uint16_t)temp;

	/*
	 * Finally, set the new and old return values. BIG_KEYP contains a
	 * pointer to the last page of the big key_data pair. Make sure that
	 * big_keyp has no following page (2 elements) or create an empty
	 * following page.
	 */

	ret->newp = np;
	ret->oldp = op;

	tp = (uint16_t *)(void *)big_keyp->page;
	big_keyp->flags |= BUF_MOD;
	if (tp[0] > 2) {
		/*
		 * There may be either one or two offsets on this page.  If
		 * there is one, then the overflow page is linked on normally
		 * and tp[4] is OVFLPAGE.  If there are two, tp[4] contains
		 * the second offset and needs to get stuffed in after the
		 * next overflow page is added.
		 */
		n = tp[4];
		free_space = FREESPACE(tp);
		off = OFFSET(tp);
		tp[0] -= 2;
		temp = free_space + OVFLSIZE;
		_DBFIT(temp, uint16_t);
		FREESPACE(tp) = (uint16_t)temp;
		OFFSET(tp) = off;
		tmpp = __add_ovflpage(hashp, big_keyp);
		if (!tmpp)
			return (-1);
		tp[4] = n;
	} else
		tmpp = big_keyp;

	if (change)
		ret->newp = tmpp;
	else
		ret->oldp = tmpp;
	return (0);
}
Пример #15
0
/*
 * Return the data for the key/data pair that begins on this page at this
 * index (index should always be 1).
 */
int
__big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, int set_current)
{
	BUFHEAD *save_p;
	uint16_t *bp, len, off, save_addr;
	char *tp;

	bp = (uint16_t *)(void *)bufp->page;
	while (bp[ndx + 1] == PARTIAL_KEY) {
		bufp = __get_buf(hashp, (uint32_t)bp[bp[0] - 1], bufp, 0);
		if (!bufp)
			return (-1);
		bp = (uint16_t *)(void *)bufp->page;
		ndx = 1;
	}

	if (bp[ndx + 1] == FULL_KEY) {
		bufp = __get_buf(hashp, (uint32_t)bp[bp[0] - 1], bufp, 0);
		if (!bufp)
			return (-1);
		bp = (uint16_t *)(void *)bufp->page;
		save_p = bufp;
		save_addr = save_p->addr;
		off = bp[1];
		len = 0;
	} else
		if (!FREESPACE(bp)) {
			/*
			 * This is a hack.  We can't distinguish between
			 * FULL_KEY_DATA that contains complete data or
			 * incomplete data, so we require that if the data
			 * is complete, there is at least 1 byte of free
			 * space left.
			 */
			off = bp[bp[0]];
			len = bp[1] - off;
			save_p = bufp;
			save_addr = bufp->addr;
			bufp = __get_buf(hashp, (uint32_t)bp[bp[0] - 1], bufp,
			    0);
			if (!bufp)
				return (-1);
			bp = (uint16_t *)(void *)bufp->page;
		} else {
			/* The data is all on one page. */
			tp = (char *)(void *)bp;
			off = bp[bp[0]];
			val->data = (uint8_t *)tp + off;
			val->size = bp[1] - off;
			if (set_current) {
				if (bp[0] == 2) {	/* No more buckets in
							 * chain */
					hashp->cpage = NULL;
					hashp->cbucket++;
					hashp->cndx = 1;
				} else {
					hashp->cpage = __get_buf(hashp,
					    (uint32_t)bp[bp[0] - 1], bufp, 0);
					if (!hashp->cpage)
						return (-1);
					hashp->cndx = 1;
					if (!((uint16_t *)(void *)
					    hashp->cpage->page)[0]) {
						hashp->cbucket++;
						hashp->cpage = NULL;
					}
				}
			}
			return (0);
		}

	val->size = collect_data(hashp, bufp, (int)len, set_current);
	if (val->size == (size_t)-1)
		return (-1);
	if (save_p->addr != save_addr) {
		/* We are pretty short on buffers. */
		errno = EINVAL;			/* OUT OF BUFFERS */
		return (-1);
	}
	memmove(hashp->tmp_buf, (save_p->page) + off, (size_t)len);
	val->data = (uint8_t *)hashp->tmp_buf;
	return (0);
}
Пример #16
0
/*
 * Called when bufp's page  contains a partial key (index should be 1)
 *
 * All pages in the big key/data pair except bufp are freed.  We cannot
 * free bufp because the page pointing to it is lost and we can't get rid
 * of its pointer.
 *
 * Returns:
 * 0 => OK
 *-1 => ERROR
 */
int
__big_delete(HTAB *hashp, BUFHEAD *bufp)
{
	BUFHEAD *last_bfp, *rbufp;
	uint16_t *bp, pageno;
	int key_done, n;
	size_t temp;

	rbufp = bufp;
	last_bfp = NULL;
	bp = (uint16_t *)(void *)bufp->page;
	pageno = 0;
	key_done = 0;

	while (!key_done || (bp[2] != FULL_KEY_DATA)) {
		if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
			key_done = 1;

		/*
		 * If there is freespace left on a FULL_KEY_DATA page, then
		 * the data is short and fits entirely on this page, and this
		 * is the last page.
		 */
		if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
			break;
		pageno = bp[bp[0] - 1];
		rbufp->flags |= BUF_MOD;
		rbufp = __get_buf(hashp, (uint32_t)pageno, rbufp, 0);
		if (last_bfp)
			__free_ovflpage(hashp, last_bfp);
		last_bfp = rbufp;
		if (!rbufp)
			return (-1);		/* Error. */
		bp = (uint16_t *)(void *)rbufp->page;
	}

	/*
	 * If we get here then rbufp points to the last page of the big
	 * key/data pair.  Bufp points to the first one -- it should now be
	 * empty pointing to the next page after this pair.  Can't free it
	 * because we don't have the page pointing to it.
	 */

	/* This is information from the last page of the pair. */
	n = bp[0];
	pageno = bp[n - 1];

	/* Now, bp is the first page of the pair. */
	bp = (uint16_t *)(void *)bufp->page;
	if (n > 2) {
		/* There is an overflow page. */
		bp[1] = pageno;
		bp[2] = OVFLPAGE;
		bufp->ovfl = rbufp->ovfl;
	} else
		/* This is the last page. */
		bufp->ovfl = NULL;
	n -= 2;
	bp[0] = n;
	temp = hashp->BSIZE - PAGE_META(n);
	_DBFIT(temp, uint16_t);
	FREESPACE(bp) = (uint16_t)temp;
	OFFSET(bp) = hashp->BSIZE;

	bufp->flags |= BUF_MOD;
	if (rbufp)
		__free_ovflpage(hashp, rbufp);
	if (last_bfp && last_bfp != rbufp)
		__free_ovflpage(hashp, last_bfp);

	hashp->NKEYS--;
	return (0);
}
Пример #17
0
/*
 * Returns:
 *   0 ==> OK
 *  -1 ==> Error
 */
extern int
__split_page(HTAB *hashp, uint32 obucket, uint32 nbucket)
{
    register BUFHEAD *new_bufp, *old_bufp;
    register uint16 *ino;
    register uint16 *tmp_uint16_array;
    register char *np;
    DBT key, val;
    uint16 n, ndx;
    int retval;
    uint16 copyto, diff, moved;
    size_t off;
    char *op;

    copyto = (uint16)hashp->BSIZE;
    off = (uint16)hashp->BSIZE;
    old_bufp = __get_buf(hashp, obucket, NULL, 0);
    if (old_bufp == NULL)
        return (-1);
    new_bufp = __get_buf(hashp, nbucket, NULL, 0);
    if (new_bufp == NULL)
        return (-1);

    old_bufp->flags |= (BUF_MOD | BUF_PIN);
    new_bufp->flags |= (BUF_MOD | BUF_PIN);

    ino = (uint16 *)(op = old_bufp->page);
    np = new_bufp->page;

    moved = 0;

    for (n = 1, ndx = 1; n < ino[0]; n += 2) {
        if (ino[n + 1] < REAL_KEY) {
            retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
                                (int)copyto, (int)moved);
            old_bufp->flags &= ~BUF_PIN;
            new_bufp->flags &= ~BUF_PIN;
            return (retval);
        }
        key.data = (uint8 *)op + ino[n];

        /* check here for ino[n] being greater than
         * off.  If it is then the database has
         * been corrupted.
         */
        if (ino[n] > off)
            return (DATABASE_CORRUPTED_ERROR);

        key.size = off - ino[n];

#ifdef DEBUG
        /* make sure the size is positive */
        assert(((int)key.size) > -1);
#endif

        if (__call_hash(hashp, (char *)key.data, key.size) == obucket) {
            /* Don't switch page */
            diff = copyto - off;
            if (diff) {
                copyto = ino[n + 1] + diff;
                memmove(op + copyto, op + ino[n + 1],
                        off - ino[n + 1]);
                ino[ndx] = copyto + ino[n] - ino[n + 1];
                ino[ndx + 1] = copyto;
            } else
                copyto = ino[n + 1];
            ndx += 2;
        } else {
            /* Switch page */
            val.data = (uint8 *)op + ino[n + 1];
            val.size = ino[n] - ino[n + 1];

            /* if the pair doesn't fit something is horribly
             * wrong.  LJM
             */
            tmp_uint16_array = (uint16 *)np;
            if (!PAIRFITS(tmp_uint16_array, &key, &val))
                return (DATABASE_CORRUPTED_ERROR);

            putpair(np, &key, &val);
            moved += 2;
        }

        off = ino[n + 1];
    }

    /* Now clean up the page */
    ino[0] -= moved;
    FREESPACE(ino) = copyto - sizeof(uint16) * (ino[0] + 3);
    OFFSET(ino) = copyto;

#ifdef DEBUG3
    (void)fprintf(stderr, "split %d/%d\n",
                  ((uint16 *)np)[0] / 2,
                  ((uint16 *)op)[0] / 2);
#endif
    /* unpin both pages */
    old_bufp->flags &= ~BUF_PIN;
    new_bufp->flags &= ~BUF_PIN;
    return (0);
}
Пример #18
0
unsigned long greedyunitedist(const GtUchar *useq,
                              unsigned long ulenvalue,
                              const GtUchar *vseq,
                              unsigned long vlenvalue)
{
  unsigned long currentallocated, realdistance;
  FrontResource gl;
  Frontspec frontspecspace[2],
            *fspec,
            *prevfspec;
  Frontvalue *fptr;
  unsigned long kval;
  long r;

#ifdef SKDEBUG
  printf("unitedistcheckSEPgeneric(ulen=%lu,vlen=%lu)\n",ulenvalue,vlenvalue);
#endif
  gt_assert(ulenvalue < (unsigned long) LONG_MAX);
  gt_assert(vlenvalue < (unsigned long) LONG_MAX);
  currentallocated = 1UL;
  ALLOCASSIGNSPACE(gl.frontspace,NULL,Frontvalue,currentallocated);
  gl.useq = useq;
  gl.vseq = vseq;
  gl.ubound = useq + ulenvalue;
  gl.vbound = vseq + vlenvalue;
  gl.ulen = (long) ulenvalue;
  gl.vlen = (long) vlenvalue;
  gl.integermin = -MAX(gl.ulen,gl.vlen);
  prevfspec = &frontspecspace[0];
  firstfrontforward(&gl,prevfspec);
  if (gl.ulen == gl.vlen && ROWVALUE(&gl.frontspace[0]) == gl.vlen)
  {
    realdistance = 0;
  } else
  {
    for (kval=1UL, r=1-MIN(gl.ulen,gl.vlen); /* Nothing */ ; kval++, r++)
    {
      if (prevfspec == &frontspecspace[0])
      {
        fspec = &frontspecspace[1];
      } else
      {
        fspec = &frontspecspace[0];
      }
      fspec->offset = prevfspec->offset + prevfspec->width;
      frontspecparms(&gl,fspec,(long) kval,r);
      while ((unsigned long) (fspec->offset + fspec->width)
             >= currentallocated)
      {
        currentallocated += (kval+1);
        ALLOCASSIGNSPACE(gl.frontspace,gl.frontspace,
                         Frontvalue,currentallocated);
      }
      (void) evalfrontforward(&gl,prevfspec,fspec,r);
      fptr = gl.frontspace + fspec->offset - fspec->left;
      if (accessfront(&gl,fptr,fspec,gl.vlen - gl.ulen) == gl.ulen)
      {
        realdistance = kval;
        break;
      }
      if (prevfspec == &frontspecspace[0])
      {
        prevfspec = &frontspecspace[1];
      } else
      {
        prevfspec = &frontspecspace[0];
      }
    }
  }
#ifdef SKDEBUG
  printf("unitedistfrontSEP returns %ld\n",realdistance);
#endif
  FREESPACE(gl.frontspace);
  return realdistance;
}
Пример #19
0
static int
ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp,
           BUFHEAD *new_bufp, /* Same as __split_page. */ int copyto, int moved)
/* int copyto;   First byte on page which contains key/data values. */
/* int moved;    Number of pairs moved to new page. */
{
    register BUFHEAD *bufp; /* Buffer header for ino */
    register uint16 *ino;   /* Page keys come off of */
    register uint16 *np;    /* New page */
    register uint16 *op;    /* Page keys go on to if they aren't moving */
    uint32 loop_detection = 0;

    BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
    DBT key, val;
    SPLIT_RETURN ret;
    uint16 n, off, ov_addr, scopyto;
    char *cino; /* Character value of ino */
    int status;

    bufp = old_bufp;
    ino = (uint16 *)old_bufp->page;
    np = (uint16 *)new_bufp->page;
    op = (uint16 *)old_bufp->page;
    last_bfp = NULL;
    scopyto = (uint16)copyto; /* ANSI */

    n = ino[0] - 1;
    while (n < ino[0]) {

        /* this function goes nuts sometimes and never returns.
         * I havent found the problem yet but I need a solution
         * so if we loop too often we assume a database curruption error
         * :LJM
         */
        loop_detection++;

        if (loop_detection > MAX_UGLY_SPLIT_LOOPS)
            return DATABASE_CORRUPTED_ERROR;

        if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
            if ((status = __big_split(hashp, old_bufp,
                                      new_bufp, bufp, bufp->addr, obucket, &ret)))
                return (status);
            old_bufp = ret.oldp;
            if (!old_bufp)
                return (-1);
            op = (uint16 *)old_bufp->page;
            new_bufp = ret.newp;
            if (!new_bufp)
                return (-1);
            np = (uint16 *)new_bufp->page;
            bufp = ret.nextp;
            if (!bufp)
                return (0);
            cino = (char *)bufp->page;
            ino = (uint16 *)cino;
            last_bfp = ret.nextp;
        } else if (ino[n + 1] == OVFLPAGE) {
            ov_addr = ino[n];
            /*
             * Fix up the old page -- the extra 2 are the fields
             * which contained the overflow information.
             */
            ino[0] -= (moved + 2);
            FREESPACE(ino) =
                scopyto - sizeof(uint16) * (ino[0] + 3);
            OFFSET(ino) = scopyto;

            bufp = __get_buf(hashp, ov_addr, bufp, 0);
            if (!bufp)
                return (-1);

            ino = (uint16 *)bufp->page;
            n = 1;
            scopyto = hashp->BSIZE;
            moved = 0;

            if (last_bfp)
                __free_ovflpage(hashp, last_bfp);
            last_bfp = bufp;
        }
        /* Move regular sized pairs of there are any */
        off = hashp->BSIZE;
        for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
            cino = (char *)ino;
            key.data = (uint8 *)cino + ino[n];
            key.size = off - ino[n];
            val.data = (uint8 *)cino + ino[n + 1];
            val.size = ino[n] - ino[n + 1];
            off = ino[n + 1];

            if (__call_hash(hashp, (char *)key.data, key.size) == obucket) {
                /* Keep on old page */
                if (PAIRFITS(op, (&key), (&val)))
                    putpair((char *)op, &key, &val);
                else {
                    old_bufp =
                        __add_ovflpage(hashp, old_bufp);
                    if (!old_bufp)
                        return (-1);
                    op = (uint16 *)old_bufp->page;
                    putpair((char *)op, &key, &val);
                }
                old_bufp->flags |= BUF_MOD;
            } else {
                /* Move to new page */
                if (PAIRFITS(np, (&key), (&val)))
                    putpair((char *)np, &key, &val);
                else {
                    new_bufp =
                        __add_ovflpage(hashp, new_bufp);
                    if (!new_bufp)
                        return (-1);
                    np = (uint16 *)new_bufp->page;
                    putpair((char *)np, &key, &val);
                }
                new_bufp->flags |= BUF_MOD;
            }
        }
    }
    if (last_bfp)
        __free_ovflpage(hashp, last_bfp);
    return (0);
}
Пример #20
0
void gt_substriter_delete(Substriter **substriter)
{
  gt_multimappowerfree(&(*substriter)->multimappower);
  FREESPACE(*substriter);
}
Пример #21
0
void gt_tyrsearchinfo_delete(Tyrsearchinfo *tyrsearchinfo)
{
  gt_alphabet_delete(tyrsearchinfo->dnaalpha);
  FREESPACE(tyrsearchinfo->bytecode);
  FREESPACE(tyrsearchinfo->rcbuf);
}
Пример #22
0
/*
 * Returns:
 *	 0 ==> OK
 *	-1 ==> Error
 */
int
__split_page(HTAB *hashp, uint32_t obucket, uint32_t nbucket)
{
	BUFHEAD *new_bufp, *old_bufp;
	uint16_t *ino;
	char *np;
	DBT key, val;
	int n, ndx, retval;
	uint16_t copyto, diff, off, moved;
	char *op;
	size_t temp;

	copyto = (uint16_t)hashp->BSIZE;
	off = (uint16_t)hashp->BSIZE;
	old_bufp = __get_buf(hashp, obucket, NULL, 0);
	if (old_bufp == NULL)
		return (-1);
	new_bufp = __get_buf(hashp, nbucket, NULL, 0);
	if (new_bufp == NULL)
		return (-1);

	old_bufp->flags |= (BUF_MOD | BUF_PIN);
	new_bufp->flags |= (BUF_MOD | BUF_PIN);

	ino = (uint16_t *)(void *)(op = old_bufp->page);
	np = new_bufp->page;

	moved = 0;

	for (n = 1, ndx = 1; n < ino[0]; n += 2) {
		if (ino[n + 1] < REAL_KEY) {
			retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
			    (int)copyto, (int)moved);
			old_bufp->flags &= ~BUF_PIN;
			new_bufp->flags &= ~BUF_PIN;
			return (retval);

		}
		key.data = (uint8_t *)op + ino[n];
		key.size = off - ino[n];

		if (__call_hash(hashp, key.data, (int)key.size) == obucket) {
			/* Don't switch page */
			diff = copyto - off;
			if (diff) {
				copyto = ino[n + 1] + diff;
				memmove(op + copyto, op + ino[n + 1],
				    (size_t)(off - ino[n + 1]));
				ino[ndx] = copyto + ino[n] - ino[n + 1];
				ino[ndx + 1] = copyto;
			} else
				copyto = ino[n + 1];
			ndx += 2;
		} else {
			/* Switch page */
			val.data = (uint8_t *)op + ino[n + 1];
			val.size = ino[n] - ino[n + 1];
			putpair(np, &key, &val);
			moved += 2;
		}

		off = ino[n + 1];
	}

	/* Now clean up the page */
	ino[0] -= moved;
	temp = sizeof(uint16_t) * (ino[0] + 3);
	_DIAGASSERT(copyto >= temp);
	FREESPACE(ino) = (uint16_t)(copyto - temp);
	OFFSET(ino) = copyto;

#ifdef DEBUG3
	(void)fprintf(stderr, "split %d/%d\n",
	    ((uint16_t *)np)[0] / 2,
	    ((uint16_t *)op)[0] / 2);
#endif
	/* unpin both pages */
	old_bufp->flags &= ~BUF_PIN;
	new_bufp->flags &= ~BUF_PIN;
	return (0);
}
Пример #23
0
/*
 * Add the given pair to the page
 *
 * Returns:
 *  0 ==> OK
 *  1 ==> failure
 */
extern int
__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
    register uint16 *bp, *sop;
    int do_expand;

    bp = (uint16 *)bufp->page;
    do_expand = 0;
    while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
        /* Exception case */
        if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
            /* This is the last page of a big key/data pair
               and we need to add another page */
            break;
        else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
            bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
            if (!bufp) {
#ifdef DEBUG
                assert(0);
#endif
                return (-1);
            }
            bp = (uint16 *)bufp->page;
        } else
            /* Try to squeeze key on this page */
            if (FREESPACE(bp) > PAIRSIZE(key, val)) {
            {
                squeeze_key(bp, key, val);

                /* LJM: I added this because I think it was
                 * left out on accident.
                 * if this isn't incremented nkeys will not
                 * be the actual number of keys in the db.
                 */
                hashp->NKEYS++;
                return (0);
            }
        } else {
            bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
            if (!bufp) {
#ifdef DEBUG
                assert(0);
#endif
                return (-1);
            }
            bp = (uint16 *)bufp->page;
        }

    if (PAIRFITS(bp, key, val))
        putpair(bufp->page, key, (DBT *)val);
    else {
        do_expand = 1;
        bufp = __add_ovflpage(hashp, bufp);
        if (!bufp) {
#ifdef DEBUG
            assert(0);
#endif
            return (-1);
        }
        sop = (uint16 *)bufp->page;

        if (PAIRFITS(sop, key, val))
            putpair((char *)sop, key, (DBT *)val);
        else if (__big_insert(hashp, bufp, key, val)) {
#ifdef DEBUG
            assert(0);
#endif
            return (-1);
        }
    }
    bufp->flags |= BUF_MOD;
    /*
     * If the average number of keys per bucket exceeds the fill factor,
     * expand the table.
     */
    hashp->NKEYS++;
    if (do_expand ||
        (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
        return (__expand_table(hashp));
    return (0);
}
Пример #24
0
/*
 * Called when we encounter an overflow or big key/data page during split
 * handling.  This is special cased since we have to begin checking whether
 * the key/data pairs fit on their respective pages and because we may need
 * overflow pages for both the old and new pages.
 *
 * The first page might be a page with regular key/data pairs in which case
 * we have a regular overflow condition and just need to go on to the next
 * page or it might be a big key/data pair in which case we need to fix the
 * big key/data pair.
 *
 * Returns:
 *	 0 ==> success
 *	-1 ==> failure
 */
static int
ugly_split(
	HTAB *hashp,
	uint32_t obucket,	/* Same as __split_page. */
	BUFHEAD *old_bufp,
	BUFHEAD *new_bufp,
	int copyto,	/* First byte on page which contains key/data values. */
	int moved	/* Number of pairs moved to new page. */
)
{
	BUFHEAD *bufp;	/* Buffer header for ino */
	uint16_t *ino;	/* Page keys come off of */
	uint16_t *np;	/* New page */
	uint16_t *op;	/* Page keys go on to if they aren't moving */
	size_t temp;

	BUFHEAD *last_bfp;	/* Last buf header OVFL needing to be freed */
	DBT key, val;
	SPLIT_RETURN ret;
	uint16_t n, off, ov_addr, scopyto;
	char *cino;		/* Character value of ino */

	bufp = old_bufp;
	ino = (uint16_t *)(void *)old_bufp->page;
	np = (uint16_t *)(void *)new_bufp->page;
	op = (uint16_t *)(void *)old_bufp->page;
	last_bfp = NULL;
	scopyto = (uint16_t)copyto;	/* ANSI */

	n = ino[0] - 1;
	while (n < ino[0]) {
		if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
			if (__big_split(hashp, old_bufp,
			    new_bufp, bufp, (int)bufp->addr, obucket, &ret))
				return (-1);
			old_bufp = ret.oldp;
			if (!old_bufp)
				return (-1);
			op = (uint16_t *)(void *)old_bufp->page;
			new_bufp = ret.newp;
			if (!new_bufp)
				return (-1);
			np = (uint16_t *)(void *)new_bufp->page;
			bufp = ret.nextp;
			if (!bufp)
				return (0);
			cino = (char *)bufp->page;
			ino = (uint16_t *)(void *)cino;
			last_bfp = ret.nextp;
		} else if (ino[n + 1] == OVFLPAGE) {
			ov_addr = ino[n];
			/*
			 * Fix up the old page -- the extra 2 are the fields
			 * which contained the overflow information.
			 */
			ino[0] -= (moved + 2);
			temp = sizeof(uint16_t) * (ino[0] + 3);
			_DIAGASSERT(scopyto >= temp);
			FREESPACE(ino) = (uint16_t)(scopyto - temp);
			OFFSET(ino) = scopyto;

			bufp = __get_buf(hashp, (uint32_t)ov_addr, bufp, 0);
			if (!bufp)
				return (-1);

			ino = (uint16_t *)(void *)bufp->page;
			n = 1;
			scopyto = hashp->BSIZE;
			moved = 0;

			if (last_bfp)
				__free_ovflpage(hashp, last_bfp);
			last_bfp = bufp;
		}
		/* Move regular sized pairs of there are any */
		off = hashp->BSIZE;
		for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
			cino = (char *)(void *)ino;
			key.data = (uint8_t *)cino + ino[n];
			key.size = off - ino[n];
			val.data = (uint8_t *)cino + ino[n + 1];
			val.size = ino[n] - ino[n + 1];
			off = ino[n + 1];

			if (__call_hash(hashp, key.data, (int)key.size) == obucket) {
				/* Keep on old page */
				if (PAIRFITS(op, (&key), (&val)))
					putpair((char *)(void *)op, &key, &val);
				else {
					old_bufp =
					    __add_ovflpage(hashp, old_bufp);
					if (!old_bufp)
						return (-1);
					op = (uint16_t *)(void *)old_bufp->page;
					putpair((char *)(void *)op, &key, &val);
				}
				old_bufp->flags |= BUF_MOD;
			} else {
				/* Move to new page */
				if (PAIRFITS(np, (&key), (&val)))
					putpair((char *)(void *)np, &key, &val);
				else {
					new_bufp =
					    __add_ovflpage(hashp, new_bufp);
					if (!new_bufp)
						return (-1);
					np = (uint16_t *)(void *)new_bufp->page;
					putpair((char *)(void *)np, &key, &val);
				}
				new_bufp->flags |= BUF_MOD;
			}
		}
	}
	if (last_bfp)
		__free_ovflpage(hashp, last_bfp);
	return (0);
}
Пример #25
0
/*
 * Big_insert
 *
 * You need to do an insert and the key/data pair is too big
 *
 * Returns:
 * 0 ==> OK
 *-1 ==> ERROR
 */
extern int
dbm_big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
    register uint16 *p;
    uint key_size, n, val_size;
    uint16 space, move_bytes, off;
    char *cp, *key_data, *val_data;

    cp = bufp->page; /* Character pointer of p. */
    p = (uint16 *)cp;

    key_data = (char *)key->data;
    key_size = key->size;
    val_data = (char *)val->data;
    val_size = val->size;

    /* First move the Key */
    for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
         space = FREESPACE(p) - BIGOVERHEAD) {
        move_bytes = PR_MIN(space, key_size);
        off = OFFSET(p) - move_bytes;
        memmove(cp + off, key_data, move_bytes);
        key_size -= move_bytes;
        key_data += move_bytes;
        n = p[0];
        p[++n] = off;
        p[0] = ++n;
        FREESPACE(p) = off - PAGE_META(n);
        OFFSET(p) = off;
        p[n] = PARTIAL_KEY;
        bufp = dbm_add_ovflpage(hashp, bufp);
        if (!bufp)
            return (-1);
        n = p[0];
        if (!key_size) {
            if (FREESPACE(p)) {
                move_bytes = PR_MIN(FREESPACE(p), val_size);
                off = OFFSET(p) - move_bytes;
                p[n] = off;
                memmove(cp + off, val_data, move_bytes);
                val_data += move_bytes;
                val_size -= move_bytes;
                p[n - 2] = FULL_KEY_DATA;
                FREESPACE(p) = FREESPACE(p) - move_bytes;
                OFFSET(p) = off;
            } else
                p[n - 2] = FULL_KEY;
        }
        p = (uint16 *)bufp->page;
        cp = bufp->page;
        bufp->flags |= BUF_MOD;
    }

    /* Now move the data */
    for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
         space = FREESPACE(p) - BIGOVERHEAD) {
        move_bytes = PR_MIN(space, val_size);
        /*
         * Here's the hack to make sure that if the data ends on the
         * same page as the key ends, FREESPACE is at least one.
         */
        if (space == val_size && val_size == val->size)
            move_bytes--;
        off = OFFSET(p) - move_bytes;
        memmove(cp + off, val_data, move_bytes);
        val_size -= move_bytes;
        val_data += move_bytes;
        n = p[0];
        p[++n] = off;
        p[0] = ++n;
        FREESPACE(p) = off - PAGE_META(n);
        OFFSET(p) = off;
        if (val_size) {
            p[n] = FULL_KEY;
            bufp = dbm_add_ovflpage(hashp, bufp);
            if (!bufp)
                return (-1);
            cp = bufp->page;
            p = (uint16 *)cp;
        } else
            p[n] = FULL_KEY_DATA;
        bufp->flags |= BUF_MOD;
    }
    return (0);
}