Beispiel #1
0
/*
 * Returns:
 *	 0 OK
 *	-1 error
 */
int
__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx)
{
	u_int16_t *bp, newoff, pairlen;
	int n;

	bp = (u_int16_t *)bufp->page;
	n = bp[0];

	if (bp[ndx + 1] < REAL_KEY)
		return (__big_delete(hashp, bufp));
	if (ndx != 1)
		newoff = bp[ndx - 1];
	else
		newoff = hashp->BSIZE;
	pairlen = newoff - bp[ndx + 1];

	if (ndx != (n - 1)) {
		/* Hard Case -- need to shuffle keys */
		int i;
		char *src = bufp->page + (int)OFFSET(bp);
		char *dst = src + (int)pairlen;
		memmove(dst, src, bp[ndx + 1] - OFFSET(bp));

		/* Now adjust the pointers */
		for (i = ndx + 2; i <= n; i += 2) {
			if (bp[i + 1] == OVFLPAGE) {
				bp[i - 2] = bp[i];
				bp[i - 1] = bp[i + 1];
			} else {
				bp[i - 2] = bp[i] + pairlen;
				bp[i - 1] = bp[i + 1] + pairlen;
			}
		}
		if (ndx == hashp->cndx) {
			/*
			 * We just removed pair we were "pointing" to.
			 * By moving back the cndx we ensure subsequent
			 * hash_seq() calls won't skip over any entries.
			 */
			hashp->cndx -= 2;
		}
	}
	/* Finally adjust the page data */
	bp[n] = OFFSET(bp) + pairlen;
	bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
	bp[0] = n - 2;
	hashp->NKEYS--;

	bufp->flags |= BUF_MOD;
	return (0);
}
Beispiel #2
0
/*
 * Returns:
 *	 0 OK
 *	-1 error
 */
int
__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx)
{
	uint16_t *bp, newoff;
	int n;
	uint16_t pairlen;
	size_t temp;

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

	if (bp[ndx + 1] < REAL_KEY)
		return (__big_delete(hashp, bufp));
	if (ndx != 1)
		newoff = bp[ndx - 1];
	else
		newoff = hashp->BSIZE;
	pairlen = newoff - bp[ndx + 1];

	if (ndx != (n - 1)) {
		/* Hard Case -- need to shuffle keys */
		int i;
		char *src = bufp->page + (int)OFFSET(bp);
		char *dst = src + (int)pairlen;
		memmove(dst, src, (size_t)(bp[ndx + 1] - OFFSET(bp)));

		/* Now adjust the pointers */
		for (i = ndx + 2; i <= n; i += 2) {
			if (bp[i + 1] == OVFLPAGE) {
				bp[i - 2] = bp[i];
				bp[i - 1] = bp[i + 1];
			} else {
				bp[i - 2] = bp[i] + pairlen;
				bp[i - 1] = bp[i + 1] + pairlen;
			}
		}
	}
	/* Finally adjust the page data */
	bp[n] = OFFSET(bp) + pairlen;
	temp = bp[n + 1] + pairlen + 2 * sizeof(uint16_t);
	_DIAGASSERT(temp <= 0xffff);
	bp[n - 1] = (uint16_t)temp;
	bp[0] = n - 2;
	hashp->NKEYS--;

	bufp->flags |= BUF_MOD;
	return (0);
}
Beispiel #3
0
/*
 * Returns:
 *   0 OK
 *  -1 error
 */
extern int
__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx)
{
    register uint16 *bp, newoff;
    register int n;
    uint16 pairlen;

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

    if (bp[ndx + 1] < REAL_KEY)
        return (__big_delete(hashp, bufp));
    if (ndx != 1)
        newoff = bp[ndx - 1];
    else
        newoff = hashp->BSIZE;
    pairlen = newoff - bp[ndx + 1];

    if (ndx != (n - 1)) {
        /* Hard Case -- need to shuffle keys */
        register int i;
        register char *src = bufp->page + (int)OFFSET(bp);
        uint32 dst_offset = (uint32)OFFSET(bp) + (uint32)pairlen;
        register char *dst = bufp->page + dst_offset;
        uint32 length = bp[ndx + 1] - OFFSET(bp);

        /*
         * +-----------+XXX+---------+XXX+---------+---------> +infinity
         * |           |             |             |
         * 0           src_offset    dst_offset    BSIZE
         *
         * Dst_offset is > src_offset, so if src_offset were bad, dst_offset
         * would be too, therefore we check only dst_offset.
         *
         * If dst_offset is >= BSIZE, either OFFSET(bp), or pairlen, or both
         * is corrupted.
         *
         * Once we know dst_offset is < BSIZE, we can subtract it from BSIZE
         * to get an upper bound on length.
         */
        if (dst_offset > (uint32)hashp->BSIZE)
            return (DATABASE_CORRUPTED_ERROR);

        if (length > (uint32)(hashp->BSIZE - dst_offset))
            return (DATABASE_CORRUPTED_ERROR);

        memmove(dst, src, length);

        /* Now adjust the pointers */
        for (i = ndx + 2; i <= n; i += 2) {
            if (bp[i + 1] == OVFLPAGE) {
                bp[i - 2] = bp[i];
                bp[i - 1] = bp[i + 1];
            } else {
                bp[i - 2] = bp[i] + pairlen;
                bp[i - 1] = bp[i + 1] + pairlen;
            }
        }
    }
    /* Finally adjust the page data */
    bp[n] = OFFSET(bp) + pairlen;
    bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(uint16);
    bp[0] = n - 2;
    hashp->NKEYS--;

    bufp->flags |= BUF_MOD;
    return (0);
}