]> git.saurik.com Git - apple/libc.git/blobdiff - db/btree/bt_get.c
Libc-320.tar.gz
[apple/libc.git] / db / btree / bt_get.c
index e62c7ac2a3695f05af4583a254d86d49f412cb91..09479a745425d66d0f1ffb99498d8f7d47d02df6 100644 (file)
@@ -1,26 +1,29 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
-/*
- * Copyright (c) 1990, 1993
+/*-
+ * Copyright (c) 1990, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_get.c   8.6 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
 
 #include <sys/types.h>
 
@@ -109,148 +116,15 @@ __bt_get(dbp, key, data, flags)
                return (RET_SPECIAL);
        }
 
-       /*
-        * A special case is if we found the record but it's flagged for
-        * deletion.  In this case, we want to find another record with the
-        * same key, if it exists.  Rather than look around the tree we call
-        * __bt_first and have it redo the search, as __bt_first will not
-        * return keys marked for deletion.  Slow, but should never happen.
-        */
-       if (ISSET(t, B_DELCRSR) && e->page->pgno == t->bt_bcursor.pgno &&
-           e->index == t->bt_bcursor.index) {
-               mpool_put(t->bt_mp, e->page, 0);
-               if ((e = __bt_first(t, key, &exact)) == NULL)
-                       return (RET_ERROR);
-               if (!exact)
-                       return (RET_SPECIAL);
-       }
+       status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
 
-       status = __bt_ret(t, e, NULL, data);
        /*
         * If the user is doing concurrent access, we copied the
         * key/data, toss the page.
         */
-       if (ISSET(t, B_DB_LOCK))
+       if (F_ISSET(t, B_DB_LOCK))
                mpool_put(t->bt_mp, e->page, 0);
        else
                t->bt_pinned = e->page;
        return (status);
 }
-
-/*
- * __BT_FIRST -- Find the first entry.
- *
- * Parameters:
- *     t:      the tree
- *     key:    the key
- *
- * Returns:
- *     The first entry in the tree greater than or equal to key.
- */
-EPG *
-__bt_first(t, key, exactp)
-       BTREE *t;
-       const DBT *key;
-       int *exactp;
-{
-       register PAGE *h;
-       register EPG *e;
-       EPG save;
-       pgno_t cpgno, pg;
-       indx_t cindex;
-       int found;
-
-       /*
-        * Find any matching record; __bt_search pins the page.  Only exact
-        * matches are tricky, otherwise just return the location of the key
-        * if it were to be inserted into the tree.
-        */
-       if ((e = __bt_search(t, key, exactp)) == NULL)
-               return (NULL);
-       if (!*exactp)
-               return (e);
-
-       if (ISSET(t, B_DELCRSR)) {
-               cpgno = t->bt_bcursor.pgno;
-               cindex = t->bt_bcursor.index;
-       } else {
-               cpgno = P_INVALID;
-               cindex = 0;             /* GCC thinks it's uninitialized. */
-       }
-
-       /*
-        * Walk backwards, skipping empty pages, as long as the entry matches
-        * and there are keys left in the tree.  Save a copy of each match in
-        * case we go too far.  A special case is that we don't return a match
-        * on records that the cursor references that have already been flagged
-        * for deletion.
-        */
-       save = *e;
-       h = e->page;
-       found = 0;
-       do {
-               if (cpgno != h->pgno || cindex != e->index) {
-                       if (save.page->pgno != e->page->pgno) {
-                               mpool_put(t->bt_mp, save.page, 0);
-                               save = *e;
-                       } else
-                               save.index = e->index;
-                       found = 1;
-               }
-               /*
-                * Make a special effort not to unpin the page the last (or
-                * original) match was on, but also make sure it's unpinned
-                * if an error occurs.
-                */
-               while (e->index == 0) {
-                       if (h->prevpg == P_INVALID)
-                               goto done1;
-                       if (h->pgno != save.page->pgno)
-                               mpool_put(t->bt_mp, h, 0);
-                       if ((h = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) {
-                               if (h->pgno == save.page->pgno)
-                                       mpool_put(t->bt_mp, save.page, 0);
-                               return (NULL);
-                       }
-                       e->page = h;
-                       e->index = NEXTINDEX(h);
-               }
-               --e->index;
-       } while (__bt_cmp(t, key, e) == 0);
-
-       /*
-        * Reach here with the last page that was looked at pinned, which may
-        * or may not be the same as the last (or original) match page.  If
-        * it's not useful, release it.
-        */
-done1: if (h->pgno != save.page->pgno)
-               mpool_put(t->bt_mp, h, 0);
-
-       /*
-        * If still haven't found a record, the only possibility left is the
-        * next one.  Move forward one slot, skipping empty pages and check.
-        */
-       if (!found) {
-               h = save.page;
-               if (++save.index == NEXTINDEX(h)) {
-                       do {
-                               pg = h->nextpg;
-                               mpool_put(t->bt_mp, h, 0);
-                               if (pg == P_INVALID) {
-                                       *exactp = 0;
-                                       return (e);
-                               }
-                               if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
-                                       return (NULL);
-                       } while ((save.index = NEXTINDEX(h)) == 0);
-                       save.page = h;
-               }
-               if (__bt_cmp(t, key, &save) != 0) {
-                       *exactp = 0;
-                       return (e);
-               }
-       }
-       *e = save;
-       *exactp = 1;
-       return (e);
-}