Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | :-) (CVS 179) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d5f2a668978c0d108045237f19b0a7ef |
User & Date: | drh 2001-01-21 00:58:08.000 |
Context
2001-01-21
| ||
22:03 | :-) (CVS 1711) (check-in: 0529c979fd user: drh tags: trunk) | |
00:58 | :-) (CVS 179) (check-in: d5f2a66897 user: drh tags: trunk) | |
2001-01-20
| ||
19:52 | :-) (CVS 178) (check-in: 1662063dfb user: drh tags: trunk) | |
Changes
Added src/TODO.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | * Finish fleshing out the db.c file. - sqliteDbReadOvfl - sqliteDbSpreadLoad - sqliteDbSplit - sqliteDbNextIndexLevel - fix sqliteDbCursorNext to work right after sqliteDbCursorDelete * Compile db.c with -Wall and get no errors. * Make a pass over pg.c and db.c looking for errors. - correct handling of I/O errors, malloc failures, etc. - page leaks (not calling sqlitePgUnref) * Write a test interface for db.c. * Compile and link against the db test interface. * Generate tests for the db interface. * Add read/write locks to pg.c * Add an sqliteDbReorganize() function. * Integrate db into vdbe. * Modify code generation to take advantage of the new db interface. - Able to delete without disturbing scan order - Now keeps a count of number of table entries + Special processing for count(*) + Better selection of indices on a select - Transactions * Modify sqlite_master to store the table number. * Add a cache in DbCursor to speed up the sqliteDbReadOvfl() routine. Longer term: * Document all the changes and release Sqlite 2.0. * Techniques for optimizing querys by grouping data with similar indices. * "OPTIMIZE select" statement to automatically create and/or tune indices. * Parse and use constraints. |
Changes to src/db.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** $Id: db.c,v 1.2 2001/01/21 00:58:08 drh Exp $ */ #include "sqliteInt.h" #include "pg.h" /* ** Everything we need to know about an open database */ |
︙ | ︙ | |||
174 175 176 177 178 179 180 | rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage); if( rc==SQLITE_OK ){ pDb->aContent[0] = pFree[1]; *pPgno = pgno; return SQLITE_OK; } } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage); if( rc==SQLITE_OK ){ pDb->aContent[0] = pFree[1]; *pPgno = pgno; return SQLITE_OK; } } if( (rc = sqlitePgCount(pDb->pPgr, &pgno))==SQLITE_OK && (rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage))==SQLITE_OK ){ *pPgno = pgno; return SQLITE_OK; } return rc; } /* ** Return a page to the freelist and dereference the page. */ static void sqliteDbFreePage(DB *pDb, u32 pgno, u32 *aPage){ if( pDb->aContent==0 ) return; aPage[0] = SWB(BLOCK_MAGIC | BLOCK_FREE); aPage[1] = pDb->aContent[0]; memset(&aPage[2], 0, SQLITE_PAGE_SIZE - 2*sizeof(u32)); pDb->aContent[0] = SWB(pgno); sqlitePgTouch(aPage); sqlitePgUnref(aPage); } /* ** Write data into overflow pages. The first overflow page is ** provided in the second argument. If additional pages are ** needed, they must be allocated. */ static int sqliteDbWriteOvfl(Db *pDb, u32 *aPage, int nData, const void *pData){ while( nData>0 ){ int toWrite, rc; u32 *nxPage, nxPgno; if( nData > SQLITE_PAGE_SIZE - 2*sizeof(u32) ){ toWrite = SQLITE_PAGE_SIZE - 2*sizeof(u32); }else{ toWrite = nData; } memcpy(&aPage[2], pData, toWrite); nData -= toWrite; pData = &((char*)pData)[toWrite]; if( nData<=0 ) break; rc = sqliteDbAllocPage(pDb, &nxPgno, &nxPage); if( rc!=SQLITE_OK ) return rc; /* Be smarter here */ aPage[1] = SWB(nxPgno); nxPage[0] = SWB(BLOCK_MAGIC|BLOCK_OVERFLOW); nxPage[1] = 0; sqlitePgTouch(aPage); sqlitePgUnref(aPage); aPage = nxPage; } return SQLITE_OK; } /* ** Open a database. */ int sqliteDbOpen(const char *filename, Db **ppDb){ Db *pDb = 0; Pgr *pPgr = 0; u32 *aPage1; int rc; u32 nPage; rc = sqlitePgOpen(filename, &pPgr); if( rc!=SQLITE_OK ) goto open_err; pDb = sqliteMalloc( sizeof(*pDb) ); if( pDb==0 ){ rc = SQLITE_NOMEM; goto open_err; } pDb->pPgr = pPgr; pDb->pCursor = 0; pDb->inTransaction = 0; sqlitePgCount(pDb->pPgr, &nPage); rc = sqlitePgGet(pDb->pPgr, 1, &aPage1); if( rc!=0 ) goto open_err; if( nPage==0 ){ sqlitePgBeginTransaction(pDb->pPgr); aPage1[0] = SWB(BLOCK_MAGIC|BLOCK_CONTENT); sqlitePgTouch(aPage1); sqlitePgCommit(pDb->pPgr); } pDb->nContent = SWB(aPage1[3]) + 2; pDb->nAlloc = 0; rc = sqliteDbExpandContent(pDb, pDb->nContent); if( rc!=SQLITE_OK ) goto open_err; rc = sqliteDbReadOvfl(pDb, 1, aPage1, 0, pDb->nContent*sizeof(u32), pDb->aContent); if( rc!=SQLITE_OK ) goto open_err; |
︙ | ︙ | |||
271 272 273 274 275 276 277 278 279 280 | return SQLITE_OK; } /* ** Commit changes to the database */ int sqliteDbCommit(Db *pDb){ if( !pDb->inTransaction ){ return SQLITE_OK; } | > > > > | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | return SQLITE_OK; } /* ** Commit changes to the database */ int sqliteDbCommit(Db *pDb){ u32 *aPage; int rc; if( !pDb->inTransaction ){ return SQLITE_OK; } rc = sqlitePgGet(pDb->pPgr, 1, &aPage); if( rc!=SQLITE_OK ) return rc; sqliteDbWriteOvfl(pDb, aPage, pDb->nContent*sizeof(u32), pDb->aContent); rc = sqlitePgCommit(pDb->pPgr); if( rc!=SQLITE_OK ) return rc; pDb->inTransaction = 0; return SQLITE_OK; } /* |
︙ | ︙ | |||
728 729 730 731 732 733 734 | } i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); assert( idx>=2 && idx+4<(SQLITE_PAGE_SIZE/sizeof(u32)) nKey = SWB(aPage[idx+2]); | | | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | } i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); assert( idx>=2 && idx+4<(SQLITE_PAGE_SIZE/sizeof(u32)) nKey = SWB(aPage[idx+2]); if( nKey & 0x80000000 ){ return sqliteDbReadOvfl(pCur->pDb, SWB(aPage[idx+4]), 0, amt, offset, buf); } if( nKey==4 ){ kstart = idx + 1; }else{ kstart = idx + 4; } |
︙ | ︙ | |||
975 976 977 978 979 980 981 | available -= nKeyU; }else{ u32 newPgno, *newPage; aPage[i+2] = SWB(nKey | 0x80000000); rc = sqliteDbAllocPage(pCur->pDb, &newPgno, &newPage); if( rc!=SQLITE_OK ) goto write_err; aPage[i+4] = SWB(newPgno); | > | > | | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 | available -= nKeyU; }else{ u32 newPgno, *newPage; aPage[i+2] = SWB(nKey | 0x80000000); rc = sqliteDbAllocPage(pCur->pDb, &newPgno, &newPage); if( rc!=SQLITE_OK ) goto write_err; aPage[i+4] = SWB(newPgno); newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW); rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nKey, pKey); if( rc!=SQLITE_OK ) goto write_err; j = i + 5; available -= 1; } if( nDataU <= available ){ aPage[i+3] = SWB(nData); memcpy(&aPage[j], pData, nData); available -= nDataU; j += nDataU; }else{ u32 newPgno, *newPage; aPage[i+3] = SWB(nData | 0x80000000); rc = sqliteDbAllocPage(pCur->pDb, &newPgno, &newPage); if( rc!=SQLITE_OK ) goto write_err; aPage[j] = SWB(newPgno); newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW); rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nData, pData); if( rc!=SQLITE_OK ) goto write_err; available -= 1; j++; } if( j<SQLITE_PAGE_SIZE/sizeof(u32) ){ aPage[j] = 0; } |
︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 1024 | write_err: aPage[i] = 0; pCur->onEntry = 0; return rc; } /* | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | write_err: aPage[i] = 0; pCur->onEntry = 0; return rc; } /* ** Delete the entry that the cursor points to. */ int sqliteDbCursorDelete(DbCursor *pCur){ int i, idx; int from, to, limit, n; int entrySize; u32 *aPage; if( !pCur->onEntry ) return SQLITE_NOTFOUND; /* Delete the entry that the cursor is pointing to. */ i = pCur->nLevel - 1; |
︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 | */ if( to>2 || pCur->nLevel==1 ) return SQLITE_OK; /* Collapse the tree into a more compact form. */ sqliteDbResetCursor(pCur, pCur->nLevel-1); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 | */ if( to>2 || pCur->nLevel==1 ) return SQLITE_OK; /* Collapse the tree into a more compact form. */ sqliteDbResetCursor(pCur, pCur->nLevel-1); i = pCur->nLevel-1; assert( i>=0 && i<MAX_LEVEL ); idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX ); assert( idx>=3 && idx<SQLITE_PAGE_SIZE/sizeof(u32) ); n = SWB(aPage[2]); assert( n>=2 && n<=SQLITE_PAGE_SIZE/2*sizeof(u32)-2 ); sqliteDbDropPage(pCur->pDb, SWB(aPage[idx+1]); to = idx; from = idx+2; limit = n*2 + 3; while( from<limit ){ aPage[to++] = aPage[from++]; } n--; if( n==1 ){ u32 oldPgno, *oldPage; oldPgno = SWB(aPage[4]); rc = sqlitePgGet(pCur->pDb->pPgr, oldPgno, &oldPage); if( rc!=SQLITE_OK ){ return rc; /* Do something smarter here */ } memcpy(aPage, oldPage, SQLITE_PAGE_SIZE); oldPage[0] = SWB(BLOCK_MAGIC|BLOCK_OVERFLOW); oldPage[1] = 0; sqliteDbDropPage(pCur->pDb, oldPgno); sqlitePgUnref(oldPage); }else{ aPage[2] = SWB(n); } sqlitePgTouch(aPage); return SQLITE_OK; } |
Changes to src/pg.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* | | < < < < | 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 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** $Id: pg.c,v 1.3 2001/01/21 00:58:08 drh Exp $ */ #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "sqliteInt.h" #include "pg.h" /* ** Uncomment the following for a debug trace */ #if 1 # define TRACE(X) printf X; fflush(stdout); #endif /* ** Hash table sizes */ #define J_HASH_SIZE 127 /* Size of the journal page hash table */ #define PG_HASH_SIZE 349 /* Size of the database page hash table */ /* |
︙ | ︙ |
Changes to src/pg.h.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** $Id: pg.h,v 1.3 2001/01/21 00:58:09 drh Exp $ */ typedef struct Pgr Pgr; #define SQLITE_PAGE_SIZE 1024 int sqlitePgOpen(const char *filename, Pgr **pp); int sqlitePgClose(Pgr*); int sqlitePgBeginTransaction(Pgr*); int sqlitePgCommit(Pgr*); int sqlitePgRollback(Pgr*); int sqlitePgGet(Pgr*, u32 pgno, void **); int sqlitePgUnref(void*); int sqlitePgTouch(void*); int sqlitePgCount(Pgr*, u32*); u32 sqlitePgNum(void*); |