/ Check-in [2d64cba3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More bug fixes in btree.c. (CVS 1323)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2d64cba38c0f5fffa18cb30c4c448278837de49d
User & Date: drh 2004-05-08 02:03:23
Context
2004-05-08
08:23
Change lots of internal symbols from sqliteXXX to sqlite3XXX so that the library links again. It doesn't work yet, due to changes in the btree layer calling convention. (CVS 1324) check-in: 8af6474c user: danielk1977 tags: trunk
02:03
More bug fixes in btree.c. (CVS 1323) check-in: 2d64cba3 user: drh tags: trunk
2004-05-07
23:50
More bug fixes in btree.c. (CVS 1322) check-in: a80939ef user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.112 2004/05/07 23:50:57 drh Exp $
           12  +** $Id: btree.c,v 1.113 2004/05/08 02:03:23 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  1447   1447       }
  1448   1448       nextPage = get4byte(aPayload);
  1449   1449       if( offset<ovflSize ){
  1450   1450         int a = amt;
  1451   1451         if( a + offset > ovflSize ){
  1452   1452           a = ovflSize - offset;
  1453   1453         }
  1454         -      memcpy(pBuf, &aPayload[offset], a);
         1454  +      memcpy(pBuf, &aPayload[offset+4], a);
  1455   1455         offset = 0;
  1456   1456         amt -= a;
  1457   1457         pBuf += a;
  1458   1458       }else{
  1459   1459         offset -= ovflSize;
  1460   1460       }
  1461   1461       sqlite3pager_unref(aPayload);
