]>
git.saurik.com Git - apple/libc.git/blob - db/recno/rec_put.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1990, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 #include <sys/types.h>
67 * __REC_PUT -- Add a recno item to the tree.
70 * dbp: pointer to access method
73 * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
76 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
77 * already in the tree and R_NOOVERWRITE specified.
80 __rec_put(dbp
, key
, data
, flags
)
93 /* Toss any page pinned across calls. */
94 if (t
->bt_pinned
!= NULL
) {
95 mpool_put(t
->bt_mp
, t
->bt_pinned
, 0);
101 if (!ISSET(t
, B_SEQINIT
))
103 nrec
= t
->bt_rcursor
;
106 if ((nrec
= *(recno_t
*)key
->data
) == 0)
110 if ((nrec
= *(recno_t
*)key
->data
) == 0) {
117 if ((nrec
= *(recno_t
*)key
->data
) == 0)
121 if ((nrec
= *(recno_t
*)key
->data
) == 0)
123 if (nrec
<= t
->bt_nrecs
)
124 return (RET_SPECIAL
);
127 einval
: errno
= EINVAL
;
132 * Make sure that records up to and including the put record are
133 * already in the database. If skipping records, create empty ones.
135 if (nrec
> t
->bt_nrecs
) {
136 if (!ISSET(t
, R_EOF
| R_INMEM
) &&
137 t
->bt_irec(t
, nrec
) == RET_ERROR
)
139 if (nrec
> t
->bt_nrecs
+ 1) {
140 if (ISSET(t
, R_FIXLEN
)) {
142 (void *)malloc(t
->bt_reclen
)) == NULL
)
144 tdata
.size
= t
->bt_reclen
;
145 memset(tdata
.data
, t
->bt_bval
, tdata
.size
);
150 while (nrec
> t
->bt_nrecs
+ 1)
152 t
->bt_nrecs
, &tdata
, 0) != RET_SUCCESS
)
154 if (ISSET(t
, R_FIXLEN
))
159 if ((status
= __rec_iput(t
, nrec
- 1, data
, flags
)) != RET_SUCCESS
)
162 if (flags
== R_SETCURSOR
)
163 t
->bt_rcursor
= nrec
;
166 return (__rec_ret(t
, NULL
, nrec
, key
, NULL
));
170 * __REC_IPUT -- Add a recno item to the tree.
174 * nrec: record number
178 * RET_ERROR, RET_SUCCESS
181 __rec_iput(t
, nrec
, data
, flags
)
190 indx_t index
, nxtindex
;
194 char *dest
, db
[NOVFLSIZE
];
197 * If the data won't fit on a page, store it on indirect pages.
200 * If the insert fails later on, these pages aren't recovered.
202 if (data
->size
> t
->bt_ovflsize
) {
203 if (__ovfl_put(t
, data
, &pg
) == RET_ERROR
)
206 tdata
.size
= NOVFLSIZE
;
208 *(size_t *)(db
+ sizeof(pgno_t
)) = data
->size
;
214 /* __rec_search pins the returned page. */
215 if ((e
= __rec_search(t
, nrec
,
216 nrec
> t
->bt_nrecs
|| flags
== R_IAFTER
|| flags
== R_IBEFORE
?
217 SINSERT
: SEARCH
)) == NULL
)
224 * Add the specified key/data pair to the tree. The R_IAFTER and
225 * R_IBEFORE flags insert the key after/before the specified key.
227 * Pages are split as required.
236 if (nrec
< t
->bt_nrecs
&&
237 __rec_dleaf(t
, h
, index
) == RET_ERROR
) {
238 mpool_put(t
->bt_mp
, h
, 0);
245 * If not enough room, split the page. The split code will insert
246 * the key and data and unpin the current page. If inserting into
247 * the offset array, shift the pointers up.
249 nbytes
= NRLEAFDBT(data
->size
);
250 if (h
->upper
- h
->lower
< nbytes
+ sizeof(indx_t
)) {
251 status
= __bt_split(t
, h
, NULL
, data
, dflags
, nbytes
, index
);
252 if (status
== RET_SUCCESS
)
257 if (index
< (nxtindex
= NEXTINDEX(h
)))
258 memmove(h
->linp
+ index
+ 1, h
->linp
+ index
,
259 (nxtindex
- index
) * sizeof(indx_t
));
260 h
->lower
+= sizeof(indx_t
);
262 h
->linp
[index
] = h
->upper
-= nbytes
;
263 dest
= (char *)h
+ h
->upper
;
264 WR_RLEAF(dest
, data
, dflags
);
268 mpool_put(t
->bt_mp
, h
, MPOOL_DIRTY
);
270 return (RET_SUCCESS
);