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