Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | :-) (CVS 1713) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3259a53111bd19417e78160174bd67c6 |
User & Date: | drh 2001-01-29 01:27:20.000 |
Context
2001-01-31
| ||
13:28 | Working better with Win95. Continued work on the new db.c backend. (CVS 1714) (check-in: df0ff30485 user: drh tags: trunk) | |
2001-01-29
| ||
01:27 | :-) (CVS 1713) (check-in: 3259a53111 user: drh tags: trunk) | |
2001-01-25
| ||
01:45 | :-) (CVS 1712) (check-in: edb01b1275 user: drh tags: trunk) | |
Changes
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.5 2001/01/29 01:27:20 drh Exp $ */ #include "sqliteInt.h" #include "pg.h" /* ** Everything we need to know about an open database */ |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 | Db *pDb; /* The whole database */ DbCursor *pPrev, *pNext; /* Linked list of all cursors */ u32 rootPgno; /* Root page of table for this cursor */ int onEntry; /* True if pointing to a table entry */ int nLevel; /* Number of levels of indexing used */ DbIdxpt aLevel[MX_LEVEL]; /* The index levels */ }; /* ** The first word of every page is some combination of these values ** used to indicate its function. */ #define BLOCK_MAGIC 0x24e47190 #define BLOCK_INDEX 0x00000001 | > > > > > > > > > > > > > > > > > > > > > | 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 | Db *pDb; /* The whole database */ DbCursor *pPrev, *pNext; /* Linked list of all cursors */ u32 rootPgno; /* Root page of table for this cursor */ int onEntry; /* True if pointing to a table entry */ int nLevel; /* Number of levels of indexing used */ DbIdxpt aLevel[MX_LEVEL]; /* The index levels */ }; /* ** Used for rebalancing */ typedef struct DbEntry DbEntry; struct DbEntry { int nByte; /* Space needed on leaf to record this entry */ int pgno; /* Page on which this entry is currently found */ int idx; /* Index slot in part that points to leaf "pgno" */ u32 *aPage; /* Pointer to the leaf for this entry */ u32 *aEntry; /* Pointer to the actual text of this entry */ DbEntry *pNext; /* Next entry in a list of them all */ }; typedef struct DbEntrySet DbEntrySet; struct DbEntrySet { u32 *pIndex; /* The index node above the leaf pages being balanced */ int nAlloc; /* Number of slots allocated in aEntry[] */ int nEntry; /* Number of slots in aEntry[] actually used */ DbEntry *pFirst; /* First entry in hash order */ DbEntry aEntry[100]; /* Descriptions of actual database entries */ }; /* ** The first word of every page is some combination of these values ** used to indicate its function. */ #define BLOCK_MAGIC 0x24e47190 #define BLOCK_INDEX 0x00000001 |
︙ | ︙ | |||
660 661 662 663 664 665 666 | sqlitePgTouch(aPage1); sqlitePgCommit(pDb->pPgr); } pDb->nContent = aPage1[2]/sizeof(u32); pDb->nAlloc = 0; rc = sqliteDbExpandContent(pDb, pDb->nContent); if( rc!=SQLITE_OK ) goto open_err; | | > | | > | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | sqlitePgTouch(aPage1); sqlitePgCommit(pDb->pPgr); } pDb->nContent = aPage1[2]/sizeof(u32); pDb->nAlloc = 0; rc = sqliteDbExpandContent(pDb, pDb->nContent); if( rc!=SQLITE_OK ) goto open_err; rc = payloadRead(pDb, &aPage1[3], 0, aPage1[2], pDb->aContent); sqlitePgUnref(aPage1); if( rc!=SQLITE_OK ) goto open_err; *ppDb = pDb; return SQLITE_OK; open_err: *ppDb = 0; if( pPgr ) sqlitePgClose(pPgr); if( pDb ){ sqliteFree(pDb->aContent); sqliteFree(pDb); } return rc; } /* ** Close a database */ int sqliteDbClose(Db *pDb){ |
︙ | ︙ | |||
741 742 743 744 745 746 747 | if( rc!=SQLITE_OK ) return rc; rc = sqlitePgGet(pDb->pPgr, 1, &aPage1); if( rc!=SQLITE_OK ) return rc; pDb->nContent = SWB(aPage1[3]) + 2; if( sqliteDbExpandContent(pDb, pDb->nContent)!=SQLITE_OK ){ return SQLITE_NOMEM; } | | | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | if( rc!=SQLITE_OK ) return rc; rc = sqlitePgGet(pDb->pPgr, 1, &aPage1); if( rc!=SQLITE_OK ) return rc; pDb->nContent = SWB(aPage1[3]) + 2; if( sqliteDbExpandContent(pDb, pDb->nContent)!=SQLITE_OK ){ return SQLITE_NOMEM; } payloadRead(pDb, &aPage1[3], 0, pDb->nContent*sizeof(u32), pDb->aContent); pDb->inTransaction = 0; return SQLITE_OK; } /* ** Create a new table in the database. Write the table number ** that is used to open a cursor into that table into *pTblno. |
︙ | ︙ | |||
769 770 771 772 773 774 775 | for(i=2; i<pDb->nContent; i++){ if( pDb->aContent[i]==0 ){ tblno = i - 2; break; } } if( tblno<0 ){ | | | | | | | | > | < < < | | | | | | < < < < < < < < < | 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 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 | for(i=2; i<pDb->nContent; i++){ if( pDb->aContent[i]==0 ){ tblno = i - 2; break; } } if( tblno<0 ){ tblno = pDb->aContent[1]; } if( tblno+2 >= pDb->nContent ){ sqliteDbExpandContent(pDb, tblno+2); } if( pDb->aContent==0 ){ rc = SQLITE_NOMEM; }else{ pDb->aContent[tblno+2] = pgno; pPage[0] = SWB(BLOCK_MAGIC | BLOCK_LEAF); memset(&pPage[1], 0, SQLITE_PAGE_SIZE - sizeof(u32)); sqlitePgTouch(pPage); } sqlitePgUnref(pPage); return rc; } /* ** Recursively add a page to the free list */ static int sqliteDbDropPage(Db *pDb, u32 pgno){ u32 *aPage; int rc; rc = sqlitePgGet(pDb->pPgr, pgno, (void**)&aPage); if( rc!=SQLITE_OK ) return rc; switch( aPage[0] ){ case BLOCK_MAGIC | BLOCK_INDEX: { int n, i; n = aPage[2]; for(i=0; i<n; i++){ u32 subpgno = aPage[4+i*2]; if( subpgno>0 ) sqliteDbDropPage(pDb, subpgno); } freePage(pDb, pgno, aPage); break; } case BLOCK_MAGIC | BLOCK_LEAF: { int i = 2; while( i<U32_PER_PAGE ){ int entrySize = aPage[i]; if( entrySize==0 ) break; payloadFree(pDb, &aPage[i+4], 0, aPage[i+2]+aPage[i+3]); i += entrySize; } freePage(pDb, pgno, aPage); break; } default: { /* Do nothing */ break; } } } /* ** Delete the current associate of a cursor and release all the ** pages it holds. Except, do not release pages at levels less ** than N. */ static void sqliteDbResetCursor(DbCursor *pCur, int N){ int i; |
︙ | ︙ | |||
864 865 866 867 868 869 870 | */ if( pDb->aContent==0 ){ return SQLITE_NOMEM; } if( tblno<0 || tblno+2>=pDb->nContent || pDb->aContent[tblno+2]==0 ){ return SQLITE_NOTFOUND; } | > | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | */ if( pDb->aContent==0 ){ return SQLITE_NOMEM; } if( tblno<0 || tblno+2>=pDb->nContent || pDb->aContent[tblno+2]==0 ){ return SQLITE_NOTFOUND; } pgno = pDb->aContent[tblno+2]; pDb->aContent[tblno+2] = 0; /* Reset any cursors pointing to the table that is about to ** be dropped */ for(pCur=pDb->pCursor; pCur; pCur=pCur->pNext){ if( pCur->rootPgno==pgno ){ sqliteDbResetCursor(pCur, 0); } } |
︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 | u32 *aPage; int idx, i; if( !pCur->onEntry ) return 0; i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); | | | | | | < < | | < < < | | > | < < | < | < < | < > > | < < | | | > | < < < < | | < < < < < | < < > | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 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 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | u32 *aPage; int idx, i; if( !pCur->onEntry ) return 0; i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); assert( idx>=2 && idx+4<U32_PER_PAGE ); return aPage[idx+3]; } /* ** Return the number of bytes of key on the entry that the cursor points ** to. */ int sqliteDbCursorKeysize(DbCursor *pCur){ u32 *aPage; int idx, i; if( !pCur->onEntry ) return 0; i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); assert( idx>=2 && idx+4<U32_PER_PAGE ); return aPage[idx+2]; } /* ** Read data from the cursor. */ int sqliteDbCursorRead(DbCursor *pCur, int amt, int offset, void *buf){ u32 *aPage; int idx, i; int nData; int nKey; if( !pCur->onEntry ){ memset(cbuf, 0, amt); return SQLITE_OK; } if( amt<=0 || offset<0 ){ return SQLITE_ERR; } i = pCur->nLevel-1; idx = pCur->aLevel[i].idx; aPage = pCur->aLevel[i].aPage; assert( aPage ); assert( idx>=2 && idx+4<U32_PER_PAGE ); nData = aPage[idx+3]; if( offset>=nData ){ memset(buf, 0, amt); return SQLITE_OK; } nKey = aPage[idx+2]; if( nData<offset+amt ){ memset(&((char*)buf)[nData-offset], 0, amt+offset-nData); amt = nData - offset; } payloadRead(pCur->pDb, &aPage[idx+4], amt, offset + nKey, buf); return SQLITE_OK; } /* ** Read the current key from the cursor. */ int sqliteDbCursorReadKey(DbCursor *pCur, int amt, int offset, void *buf){ u32 *aPage; int idx, i; int nData; int nKey; if( !pCur->onEntry ){ memset(cbuf, 0, amt); return SQLITE_OK; } if( amt<=0 || offset<0 ){ return SQLITE_ERR; } 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 = aPage[idx+2]; if( offset>=nKey ){ memset(buf, 0, amt); return SQLITE_OK; } if( nKey<offset+amt ){ memset(&((char*)buf)[nKey-offset], 0, amt+offset-nKey); amt = nKey - offset; } payloadRead(pCur->pDb, &aPage[idx+4], amt, offset, buf); return SQLITE_OK; } /* ** Generate a 32-bit hash from the given key. */ static u32 sqliteDbHash(int nKey, void *pKey){ u32 h; |
︙ | ︙ |
Changes to src/db.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 | ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** $Id: db.h,v 1.4 2001/01/29 01:27:20 drh Exp $ */ typedef struct Db Db; typedef struct DbCursor DbCursor; int sqliteDbOpen(const char *filename, Db**); int sqliteDbClose(Db*); |
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 | int sqliteDbCursorFirst(DbCursor*); int sqliteDbCursorNext(DbCursor*); int sqliteDbCursorDatasize(DbCursor*); int sqliteDbCursorKeysize(DbCursor*); int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf); int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf); int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createSize); int sqliteDbCursorResize(DbCursor*, int nData); | > > < | 41 42 43 44 45 46 47 48 49 50 51 | int sqliteDbCursorFirst(DbCursor*); int sqliteDbCursorNext(DbCursor*); int sqliteDbCursorDatasize(DbCursor*); int sqliteDbCursorKeysize(DbCursor*); int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf); int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf); int sqliteDbCursorWrite(DbCursor*, int amt, int offset, const void *buf); int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createSize); int sqliteDbCursorResize(DbCursor*, int nData); |