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