Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the way checksums are calculated. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | wal |
Files: | files | file ages | folders |
SHA1: |
84955c2e9ce526c5a3ed479aa09f093a |
User & Date: | dan 2010-04-15 10:58:52 |
Context
2010-04-15
| ||
13:33 | Merge two leaves on the WAL branch. check-in: c9ed66cc user: dan tags: wal | |
10:58 | Change the way checksums are calculated. check-in: 84955c2e user: dan tags: wal | |
02:37 | Bring over the recent query planner enhancements from the trunk. check-in: 82969f27 user: drh tags: wal | |
Changes
Changes to src/log.c.
137 137 /* 138 138 ** Generate an 8 byte checksum based on the data in array aByte[] and the 139 139 ** initial values of aCksum[0] and aCksum[1]. The checksum is written into 140 140 ** aCksum[] before returning. 141 141 */ 142 142 #define LOG_CKSM_BYTES 8 143 143 static void logChecksumBytes(u8 *aByte, int nByte, u32 *aCksum){ 144 - u32 *z32 = (u32 *)aByte; 145 - int n32 = nByte / sizeof(u32); 146 - int i; 144 + u64 sum1 = aCksum[0]; 145 + u64 sum2 = aCksum[1]; 146 + u32 *a32 = (u32 *)aByte; 147 + u32 *aEnd = (u32 *)&aByte[nByte]; 147 148 148 149 assert( LOG_CKSM_BYTES==2*sizeof(u32) ); 149 150 assert( (nByte&0x00000003)==0 ); 150 151 151 - u32 cksum0 = aCksum[0]; 152 - u32 cksum1 = aCksum[1]; 152 + do { 153 + sum1 += (*a32++); 154 + sum2 += sum1; 155 + } while( a32<aEnd ); 153 156 154 - for(i=0; i<n32; i++){ 155 - cksum0 = (cksum0 >> 8) + (cksum0 ^ z32[i]); 156 - cksum1 = (cksum1 >> 8) + (cksum1 ^ z32[i]); 157 - } 158 - 159 - aCksum[0] = cksum0; 160 - aCksum[1] = cksum1; 157 + aCksum[0] = sum1 + (sum1>>24); 158 + aCksum[1] = sum2 + (sum2>>24); 161 159 } 162 160 163 161 /* 164 162 ** Argument zPath must be a nul-terminated string containing a path-name. 165 163 ** This function modifies the string in-place by removing any "./" or "../" 166 164 ** elements in the path. For example, the following input: 167 165 ** ................................................................................ 1255 1253 if( pLog->isLocked ){ 1256 1254 assert( pLog->isLocked==LOG_REGION_A || pLog->isLocked==LOG_REGION_D ); 1257 1255 logLockRegion(pLog, pLog->isLocked, LOG_UNLOCK); 1258 1256 } 1259 1257 pLog->isLocked = 0; 1260 1258 } 1261 1259 1262 - 1263 - 1264 1260 /* 1265 1261 ** Read a page from the log, if it is present. 1266 1262 */ 1267 1263 int sqlite3LogRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut){ 1268 1264 u32 iRead = 0; 1269 1265 u32 *aData = pLog->pSummary->aData; 1270 1266 int iFrame = (pLog->hdr.iLastPg & 0xFFFFFF00); 1267 + 1268 + assert( pLog->isLocked ); 1271 1269 1272 1270 /* Do a linear search of the unindexed block of page-numbers (if any) 1273 1271 ** at the end of the log-summary. An alternative to this would be to 1274 1272 ** build an index in private memory each time a read transaction is 1275 1273 ** opened on a new snapshot. 1276 1274 */ 1277 1275 if( pLog->hdr.iLastPg ){ ................................................................................ 1345 1343 1346 1344 /* Obtain the writer lock */ 1347 1345 int rc = logLockRegion(pLog, LOG_REGION_C|LOG_REGION_D, LOG_WRLOCK); 1348 1346 if( rc!=SQLITE_OK ){ 1349 1347 return rc; 1350 1348 } 1351 1349 1352 - /* If this is connection is a region D, then the SHARED lock on region 1353 - ** D has just been upgraded to EXCLUSIVE. But no lock at all is held on 1354 - ** region A. This means that if the write-transaction is committed 1350 + /* If this is connection is a region D reader, then the SHARED lock on 1351 + ** region D has just been upgraded to EXCLUSIVE. But no lock at all is 1352 + ** held on region A. This means that if the write-transaction is committed 1355 1353 ** and this connection downgrades to a reader, it will be left with no 1356 - ** lock at all. And its snapshot could get clobbered by a checkpoint 1354 + ** lock at all. And so its snapshot could get clobbered by a checkpoint 1357 1355 ** operation. 1358 1356 ** 1359 1357 ** To stop this from happening, grab a SHARED lock on region A now. 1360 1358 ** This should always be successful, as the only time a client holds 1361 1359 ** an EXCLUSIVE lock on region A, it must also be holding an EXCLUSIVE 1362 1360 ** lock on region C (a checkpointer does this). This is not possible, 1363 1361 ** as this connection currently has the EXCLUSIVE lock on region C. 1364 1362 */ 1365 1363 if( pLog->isLocked==LOG_REGION_D ){ 1366 1364 logLockRegion(pLog, LOG_REGION_A, LOG_RDLOCK); 1367 1365 pLog->isLocked = LOG_REGION_A; 1368 1366 } 1369 1367 1368 + /* If this connection is not reading the most recent database snapshot, 1369 + ** it is not possible to write to the database. In this case release 1370 + ** the write locks and return SQLITE_BUSY. 1371 + */ 1370 1372 if( memcmp(&pLog->hdr, pLog->pSummary->aData, sizeof(pLog->hdr)) ){ 1371 1373 logLockRegion(pLog, LOG_REGION_C|LOG_REGION_D, LOG_UNLOCK); 1372 1374 return SQLITE_BUSY; 1373 1375 } 1374 1376 pLog->isWriteLocked = 1; 1375 1377 1376 1378 }else if( pLog->isWriteLocked ){ ................................................................................ 1531 1533 sqlite3_file *pFd, /* File descriptor open on db file */ 1532 1534 u8 *zBuf, /* Temporary buffer to use */ 1533 1535 int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ 1534 1536 void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ 1535 1537 ){ 1536 1538 int rc; /* Return code */ 1537 1539 1538 - /* Wait for a write-lock on regions B and C. */ 1540 + assert( !pLog->isLocked ); 1541 + 1542 + /* Wait for an EXCLUSIVE lock on regions B and C. */ 1539 1543 do { 1540 1544 rc = logLockRegion(pLog, LOG_REGION_B|LOG_REGION_C, LOG_WRLOCK); 1541 1545 }while( rc==SQLITE_BUSY && xBusyHandler(pBusyHandlerArg) ); 1542 1546 if( rc!=SQLITE_OK ) return rc; 1543 1547 1544 - /* Wait for a write-lock on region A. */ 1548 + /* Wait for an EXCLUSIVE lock on region A. */ 1545 1549 do { 1546 1550 rc = logLockRegion(pLog, LOG_REGION_A, LOG_WRLOCK); 1547 1551 }while( rc==SQLITE_BUSY && xBusyHandler(pBusyHandlerArg) ); 1548 1552 if( rc!=SQLITE_OK ){ 1549 1553 logLockRegion(pLog, LOG_REGION_B|LOG_REGION_C, LOG_UNLOCK); 1550 1554 return rc; 1551 1555 }