Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch failed-dropCell-opt Excluding Merge-Ins
This is equivalent to a diff from 684ef4582e to 478627c9e9
2016-12-10
| ||
04:06 | Avoid signed integer overflow when dealing with a LIMIT and OFFSET whose sum exceeds the maximum integer value. (check-in: c9bdf7adb4 user: drh tags: trunk) | |
00:14 | In balance_nonroot, try to combine dropCell/insertCell combinations for the dividers into a cell overwrites. This results in a very small (0.05%) performance gain which is probably not worth the added complexity. (Closed-Leaf check-in: 478627c9e9 user: drh tags: failed-dropCell-opt) | |
2016-12-09
| ||
19:42 | When doing the sqlite3BtreeInsert() overwrite optimization, make sure the memcpy() does not extend off the end of the page. (check-in: 684ef4582e user: drh tags: trunk) | |
18:09 | Additional comments and an assert on the sqlite3BtreeInsert() overwrite optimization. (check-in: c1f0ae9d29 user: drh tags: trunk) | |
Changes to src/btree.c.
︙ | ︙ | |||
7013 7014 7015 7016 7017 7018 7019 | int szNew[NB+2]; /* Combined size of cells placed on i-th page */ u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ | | > > > > > > | 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 | int szNew[NB+2]; /* Combined size of cells placed on i-th page */ u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ u8 abDone[NB+2]; /* True after i'th new page is populated */ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ CellArray b; /* Parsed information on cells being balanced */ struct DeferredDropCell { /* Deferred calls to dropCell() for pParent */ u16 idx; /* The index of the cell to drop */ u16 sz; /* The size of the cell to drop */ } sDDC0, sDDC1; /* Up to 2 deferred calls */ memset(abDone, 0, sizeof(abDone)); b.nCell = 0; b.apCell = 0; pBt = pParent->pBt; sDDC0.sz = sDDC0.idx = 0; sDDC1.sz = sDDC1.idx = 0; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); #if 0 TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); #endif |
︙ | ︙ | |||
7114 7115 7116 7117 7118 7119 7120 | memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; }else{ memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; } } | > > > > > | | 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 | memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; }else{ memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; } } assert( sDDC1.sz==0 ); sDDC1 = sDDC0; sDDC0.idx = i+nxDiv-pParent->nOverflow; sDDC0.sz = szNew[i]; //printf("dropCell:\n"); // dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); } } /* Make nMaxCells a multiple of 4 in order to preserve 8-byte ** alignment */ nMaxCells = (nMaxCells + 3)&~3; |
︙ | ︙ | |||
7582 7583 7584 7585 7586 7587 7588 | assert(leafCorrection==4); sz = pParent->xCellSize(pParent, pCell); } } iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); | > > > > > > > > > > > > > > > > > > > > > | > > > | 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 | assert(leafCorrection==4); sz = pParent->xCellSize(pParent, pCell); } } iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); if( sDDC0.idx==nxDiv+i && sDDC0.sz==sz ){ /* overwrite */ unsigned char *oldCell = findCell(pParent, sDDC0.idx); //printf("overwrite: pg=%d idx=%d sz=%d\n", pParent->pgno, sDDC0.idx, sDDC0.sz); memcpy(oldCell+4, pCell+4, sz-4); put4byte(oldCell, pNew->pgno); sDDC0 = sDDC1; sDDC1.sz = 0; }else{ if( sDDC0.sz>0 ){ if( sDDC1.sz>0 ){ //printf("dropCell: pg=%d idx=%d sz=%d\n", pParent->pgno, sDDC1.idx, sDDC1.sz); dropCell(pParent, sDDC1.idx, sDDC1.sz, &rc); sDDC1.sz = 0; } //printf("dropCell: pg=%d idx=%d sz=%d\n", pParent->pgno, sDDC0.idx, sDDC0.sz); dropCell(pParent, sDDC0.idx, sDDC0.sz, &rc); sDDC0.sz = 0; if( rc ) goto balance_cleanup; } //printf("insertCell: pg=%d idx=%d sz=%d\n", pParent->pgno, nxDiv+i, sz); insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); } if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } if( sDDC1.sz ) dropCell(pParent, sDDC1.idx, sDDC1.sz, &rc); if( sDDC0.sz ) dropCell(pParent, sDDC0.idx, sDDC0.sz, &rc); /* Now update the actual sibling pages. The order in which they are updated ** is important, as this code needs to avoid disrupting any page from which ** cells may still to be read. In practice, this means: ** ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1]) ** then it is not safe to update page apNew[iPg] until after |
︙ | ︙ |