]>
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 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1990, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 #include <sys/types.h>
70 * __REC_PUT -- Add a recno item to the tree.
73 * dbp: pointer to access method
76 * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
79 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
80 * already in the tree and R_NOOVERWRITE specified.
83 __rec_put(dbp
, key
, data
, flags
)
96 /* Toss any page pinned across calls. */
97 if (t
->bt_pinned
!= NULL
) {
98 mpool_put(t
->bt_mp
, t
->bt_pinned
, 0);
104 if (!ISSET(t
, B_SEQINIT
))
106 nrec
= t
->bt_rcursor
;
109 if ((nrec
= *(recno_t
*)key
->data
) == 0)
113 if ((nrec
= *(recno_t
*)key
->data
) == 0) {
120 if ((nrec
= *(recno_t
*)key
->data
) == 0)
124 if ((nrec
= *(recno_t
*)key
->data
) == 0)
126 if (nrec
<= t
->bt_nrecs
)
127 return (RET_SPECIAL
);
130 einval
: errno
= EINVAL
;
135 * Make sure that records up to and including the put record are
136 * already in the database. If skipping records, create empty ones.
138 if (nrec
> t
->bt_nrecs
) {
139 if (!ISSET(t
, R_EOF
| R_INMEM
) &&
140 t
->bt_irec(t
, nrec
) == RET_ERROR
)
142 if (nrec
> t
->bt_nrecs
+ 1) {
143 if (ISSET(t
, R_FIXLEN
)) {
145 (void *)malloc(t
->bt_reclen
)) == NULL
)
147 tdata
.size
= t
->bt_reclen
;
148 memset(tdata
.data
, t
->bt_bval
, tdata
.size
);
153 while (nrec
> t
->bt_nrecs
+ 1)
155 t
->bt_nrecs
, &tdata
, 0) != RET_SUCCESS
)
157 if (ISSET(t
, R_FIXLEN
))
162 if ((status
= __rec_iput(t
, nrec
- 1, data
, flags
)) != RET_SUCCESS
)
165 if (flags
== R_SETCURSOR
)
166 t
->bt_rcursor
= nrec
;
169 return (__rec_ret(t
, NULL
, nrec
, key
, NULL
));
173 * __REC_IPUT -- Add a recno item to the tree.
177 * nrec: record number
181 * RET_ERROR, RET_SUCCESS
184 __rec_iput(t
, nrec
, data
, flags
)
193 indx_t index
, nxtindex
;
197 char *dest
, db
[NOVFLSIZE
];
200 * If the data won't fit on a page, store it on indirect pages.
203 * If the insert fails later on, these pages aren't recovered.
205 if (data
->size
> t
->bt_ovflsize
) {
206 if (__ovfl_put(t
, data
, &pg
) == RET_ERROR
)
209 tdata
.size
= NOVFLSIZE
;
211 *(size_t *)(db
+ sizeof(pgno_t
)) = data
->size
;
217 /* __rec_search pins the returned page. */
218 if ((e
= __rec_search(t
, nrec
,
219 nrec
> t
->bt_nrecs
|| flags
== R_IAFTER
|| flags
== R_IBEFORE
?
220 SINSERT
: SEARCH
)) == NULL
)
227 * Add the specified key/data pair to the tree. The R_IAFTER and
228 * R_IBEFORE flags insert the key after/before the specified key.
230 * Pages are split as required.
239 if (nrec
< t
->bt_nrecs
&&
240 __rec_dleaf(t
, h
, index
) == RET_ERROR
) {
241 mpool_put(t
->bt_mp
, h
, 0);
248 * If not enough room, split the page. The split code will insert
249 * the key and data and unpin the current page. If inserting into
250 * the offset array, shift the pointers up.
252 nbytes
= NRLEAFDBT(data
->size
);
253 if (h
->upper
- h
->lower
< nbytes
+ sizeof(indx_t
)) {
254 status
= __bt_split(t
, h
, NULL
, data
, dflags
, nbytes
, index
);
255 if (status
== RET_SUCCESS
)
260 if (index
< (nxtindex
= NEXTINDEX(h
)))
261 memmove(h
->linp
+ index
+ 1, h
->linp
+ index
,
262 (nxtindex
- index
) * sizeof(indx_t
));
263 h
->lower
+= sizeof(indx_t
);
265 h
->linp
[index
] = h
->upper
-= nbytes
;
266 dest
= (char *)h
+ h
->upper
;
267 WR_RLEAF(dest
, data
, dflags
);
271 mpool_put(t
->bt_mp
, h
, MPOOL_DIRTY
);
273 return (RET_SUCCESS
);