................................................................................
  2063   2063             if( d2<dist ) closest = i;
  2064   2064           }
  2065   2065         }else{
  2066   2066           closest = 0;
  2067   2067         }
  2068   2068         put4byte(&aData[4], n-1);
  2069   2069         *pPgno = get4byte(&aData[8+closest*4]);
  2070         -      memcpy(&aData[8+closest*4], &aData[4+closest*n], 4);
         2070  +      if( closest<k-1 ){
         2071  +        memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
         2072  +      }
         2073  +      put4byte(&pTrunk->aData[4], k-1);
  2071   2074         rc = getPage(pBt, *pPgno, ppPage);
  2072   2075         releasePage(pTrunk);
  2073   2076         if( rc==SQLITE_OK ){
  2074         -        sqlite3pager_dont_rollback(*ppPage);
         2077  +        sqlite3pager_dont_rollback((*ppPage)->aData);
  2075   2078           rc = sqlite3pager_write((*ppPage)->aData);
  2076   2079         }
  2077   2080       }
  2078   2081     }else{
  2079   2082       /* There are no pages on the freelist, so create a new page at the
  2080   2083       ** end of the file */
  2081   2084       *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
................................................................................
  2191   2194     int *pnSize                    /* Write cell size here */
  2192   2195   ){
  2193   2196     int nPayload;
  2194   2197     const void *pSrc;
  2195   2198     int nSrc, n, rc;
  2196   2199     int spaceLeft;
  2197   2200     MemPage *pOvfl = 0;
         2201  +  MemPage *pToRelease = 0;
  2198   2202     unsigned char *pPrior;
  2199   2203     unsigned char *pPayload;
  2200   2204     Btree *pBt = pPage->pBt;
  2201   2205     Pgno pgnoOvfl = 0;
  2202   2206     int nHeader;
  2203   2207   
  2204   2208     /* Fill in the header. */
................................................................................
  2234   2238     pPayload = &pCell[nHeader];
  2235   2239     pPrior = &pPayload[pBt->maxLocal];
  2236   2240   
  2237   2241     while( nPayload>0 ){
  2238   2242       if( spaceLeft==0 ){
  2239   2243         rc =  allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl);
  2240   2244         if( rc ){
         2245  +        releasePage(pToRelease);
  2241   2246           clearCell(pPage, pCell);
  2242   2247           return rc;
  2243   2248         }
  2244   2249         put4byte(pPrior, pgnoOvfl);
         2250  +      releasePage(pToRelease);
         2251  +      pToRelease = pOvfl;
  2245   2252         pPrior = pOvfl->aData;
  2246   2253         put4byte(pPrior, 0);
  2247   2254         pPayload = &pOvfl->aData[4];
  2248   2255         spaceLeft = pBt->pageSize - 4;
  2249   2256       }
  2250   2257       n = nPayload;
  2251   2258       if( n>spaceLeft ) n = spaceLeft;
  2252   2259       if( n>nSrc ) n = nSrc;
  2253   2260       memcpy(pPayload, pSrc, n);
  2254   2261       nPayload -= n;
  2255   2262       pPayload += n;
         2263  +    pSrc += n;
  2256   2264       nSrc -= n;
  2257   2265       spaceLeft -= n;
  2258   2266       if( nSrc==0 ){
  2259   2267         nSrc = nData;
  2260   2268         pSrc = pData;
  2261   2269       }
  2262         -    if( pOvfl && (spaceLeft==0 || nPayload==0) ){
  2263         -      releasePage(pOvfl);
  2264         -    }
  2265   2270     }
         2271  +  releasePage(pToRelease);
  2266   2272     return SQLITE_OK;
  2267   2273   }
  2268   2274   
  2269   2275   /*
  2270   2276   ** Change the MemPage.pParent pointer on the page whose number is
  2271   2277   ** given in the second argument so that MemPage.pParent holds the
  2272   2278   ** pointer in the third argument.

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.28 2004/05/07 23:50:57 drh Exp $
           16  +** $Id: test3.c,v 1.29 2004/05/08 02:03:23 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "pager.h"
    20     20   #include "btree.h"
    21     21   #include "tcl.h"
    22     22   #include <stdlib.h>
    23     23   #include <string.h>
................................................................................
  1014   1014     for(i=0; i<sizeof(aResult)/sizeof(aResult[0]); i++){
  1015   1015       sprintf(&zBuf[j]," %d", aResult[i]);
  1016   1016       j += strlen(&zBuf[j]);
  1017   1017     }
  1018   1018     Tcl_AppendResult(interp, &zBuf[1], 0);
  1019   1019     return SQLITE_OK;
  1020   1020   }
         1021  +
         1022  +/*
         1023  +** The command is provided for the purpose of setting breakpoints.
         1024  +** in regression test scripts.
         1025  +**
         1026  +** By setting a GDB breakpoint on this procedure and executing the
         1027  +** btree_breakpoint command in a test script, we can stop GDB at
         1028  +** the point in the script where the btree_breakpoint command is
         1029  +** inserted.  This is useful for debugging.
         1030  +*/
         1031  +static int btree_breakpoint(
         1032  +  void *NotUsed,
         1033  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         1034  +  int argc,              /* Number of arguments */
         1035  +  const char **argv      /* Text of each argument */
         1036  +){
         1037  +  return TCL_OK;
         1038  +}
         1039  +
  1021   1040   
  1022   1041   /*
  1023   1042   ** Register commands with the TCL interpreter.
  1024   1043   */
  1025   1044   int Sqlitetest3_Init(Tcl_Interp *interp){
  1026   1045     static struct {
  1027   1046        char *zName;
................................................................................
  1053   1072        { "btree_key",                (Tcl_CmdProc*)btree_key                },
  1054   1073        { "btree_data",               (Tcl_CmdProc*)btree_data               },
  1055   1074        { "btree_payload_size",       (Tcl_CmdProc*)btree_payload_size       },
  1056   1075        { "btree_first",              (Tcl_CmdProc*)btree_first              },
  1057   1076        { "btree_last",               (Tcl_CmdProc*)btree_last               },
  1058   1077        { "btree_cursor_dump",        (Tcl_CmdProc*)btree_cursor_dump        },
  1059   1078        { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
         1079  +     { "btree_breakpoint",         (Tcl_CmdProc*)btree_breakpoint         },
  1060   1080     };
  1061   1081     int i;
  1062   1082   
  1063   1083     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1064   1084       Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1065   1085     }
  1066   1086     Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable,
  1067   1087        TCL_LINK_INT);
  1068   1088     return TCL_OK;
  1069   1089   }

Changes to test/btree.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is btree database backend
    13     13   #
    14         -# $Id: btree.test,v 1.17 2004/05/07 23:50:58 drh Exp $
           14  +# $Id: btree.test,v 1.18 2004/05/08 02:03:23 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Basic functionality.  Open and close a database.
    21     21   #
