/ Check-in [bb4313a9]
Login

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

Overview
Comment:RowIDs are now always expressed in native byte order. (CVS 263)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bb4313a94bc079d072078f353e54f3804971060d
User & Date: drh 2001-09-23 20:17:55
Context
2001-09-24
03:12
Tests for inserting lots of data (~64K) into a single row of a table. (CVS 264) check-in: a462c850 user: drh tags: trunk
2001-09-23
20:17
RowIDs are now always expressed in native byte order. (CVS 263) check-in: bb4313a9 user: drh tags: trunk
19:46
Additional test cases with locking fixes. Also, make the code thread-safe. (CVS 262) check-in: bd7d6a64 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.40 2001/09/22 18:12:10 drh Exp $
           17  +** $Id: main.c,v 1.41 2001/09/23 20:17:55 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   
    22     22   /*
    23     23   ** This is the callback routine for the code that initializes the
    24     24   ** database.  Each callback contains the following information:
................................................................................
   247    247   
   248    248     /* Allocate the sqlite data structure */
   249    249     db = sqliteMalloc( sizeof(sqlite) );
   250    250     if( pzErrMsg ) *pzErrMsg = 0;
   251    251     if( db==0 ) goto no_mem_on_open;
   252    252     sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0);
   253    253     sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
          254  +  db->nextRowid = sqliteRandomInteger(db);
   254    255     
   255    256     /* Open the backend database driver */
   256    257     rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
   257    258     if( rc!=SQLITE_OK ){
   258    259       switch( rc ){
   259    260         default: {
   260    261           if( pzErrMsg ){

Changes to src/vdbe.c.

    26     26   ** type to the other occurs as necessary.
    27     27   ** 
    28     28   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    29     29   ** function which does the work of interpreting a VDBE program.
    30     30   ** But other routines are also provided to help in building up
    31     31   ** a program instruction by instruction.
    32     32   **
    33         -** $Id: vdbe.c,v 1.75 2001/09/23 19:46:52 drh Exp $
           33  +** $Id: vdbe.c,v 1.76 2001/09/23 20:17:55 drh Exp $
    34     34   */
    35     35   #include "sqliteInt.h"
    36     36   #include <ctype.h>
    37     37   #include <unistd.h>
    38     38   
    39     39   /*
    40     40   ** SQL is translated into a sequence of instructions to be
................................................................................
   900    900     if( pLeft ){
   901    901       pTail->pNext = pLeft;
   902    902     }else if( pRight ){
   903    903       pTail->pNext = pRight;
   904    904     }
   905    905     return sHead.pNext;
   906    906   }
          907  +
          908  +/*
          909  +** Convert an integer into a big-endian integer.  In other words,
          910  +** make sure the most significant byte comes first.
          911  +*/
          912  +static int bigEndian(int x){
          913  +  union {
          914  +     char zBuf[sizeof(int)];
          915  +     int i;
          916  +  } ux;
          917  +  ux.zBuf[3] = x&0xff;
          918  +  ux.zBuf[2] = (x>>8)&0xff;
          919  +  ux.zBuf[1] = (x>>16)&0xff;
          920  +  ux.zBuf[0] = (x>>24)&0xff;
          921  +  return ux.i;
          922  +}
   907    923   
   908    924   /*
   909    925   ** Code contained within the VERIFY() macro is not needed for correct
   910    926   ** execution.  It is there only to catch errors.  So when we compile
   911    927   ** with NDEBUG=1, the VERIFY() code is omitted.
   912    928   */
   913    929   #ifdef NDEBUG
................................................................................
  1830   1846   ** See also:  MakeKey, SortMakeKey
  1831   1847   */
  1832   1848   case OP_MakeIdxKey: {
  1833   1849     char *zNewKey;
  1834   1850     int nByte;
  1835   1851     int nField;
  1836   1852     int i, j;
         1853  +  u32 iKey;
  1837   1854   
  1838   1855     nField = pOp->p1;
  1839   1856     VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
  1840   1857     nByte = sizeof(u32);
  1841   1858     for(i=p->tos-nField+1; i<=p->tos; i++){
  1842   1859       if( aStack[i].flags & STK_Null ){
  1843   1860         nByte++;
................................................................................
  1858   1875         zNewKey[j++] = 0;
  1859   1876       }else{
  1860   1877         memcpy(&zNewKey[j], zStack[i], aStack[i].n);
  1861   1878         j += aStack[i].n;
  1862   1879       }
  1863   1880     }
  1864   1881     Integerify(p, p->tos-nField);
  1865         -  memcpy(&zNewKey[j], &aStack[p->tos-nField].i, sizeof(u32));
         1882  +  iKey = bigEndian(aStack[p->tos-nField].i);
         1883  +  memcpy(&zNewKey[j], &iKey, sizeof(u32));
  1866   1884     PopStack(p, nField+1);
  1867   1885     VERIFY( NeedStack(p, p->tos+1); )
  1868   1886     p->tos++;
  1869   1887     aStack[p->tos].n = nByte;
  1870   1888     aStack[p->tos].flags = STK_Str|STK_Dyn;
  1871   1889     zStack[p->tos] = zNewKey;
  1872   1890     break;
................................................................................
  2152   2170   case OP_MoveTo: {
  2153   2171     int i = pOp->p1;
  2154   2172     int tos = p->tos;
  2155   2173     VERIFY( if( tos<0 ) goto not_enough_stack; )
  2156   2174     if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
  2157   2175       int res;
  2158   2176       if( aStack[tos].flags & STK_Int ){
         2177  +      int iKey = bigEndian(aStack[tos].i);
  2159   2178         sqliteBtreeMoveto(p->aCsr[i].pCursor, 
  2160         -          (char*)&aStack[tos].i, sizeof(int), &res);
         2179  +          (char*)&iKey, sizeof(int), &res);
  2161   2180         p->aCsr[i].lastRecno = aStack[tos].i;
  2162   2181         p->aCsr[i].recnoIsValid = 1;
  2163   2182       }else{
  2164   2183         if( Stringify(p, tos) ) goto no_mem;
  2165   2184         sqliteBtreeMoveto(p->aCsr[i].pCursor, zStack[tos], aStack[tos].n, &res);
  2166   2185         p->aCsr[i].recnoIsValid = 0;
  2167   2186       }
................................................................................
  2227   2246     int i = pOp->p1;
  2228   2247     int tos = p->tos;
  2229   2248     int alreadyExists = 0;
  2230   2249     VERIFY( if( tos<0 ) goto not_enough_stack; )
  2231   2250     if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor ){
  2232   2251       int res, rx;
  2233   2252       if( aStack[tos].flags & STK_Int ){
         2253  +      int iKey = bigEndian(aStack[tos].i);
  2234   2254         rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, 
  2235         -           (char*)&aStack[tos].i, sizeof(int), &res);
         2255  +           (char*)&iKey, sizeof(int), &res);
  2236   2256       }else{
  2237   2257         if( Stringify(p, tos) ) goto no_mem;
  2238   2258         rx = sqliteBtreeMoveto(p->aCsr[i].pCursor,
  2239   2259            zStack[tos], aStack[tos].n, &res);
  2240   2260       }
  2241   2261       alreadyExists = rx==SQLITE_OK && res==0;
  2242   2262     }
................................................................................
  2276   2296       ** hardware failure than for this algorithm to fail.
  2277   2297       **
  2278   2298       ** To promote locality of reference for repetitive inserts, the
  2279   2299       ** first few attempts at chosing a rowid pick values just a little
  2280   2300       ** larger than the previous rowid.  This has been shown experimentally
  2281   2301       ** to double the speed of the COPY operation.
  2282   2302       */
  2283         -    int res, rx, cnt;
  2284         -    int x;
         2303  +    int res, rx, cnt, x;
  2285   2304       union {
  2286   2305          char zBuf[sizeof(int)];
  2287   2306          int i;
  2288   2307       } ux;
  2289   2308       cnt = 0;
  2290         -    x = db->nextRowid;
         2309  +    v = db->nextRowid;
  2291   2310       do{
  2292   2311         if( cnt>5 ){
  2293         -        x = sqliteRandomInteger(db);
         2312  +        v = sqliteRandomInteger(db);
  2294   2313         }else{
  2295         -        x += sqliteRandomByte(db) + 1;
         2314  +        v += sqliteRandomByte(db) + 1;
  2296   2315         }
  2297         -      if( x==0 ) continue;
  2298         -      ux.zBuf[3] = x&0xff;
  2299         -      ux.zBuf[2] = (x>>8)&0xff;
  2300         -      ux.zBuf[1] = (x>>16)&0xff;
  2301         -      ux.zBuf[0] = (x>>24)&0xff;
  2302         -      v = ux.i;
  2303         -      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &v, sizeof(v), &res);
         2316  +      if( v==0 ) continue;
         2317  +      x = bigEndian(v);
         2318  +      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &x, sizeof(int), &res);
  2304   2319         cnt++;
  2305   2320       }while( cnt<1000 && rx==SQLITE_OK && res==0 );
  2306         -    db->nextRowid = x;
         2321  +    db->nextRowid = v;
  2307   2322       if( rx==SQLITE_OK && res==0 ){
  2308   2323         rc = SQLITE_FULL;
  2309   2324         goto abort_due_to_error;
  2310   2325       }
  2311   2326     }
  2312   2327     VERIFY( NeedStack(p, p->tos+1); )
  2313   2328     p->tos++;
