source: rtems-libbsd/freebsd-userspace/lib/libc/db/recno/rec_delete.c @ e4e1746

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since e4e1746 was e4e1746, checked in by Jennifer Averett <jennifer.averett@…>, on 09/12/12 at 15:59:41

Added userspace db files.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1#include "port_before.h"
2
3/*-
4 * Copyright (c) 1990, 1993, 1994
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Mike Olson.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 4. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if defined(LIBC_SCCS) && !defined(lint)
36static char sccsid[] = "@(#)rec_delete.c        8.7 (Berkeley) 7/14/94";
37#endif /* LIBC_SCCS and not lint */
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41#include <sys/types.h>
42
43#include <errno.h>
44#include <stdio.h>
45#include <string.h>
46
47#include <db.h>
48#include "recno.h"
49
50static int rec_rdelete(BTREE *, recno_t);
51
52/*
53 * __REC_DELETE -- Delete the item(s) referenced by a key.
54 *
55 * Parameters:
56 *      dbp:    pointer to access method
57 *      key:    key to delete
58 *      flags:  R_CURSOR if deleting what the cursor references
59 *
60 * Returns:
61 *      RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
62 */
63int
64__rec_delete(const DB *dbp, const DBT *key, u_int flags)
65{
66        BTREE *t;
67        recno_t nrec;
68        int status;
69
70        t = dbp->internal;
71
72        /* Toss any page pinned across calls. */
73        if (t->bt_pinned != NULL) {
74                mpool_put(t->bt_mp, t->bt_pinned, 0);
75                t->bt_pinned = NULL;
76        }
77
78        switch(flags) {
79        case 0:
80                if ((nrec = *(recno_t *)key->data) == 0)
81                        goto einval;
82                if (nrec > t->bt_nrecs)
83                        return (RET_SPECIAL);
84                --nrec;
85                status = rec_rdelete(t, nrec);
86                break;
87        case R_CURSOR:
88                if (!F_ISSET(&t->bt_cursor, CURS_INIT))
89                        goto einval;
90                if (t->bt_nrecs == 0)
91                        return (RET_SPECIAL);
92                status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
93                if (status == RET_SUCCESS)
94                        --t->bt_cursor.rcursor;
95                break;
96        default:
97einval:         errno = EINVAL;
98                return (RET_ERROR);
99        }
100
101        if (status == RET_SUCCESS)
102                F_SET(t, B_MODIFIED | R_MODIFIED);
103        return (status);
104}
105
106/*
107 * REC_RDELETE -- Delete the data matching the specified key.
108 *
109 * Parameters:
110 *      tree:   tree
111 *      nrec:   record to delete
112 *
113 * Returns:
114 *      RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
115 */
116static int
117rec_rdelete(BTREE *t, recno_t nrec)
118{
119        EPG *e;
120        PAGE *h;
121        int status;
122
123        /* Find the record; __rec_search pins the page. */
124        if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
125                return (RET_ERROR);
126
127        /* Delete the record. */
128        h = e->page;
129        status = __rec_dleaf(t, h, e->index);
130        if (status != RET_SUCCESS) {
131                mpool_put(t->bt_mp, h, 0);
132                return (status);
133        }
134        mpool_put(t->bt_mp, h, MPOOL_DIRTY);
135        return (RET_SUCCESS);
136}
137
138/*
139 * __REC_DLEAF -- Delete a single record from a recno leaf page.
140 *
141 * Parameters:
142 *      t:      tree
143 *      idx:    index on current page to delete
144 *
145 * Returns:
146 *      RET_SUCCESS, RET_ERROR.
147 */
148int
149__rec_dleaf(BTREE *t, PAGE *h, u_int32_t idx)
150{
151        RLEAF *rl;
152        indx_t *ip, cnt, offset;
153        u_int32_t nbytes;
154        char *from;
155        void *to;
156
157        /*
158         * Delete a record from a recno leaf page.  Internal records are never
159         * deleted from internal pages, regardless of the records that caused
160         * them to be added being deleted.  Pages made empty by deletion are
161         * not reclaimed.  They are, however, made available for reuse.
162         *
163         * Pack the remaining entries at the end of the page, shift the indices
164         * down, overwriting the deleted record and its index.  If the record
165         * uses overflow pages, make them available for reuse.
166         */
167        to = rl = GETRLEAF(h, idx);
168        if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
169                return (RET_ERROR);
170        nbytes = NRLEAF(rl);
171
172        /*
173         * Compress the key/data pairs.  Compress and adjust the [BR]LEAF
174         * offsets.  Reset the headers.
175         */
176        from = (char *)h + h->upper;
177        memmove(from + nbytes, from, (char *)to - from);
178        h->upper += nbytes;
179
180        offset = h->linp[idx];
181        for (cnt = &h->linp[idx] - (ip = &h->linp[0]); cnt--; ++ip)
182                if (ip[0] < offset)
183                        ip[0] += nbytes;
184        for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
185                ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
186        h->lower -= sizeof(indx_t);
187        --t->bt_nrecs;
188        return (RET_SUCCESS);
189}
Note: See TracBrowser for help on using the repository browser.