Ejemplo n.º 1
0
/*
 * REC_RDELETE -- Delete the data matching the specified key.
 *
 * Parameters:
 *	tree:	tree
 *	nrec:	record to delete
 *
 * Returns:
 *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
 */
static int
rec_rdelete(BTREE *t, recno_t nrec)
{
	EPG *e;
	PAGE *h;
	int status;

	/* Find the record; __rec_search pins the page. */
	if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
		return (RET_ERROR);

	/* Delete the record. */
	h = e->page;
	status = __rec_dleaf(t, h, e->index);
	if (status != RET_SUCCESS) {
		mpool_put(t->bt_mp, h, 0);
		return (status);
	}
	mpool_put(t->bt_mp, h, MPOOL_DIRTY);
	return (RET_SUCCESS);
}
Ejemplo n.º 2
0
/*
 * __REC_IPUT -- Add a recno item to the tree.
 *
 * Parameters:
 *	t:	tree
 *	nrec:	record number
 *	data:	data
 *
 * Returns:
 *	RET_ERROR, RET_SUCCESS
 */
int
__rec_iput(BTREE *t, recno_t nrec, const DBT *data, u_int flags)
{
    DBT tdata;
    EPG *e;
    PAGE *h;
    indx_t idx, nxtindex;
    pgno_t pg;
    uint32_t nbytes;
    int dflags, status;
    char *dest, db[NOVFLSIZE];

    /*
     * If the data won't fit on a page, store it on indirect pages.
     *
     * XXX
     * If the insert fails later on, these pages aren't recovered.
     */
    if (data->size > t->bt_ovflsize) {
        if (__ovfl_put(t, data, &pg) == RET_ERROR)
            return (RET_ERROR);
        tdata.data = db;
        tdata.size = NOVFLSIZE;
        *(pgno_t *)(void *)db = pg;
        _DBFIT(data->size, uint32_t);
        *(uint32_t *)(void *)(db + sizeof(pgno_t)) =
            (uint32_t)data->size;
        dflags = P_BIGDATA;
        data = &tdata;
    } else
        dflags = 0;

    /* __rec_search pins the returned page. */
    if ((e = __rec_search(t, nrec,
                          nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
                          SINSERT : SEARCH)) == NULL)
        return (RET_ERROR);

    h = e->page;
    idx = e->index;

    /*
     * Add the specified key/data pair to the tree.  The R_IAFTER and
     * R_IBEFORE flags insert the key after/before the specified key.
     *
     * Pages are split as required.
     */
    switch (flags) {
    case R_IAFTER:
        ++idx;
        break;
    case R_IBEFORE:
        break;
    default:
        if (nrec < t->bt_nrecs &&
                __rec_dleaf(t, h, (uint32_t)idx) == RET_ERROR) {
            mpool_put(t->bt_mp, h, 0);
            return (RET_ERROR);
        }
        break;
    }

    /*
     * If not enough room, split the page.  The split code will insert
     * the key and data and unpin the current page.  If inserting into
     * the offset array, shift the pointers up.
     */
    nbytes = NRLEAFDBT(data->size);
    if ((uint32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t)) {
        status = __bt_split(t, h, NULL, data, dflags, nbytes,
                            (uint32_t)idx);
        if (status == RET_SUCCESS)
            ++t->bt_nrecs;
        return (status);
    }

    if (idx < (nxtindex = NEXTINDEX(h)))
        memmove(h->linp + idx + 1, h->linp + idx,
                (nxtindex - idx) * sizeof(indx_t));
    h->lower += sizeof(indx_t);

    h->linp[idx] = h->upper -= nbytes;
    dest = (char *)(void *)h + h->upper;
    WR_RLEAF(dest, data, dflags);

    ++t->bt_nrecs;
    F_SET(t, B_MODIFIED);
    mpool_put(t->bt_mp, h, MPOOL_DIRTY);

    return (RET_SUCCESS);
}