................................................................................
  2327   2342   case OP_Put: {
  2328   2343     int tos = p->tos;
  2329   2344     int nos = p->tos-1;
  2330   2345     int i = pOp->p1;
  2331   2346     VERIFY( if( nos<0 ) goto not_enough_stack; )
  2332   2347     if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
  2333   2348       char *zKey;
  2334         -    int nKey;
         2349  +    int nKey, iKey;
  2335   2350       if( (aStack[nos].flags & STK_Int)==0 ){
  2336   2351         if( Stringify(p, nos) ) goto no_mem;
  2337   2352         nKey = aStack[nos].n;
  2338   2353         zKey = zStack[nos];
  2339   2354       }else{
  2340   2355         nKey = sizeof(int);
  2341         -      zKey = (char*)&aStack[nos].i;
         2356  +      iKey = bigEndian(aStack[nos].i);
         2357  +      zKey = (char*)&iKey;
  2342   2358       }
  2343   2359       rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey,
  2344   2360                           zStack[tos], aStack[tos].n);
  2345   2361     }
  2346   2362     POPSTACK;
  2347   2363     POPSTACK;
  2348   2364     break;
................................................................................
  2492   2508     VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  2493   2509     if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2494   2510       int v;
  2495   2511       if( p->aCsr[i].recnoIsValid ){
  2496   2512         v = p->aCsr[i].lastRecno;
  2497   2513       }else{
  2498   2514         sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v);
         2515  +      v = bigEndian(v);
  2499   2516       }
  2500   2517       aStack[tos].i = v;
  2501   2518       aStack[tos].flags = STK_Int;
  2502   2519     }
  2503   2520     break;
  2504   2521   }
  2505   2522   
................................................................................
  2653   2670         memcmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
  2654   2671       ){
  2655   2672         pc = pOp->p2 - 1;
  2656   2673         POPSTACK;
  2657   2674       }else{
  2658   2675         int recno;
  2659   2676         sqliteBtreeKey(pCur, pCrsr->nKey, sizeof(u32), (char*)&recno);
         2677  +      recno = bigEndian(recno);
  2660   2678         p->aCsr[i].lastRecno = aStack[tos].i = recno;
  2661   2679         p->aCsr[i].recnoIsValid = 1;
  2662   2680         aStack[tos].flags = STK_Int;
  2663   2681       }
  2664   2682     }
  2665   2683     break;
  2666   2684   }