................................................................................
   637    637   do_test btree-8.4 {
   638    638     btree_delete $::c1
   639    639   } {}
   640    640   do_test btree-8.4.1 {
   641    641     lindex [btree_get_meta $::b1] 0
   642    642   } [expr {int(([string length $::data]-238+1019)/1020)}]
   643    643   do_test btree-8.5 {
   644         -  set data "*** This is an even longer key"
          644  +  set data "*** This is an even longer key "
   645    645     while {[string length $data]<2000} {append data $data}
          646  +  append data END
   646    647     set ::data $data
   647    648     btree_insert $::c1 2030 $data
   648    649   } {}
   649    650   do_test btree-8.6 {
   650         -  btree_move_to 2030
          651  +  btree_move_to $::c1 2030
   651    652     string length [btree_data $::c1]
   652    653   } [string length $::data]
   653    654   do_test btree-8.7 {
   654    655     btree_data $::c1
   655    656   } $::data
   656    657   do_test btree-8.8 {
   657    658     btree_commit $::b1
................................................................................
   667    668   } $::data
   668    669   do_test btree-8.10 {
   669    670     btree_begin_transaction $::b1
   670    671     btree_delete $::c1
   671    672   } {}
   672    673   do_test btree-8.11 {
   673    674     lindex [btree_get_meta $::b1] 0
   674         -} {}
          675  +} {4}
   675    676   
   676    677   # Now check out keys on overflow pages.
   677    678   #
   678    679   do_test btree-8.12 {
   679    680     set ::keyprefix "This is a long prefix to a key "
   680    681     while {[string length $::keyprefix]<256} {append ::keyprefix $::keyprefix}
   681    682     btree_close_cursor $::c1
   682         -  btree_drop_table $::b1 2
          683  +  btree_clear_table $::b1 2
   683    684     lindex [btree_get_meta $::b1] 0
   684    685   } {4}
   685    686   do_test btree-8.12.1 {
   686    687     set ::c1 [btree_cursor $::b1 2 1]
   687    688     btree_insert $::c1 ${::keyprefix}1 1
          689  +  btree_first $::c1
   688    690     btree_data $::c1
   689    691   } {1}
   690    692   do_test btree-8.13 {
   691    693     btree_key $::c1
   692    694   } ${keyprefix}1
   693    695   do_test btree-8.14 {
   694    696     btree_insert $::c1 ${::keyprefix}2 2
   695    697     btree_insert $::c1 ${::keyprefix}3 3
          698  +  btree_last $::c1
   696    699     btree_key $::c1
   697    700   } ${keyprefix}3
   698    701   do_test btree-8.15 {
   699    702     btree_move_to $::c1 ${::keyprefix}2
   700    703     btree_data $::c1
   701    704   } {2}
   702    705   do_test btree-8.16 {
................................................................................
   728    731     lindex [btree_pager_stats $::b1] 1
   729    732   } {2}
   730    733   do_test btree-8.23 {
   731    734     btree_close_cursor $::c1
   732    735     btree_drop_table $::b1 2
   733    736     set ::c1 [btree_cursor $::b1 2 1]
   734    737     lindex [btree_get_meta $::b1] 0
   735         -} {4}
          738  +} {5}
   736    739   do_test btree-8.24 {
   737    740     lindex [btree_pager_stats $::b1] 1
   738    741   } {2}
   739    742   #btree_pager_ref_dump $::b1
   740    743   
   741    744   # Check page splitting logic
   742    745   #
................................................................................
   774    777     do_test btree-9.3.$i.2 [subst {
   775    778       btree_move_to $::c1 [format %03d $i]
   776    779       string range \[btree_data $::c1\] 0 10
   777    780     }] "*** [format %03d $i] ***"
   778    781   }
   779    782   do_test btree-9.4.1 {
   780    783     lindex [btree_pager_stats $::b1] 1
   781         -} {3}
          784  +} {2}
   782    785   
   783    786   # Check the page joining logic.
   784    787   #
   785    788   #btree_page_dump $::b1 2
   786    789   #btree_pager_ref_dump $::b1
   787    790   do_test btree-9.4.2 {
   788    791     btree_move_to $::c1 005
................................................................................
   812    815   
   813    816   # Create a tree of depth two.  That is, there is a single divider entry
   814    817   # on the root pages and two leaf pages.  Then delete the divider entry
   815    818   # see what happens.
   816    819   #
   817    820   do_test btree-10.1 {
   818    821     btree_begin_transaction $::b1
   819         -  btree_drop_table $::b1 2
          822  +  btree_clear_table $::b1 2
   820    823     lindex [btree_pager_stats $::b1] 1
   821    824   } {1}
   822    825   do_test btree-10.2 {
   823    826     set ::c1 [btree_cursor $::b1 2 1]
   824    827     lindex [btree_pager_stats $::b1] 1
   825    828   } {2}
   826    829   do_test btree-10.3 {