Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Refactor the interface to the randomness generator. (CVS 1224) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f2bdccf4bb2f796aafb64c33e55f62a1 |
User & Date: | drh 2004-02-11 09:46:31.000 |
Context
2004-02-11
| ||
10:35 | Fix an uninitialized variable in expr.c. Ticket #604. (CVS 1225) (check-in: 1673bf7c7b user: drh tags: trunk) | |
09:46 | Refactor the interface to the randomness generator. (CVS 1224) (check-in: f2bdccf4bb user: drh tags: trunk) | |
02:18 | Pass all (relevant) regression tests when using the codec. (CVS 1223) (check-in: 5200e9edc5 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.165 2004/02/11 09:46:31 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
815 816 817 818 819 820 821 | ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ void sqliteChangeCookie(sqlite *db, Vdbe *v){ if( db->next_cookie==db->aDb[0].schema_cookie ){ | > > | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ void sqliteChangeCookie(sqlite *db, Vdbe *v){ if( db->next_cookie==db->aDb[0].schema_cookie ){ unsigned char r; sqliteRandomness(1, &r); db->next_cookie = db->aDb[0].schema_cookie + r + 1; db->flags |= SQLITE_InternChanges; sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0); sqliteVdbeAddOp(v, OP_SetCookie, 0, 0); } } /* |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.39 2004/02/11 09:46:32 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "os.h" |
︙ | ︙ | |||
191 192 193 194 195 196 197 | } } /* ** Implementation of random(). Return a random integer. */ static void randomFunc(sqlite_func *context, int argc, const char **argv){ | > > | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | } } /* ** Implementation of random(). Return a random integer. */ static void randomFunc(sqlite_func *context, int argc, const char **argv){ int r; sqliteRandomness(sizeof(r), &r); sqlite_set_result_int(context, r); } /* ** Implementation of the last_insert_rowid() SQL function. The return ** value is the same as the sqlite_last_insert_rowid() API function. */ static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){ |
︙ | ︙ | |||
337 338 339 340 341 342 343 | #ifdef SQLITE_TEST /* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr(sqlite_func *context, int argc, const char **argv){ | | | > | | < | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | #ifdef SQLITE_TEST /* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr(sqlite_func *context, int argc, const char **argv){ static const unsigned char zSrc[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" ".-!,:*^+=_|?/<> "; int iMin, iMax, n, r, i; unsigned char zBuf[1000]; if( argc>=1 ){ iMin = atoi(argv[0]); if( iMin<0 ) iMin = 0; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; }else{ iMin = 1; } if( argc>=2 ){ iMax = atoi(argv[1]); if( iMax<iMin ) iMax = iMin; if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; }else{ iMax = 50; } n = iMin; if( iMax>iMin ){ sqliteRandomness(sizeof(r), &r); r &= 0x7fffffff; n += r%(iMax + 1 - iMin); } assert( n<sizeof(zBuf) ); sqliteRandomness(n, zBuf); for(i=0; i<n; i++){ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)]; } zBuf[n] = 0; sqlite_set_result_string(context, zBuf, n); } #endif /* |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
781 782 783 784 785 786 787 | #if OS_UNIX static const char *azDirs[] = { "/var/tmp", "/usr/tmp", "/tmp", ".", }; | | > | | < > | | < | 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 | #if OS_UNIX static const char *azDirs[] = { "/var/tmp", "/usr/tmp", "/tmp", ".", }; static unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; struct stat buf; const char *zDir = "."; for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ if( stat(azDirs[i], &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; if( access(azDirs[i], 07) ) continue; zDir = azDirs[i]; break; } do{ sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; }while( access(zBuf,0)==0 ); #endif #if OS_WIN static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; char zTempPath[SQLITE_TEMPNAME_SIZE]; GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath); for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; for(;;){ sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqliteOsFileExists(zBuf) ) break; } #endif #if OS_MAC static char zChars[] = |
︙ | ︙ | |||
861 862 863 864 865 866 867 | } while( infoRec.dirInfo.ioDrDirID != fsRtDirID ); } if( *zTempPath == 0 ) getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24); for(;;){ sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); | > | | < | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | } while( infoRec.dirInfo.ioDrDirID != fsRtDirID ); } if( *zTempPath == 0 ) getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24); for(;;){ sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqliteOsFileExists(zBuf) ) break; } #endif return SQLITE_OK; } |
︙ | ︙ | |||
1321 1322 1323 1324 1325 1326 1327 | return rc; #endif #if OS_WIN int rc; if( id->locked>0 ){ rc = SQLITE_OK; }else{ | | > > | 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | return rc; #endif #if OS_WIN int rc; if( id->locked>0 ){ rc = SQLITE_OK; }else{ int lk; int res; int cnt = 100; sqliteRandomness(sizeof(lk), &lk); lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1; while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){ Sleep(1); } if( res ){ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); if( isNT() ){ OVERLAPPED ovlp; |
︙ | ︙ | |||
1355 1356 1357 1358 1359 1360 1361 | return rc; #endif #if OS_MAC int rc; if( id->locked>0 || id->refNumRF == -1 ){ rc = SQLITE_OK; }else{ | | > > | 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | return rc; #endif #if OS_MAC int rc; if( id->locked>0 || id->refNumRF == -1 ){ rc = SQLITE_OK; }else{ int lk; OSErr res; int cnt = 5; ParamBlockRec params; sqliteRandomness(sizeof(lk), &lk); lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1; memset(¶ms, 0, sizeof(params)); params.ioParam.ioRefNum = id->refNumRF; params.ioParam.ioPosMode = fsFromStart; params.ioParam.ioPosOffset = FIRST_LOCKBYTE; params.ioParam.ioReqCount = 1; while( cnt-->0 && (res = PBLockRangeSync(¶ms))!=noErr ){ UInt32 finalTicks; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.100 2004/02/11 09:46:32 drh Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 | pPager->origDbSize = pPager->dbSize; if( journal_format==JOURNAL_FORMAT_3 ){ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3)); if( rc==SQLITE_OK ){ rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0); } if( rc==SQLITE_OK ){ | | | 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 | pPager->origDbSize = pPager->dbSize; if( journal_format==JOURNAL_FORMAT_3 ){ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3)); if( rc==SQLITE_OK ){ rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0); } if( rc==SQLITE_OK ){ sqliteRandomness(sizeof(pPager->cksumInit), &pPager->cksumInit); rc = write32bits(&pPager->jfd, pPager->cksumInit); } }else if( journal_format==JOURNAL_FORMAT_2 ){ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2)); }else{ assert( journal_format==JOURNAL_FORMAT_1 ); rc = sqliteOsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1)); |
︙ | ︙ |
Changes to src/random.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** | | | | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** ** $Id: random.c,v 1.11 2004/02/11 09:46:33 drh Exp $ */ #include "sqliteInt.h" #include "os.h" /* ** Get a single 8-bit random value from the RC4 PRNG. The Mutex ** must be held while executing this routine. ** ** Why not just use a library random generator like lrand48() for this? ** Because the OP_NewRecno opcode in the VDBE depends on having a very ** good source of random numbers. The lrand48() library function may ** well be good enough. But maybe not. Or maybe lrand48() has some ** subtle problems on some systems that could cause problems. It is hard ** to know. To minimize the risk of problems due to bad lrand48() ** implementations, SQLite uses this random number generator based ** on RC4, which we know works very well. */ static int randomByte(){ unsigned char t; /* All threads share a single random number generator. ** This structure is the current state of the generator. */ static struct { unsigned char isInit; /* True if initialized */ unsigned char i, j; /* State variables */ unsigned char s[256]; /* State variables */ } prng; /* Initialize the state of the random number generator once, ** the first time this routine is called. The seed value does ** not need to contain a lot of randomness since we are not ** trying to do secure encryption or anything like that... ** |
︙ | ︙ | |||
61 62 63 64 65 66 67 | prng.j = 0; prng.i = 0; sqliteOsRandomSeed(k); for(i=0; i<256; i++){ prng.s[i] = i; } for(i=0; i<256; i++){ | < | | < > | | | | | < < < < | < < < < < < < < | < < < | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | prng.j = 0; prng.i = 0; sqliteOsRandomSeed(k); for(i=0; i<256; i++){ prng.s[i] = i; } for(i=0; i<256; i++){ prng.j += prng.s[i] + k[i]; t = prng.s[prng.j]; prng.s[prng.j] = prng.s[i]; prng.s[i] = t; } prng.isInit = 1; } /* Generate and return single random byte */ prng.i++; t = prng.s[prng.i]; prng.j += t; prng.s[prng.i] = prng.s[prng.j]; prng.s[prng.j] = t; t += prng.s[prng.i]; return prng.s[t]; } /* ** Return N random bytes. */ void sqliteRandomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; sqliteOsEnterMutex(); while( N-- ){ *(zBuf++) = randomByte(); } sqliteOsLeaveMutex(); } |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.210 2004/02/11 09:46:33 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
1147 1148 1149 1150 1151 1152 1153 | int sqliteExprCheck(Parse*, Expr*, int, int*); int sqliteExprType(Expr*); int sqliteExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*); int sqliteExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqliteGetVdbe(Parse*); | | < | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 | int sqliteExprCheck(Parse*, Expr*, int, int*); int sqliteExprType(Expr*); int sqliteExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*); int sqliteExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqliteGetVdbe(Parse*); void sqliteRandomness(int, void*); void sqliteRollbackAll(sqlite*); void sqliteCodeVerifySchema(Parse*, int); void sqliteBeginTransaction(Parse*, int); void sqliteCommitTransaction(Parse*); void sqliteRollbackTransaction(Parse*); int sqliteExprIsConstant(Expr*); int sqliteExprIsInteger(Expr*, int*); |
︙ | ︙ |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.10 2004/02/11 09:46:33 drh Exp $ */ #include "sqliteInt.h" #include "os.h" /* ** A structure for holding a dynamic string - a string that can grow ** without bound. |
︙ | ︙ | |||
181 182 183 184 185 186 187 | rc = execsql(p->pzErrMsg, p->dbNew, zBuf); return rc; } /* ** Generate a random name of 20 character in length. */ | | | > < | | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | rc = execsql(p->pzErrMsg, p->dbNew, zBuf); return rc; } /* ** Generate a random name of 20 character in length. */ static void randomName(unsigned char *zBuf){ static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "0123456789"; int i; sqliteRandomness(20, zBuf); for(i=0; i<20; i++){ zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ]; } } #endif /* ** The non-standard VACUUM command is used to clean up the database, ** collapse free space, etc. It is modelled after the VACUUM command |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.259 2004/02/11 09:46:33 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2889 2890 2891 2892 2893 2894 2895 | } } if( pC->useRandomRowid ){ v = db->priorNewRowid; cnt = 0; do{ if( v==0 || cnt>2 ){ | | > | > | 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 | } } if( pC->useRandomRowid ){ v = db->priorNewRowid; cnt = 0; do{ if( v==0 || cnt>2 ){ sqliteRandomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; }else{ unsigned char r; sqliteRandomness(1, &r); v += r + 1; } if( v==0 ) continue; x = intToKey(v); rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res); cnt++; }while( cnt<1000 && rx==SQLITE_OK && res==0 ); db->priorNewRowid = v; |
︙ | ︙ |