wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3 using System.Text;
4  
5 using i64 = System.Int64;
6 using u8 = System.Byte;
7 using u16 = System.UInt16;
8 using u32 = System.UInt32;
9 using u64 = System.UInt64;
10 using sqlite3_int64 = System.Int64;
11 using Pgno = System.UInt32;
12  
13 namespace Community.CsharpSqlite
14 {
15 using DbPage = Sqlite3.PgHdr;
16  
17 public partial class Sqlite3
18 {
19 /*
20 ** 2004 April 6
21 **
22 ** The author disclaims copyright to this source code. In place of
23 ** a legal notice, here is a blessing:
24 **
25 ** May you do good and not evil.
26 ** May you find forgiveness for yourself and forgive others.
27 ** May you share freely, never taking more than you give.
28 **
29 ** This file implements a external (disk-based) database using BTrees.
30 ** See the header comment on "btreeInt.h" for additional information.
31 ** Including a description of file format and an overview of operation.
32 *************************************************************************
33 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
34 ** C#-SQLite is an independent reimplementation of the SQLite software library
35 **
36 ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
37 **
38 *************************************************************************
39 */
40 //#include "btreeInt.h"
41  
42 /*
43 ** The header string that appears at the beginning of every
44 ** SQLite database.
45 */
46 static byte[] zMagicHeader = Encoding.UTF8.GetBytes( SQLITE_FILE_HEADER );
47  
48 /*
49 ** Set this global variable to 1 to enable tracing using the TRACE
50 ** macro.
51 */
52 #if TRACE
53 static bool sqlite3BtreeTrace=false; /* True to enable tracing */
54 //# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);}
55 static void TRACE(string X, params object[] ap) { if (sqlite3BtreeTrace) printf(X, ap); }
56 #else
57 //# define TRACE(X)
58 static void TRACE( string X, params object[] ap )
59 {
60 }
61 #endif
62  
63 /*
64 ** Extract a 2-byte big-endian integer from an array of unsigned bytes.
65 ** But if the value is zero, make it 65536.
66 **
67 ** This routine is used to extract the "offset to cell content area" value
68 ** from the header of a btree page. If the page size is 65536 and the page
69 ** is empty, the offset should be 65536, but the 2-byte value stores zero.
70 ** This routine makes the necessary adjustment to 65536.
71 */
72 //#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1)
73 static int get2byteNotZero( byte[] X, int offset )
74 {
75 return ( ( ( ( (int)get2byte( X, offset ) ) - 1 ) & 0xffff ) + 1 );
76 }
77  
78 #if !SQLITE_OMIT_SHARED_CACHE
79 /*
80 ** A list of BtShared objects that are eligible for participation
81 ** in shared cache. This variable has file scope during normal builds,
82 ** but the test harness needs to access it so we make it global for
83 ** test builds.
84 **
85 ** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
86 */
87 #if SQLITE_TEST
88 BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
89 #else
90 static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
91 #endif
92 #endif //* SQLITE_OMIT_SHARED_CACHE */
93  
94 #if !SQLITE_OMIT_SHARED_CACHE
95 /*
96 ** Enable or disable the shared pager and schema features.
97 **
98 ** This routine has no effect on existing database connections.
99 ** The shared cache setting effects only future calls to
100 ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
101 */
102 int sqlite3_enable_shared_cache(int enable){
103 sqlite3GlobalConfig.sharedCacheEnabled = enable;
104 return SQLITE_OK;
105 }
106 #endif
107  
108  
109  
110 #if SQLITE_OMIT_SHARED_CACHE
111 /*
112 ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
113 ** and clearAllSharedCacheTableLocks()
114 ** manipulate entries in the BtShared.pLock linked list used to store
115 ** shared-cache table level locks. If the library is compiled with the
116 ** shared-cache feature disabled, then there is only ever one user
117 ** of each BtShared structure and so this locking is not necessary.
118 ** So define the lock related functions as no-ops.
119 */
120 //#define querySharedCacheTableLock(a,b,c) SQLITE_OK
121 static int querySharedCacheTableLock( Btree p, Pgno iTab, u8 eLock )
122 {
123 return SQLITE_OK;
124 }
125  
126 //#define setSharedCacheTableLock(a,b,c) SQLITE_OK
127 //#define clearAllSharedCacheTableLocks(a)
128 static void clearAllSharedCacheTableLocks( Btree a )
129 {
130 }
131 //#define downgradeAllSharedCacheTableLocks(a)
132 static void downgradeAllSharedCacheTableLocks( Btree a )
133 {
134 }
135 //#define hasSharedCacheTableLock(a,b,c,d) 1
136 static bool hasSharedCacheTableLock( Btree a, Pgno b, int c, int d )
137 {
138 return true;
139 }
140 //#define hasReadConflicts(a, b) 0
141 static bool hasReadConflicts( Btree a, Pgno b )
142 {
143 return false;
144 }
145 #endif
146  
147 #if !SQLITE_OMIT_SHARED_CACHE
148  
149 #if SQLITE_DEBUG
150 /*
151 **** This function is only used as part of an assert() statement. ***
152 **
153 ** Check to see if pBtree holds the required locks to read or write to the
154 ** table with root page iRoot. Return 1 if it does and 0 if not.
155 **
156 ** For example, when writing to a table with root-page iRoot via
157 ** Btree connection pBtree:
158 **
159 ** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) );
160 **
161 ** When writing to an index that resides in a sharable database, the
162 ** caller should have first obtained a lock specifying the root page of
163 ** the corresponding table. This makes things a bit more complicated,
164 ** as this module treats each table as a separate structure. To determine
165 ** the table corresponding to the index being written, this
166 ** function has to search through the database schema.
167 **
168 ** Instead of a lock on the table/index rooted at page iRoot, the caller may
169 ** hold a write-lock on the schema table (root page 1). This is also
170 ** acceptable.
171 */
172 static int hasSharedCacheTableLock(
173 Btree pBtree, /* Handle that must hold lock */
174 Pgno iRoot, /* Root page of b-tree */
175 int isIndex, /* True if iRoot is the root of an index b-tree */
176 int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */
177 ){
178 Schema pSchema = (Schema *)pBtree.pBt.pSchema;
179 Pgno iTab = 0;
180 BtLock pLock;
181  
182 /* If this database is not shareable, or if the client is reading
183 ** and has the read-uncommitted flag set, then no lock is required.
184 ** Return true immediately.
185 */
186 if( (pBtree.sharable==null)
187 || (eLockType==READ_LOCK && (pBtree.db.flags & SQLITE_ReadUncommitted))
188 ){
189 return 1;
190 }
191  
192 /* If the client is reading or writing an index and the schema is
193 ** not loaded, then it is too difficult to actually check to see if
194 ** the correct locks are held. So do not bother - just return true.
195 ** This case does not come up very often anyhow.
196 */
197 if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){
198 return 1;
199 }
200  
201 /* Figure out the root-page that the lock should be held on. For table
202 ** b-trees, this is just the root page of the b-tree being read or
203 ** written. For index b-trees, it is the root page of the associated
204 ** table. */
205 if( isIndex ){
206 HashElem p;
207 for(p=sqliteHashFirst(pSchema.idxHash); p!=null; p=sqliteHashNext(p)){
208 Index pIdx = (Index *)sqliteHashData(p);
209 if( pIdx.tnum==(int)iRoot ){
210 iTab = pIdx.pTable.tnum;
211 }
212 }
213 }else{
214 iTab = iRoot;
215 }
216  
217 /* Search for the required lock. Either a write-lock on root-page iTab, a
218 ** write-lock on the schema table, or (if the client is reading) a
219 ** read-lock on iTab will suffice. Return 1 if any of these are found. */
220 for(pLock=pBtree.pBt.pLock; pLock; pLock=pLock.pNext){
221 if( pLock.pBtree==pBtree
222 && (pLock.iTable==iTab || (pLock.eLock==WRITE_LOCK && pLock.iTable==1))
223 && pLock.eLock>=eLockType
224 ){
225 return 1;
226 }
227 }
228  
229 /* Failed to find the required lock. */
230 return 0;
231 }
232  
233 #endif //* SQLITE_DEBUG */
234  
235 #if SQLITE_DEBUG
236 /*
237 ** This function may be used as part of assert() statements only. ****
238 **
239 ** Return true if it would be illegal for pBtree to write into the
240 ** table or index rooted at iRoot because other shared connections are
241 ** simultaneously reading that same table or index.
242 **
243 ** It is illegal for pBtree to write if some other Btree object that
244 ** shares the same BtShared object is currently reading or writing
245 ** the iRoot table. Except, if the other Btree object has the
246 ** read-uncommitted flag set, then it is OK for the other object to
247 ** have a read cursor.
248 **
249 ** For example, before writing to any part of the table or index
250 ** rooted at page iRoot, one should call:
251 **
252 ** assert( !hasReadConflicts(pBtree, iRoot) );
253 */
254 static int hasReadConflicts(Btree pBtree, Pgno iRoot){
255 BtCursor p;
256 for(p=pBtree.pBt.pCursor; p!=null; p=p.pNext){
257 if( p.pgnoRoot==iRoot
258 && p.pBtree!=pBtree
259 && 0==(p.pBtree.db.flags & SQLITE_ReadUncommitted)
260 ){
261 return 1;
262 }
263 }
264 return 0;
265 }
266 #endif //* #if SQLITE_DEBUG */
267  
268 /*
269 ** Query to see if Btree handle p may obtain a lock of type eLock
270 ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
271 ** SQLITE_OK if the lock may be obtained (by calling
272 ** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
273 */
274 static int querySharedCacheTableLock(Btree p, Pgno iTab, u8 eLock){
275 BtShared pBt = p.pBt;
276 BtLock pIter;
277  
278 Debug.Assert( sqlite3BtreeHoldsMutex(p) );
279 Debug.Assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
280 Debug.Assert( p.db!=null );
281 Debug.Assert( !(p.db.flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
282  
283 /* If requesting a write-lock, then the Btree must have an open write
284 ** transaction on this file. And, obviously, for this to be so there
285 ** must be an open write transaction on the file itself.
286 */
287 Debug.Assert( eLock==READ_LOCK || (p==pBt.pWriter && p.inTrans==TRANS_WRITE) );
288 Debug.Assert( eLock==READ_LOCK || pBt.inTransaction==TRANS_WRITE );
289  
290 /* This routine is a no-op if the shared-cache is not enabled */
291 if( !p.sharable ){
292 return SQLITE_OK;
293 }
294  
295 /* If some other connection is holding an exclusive lock, the
296 ** requested lock may not be obtained.
297 */
298 if( pBt.pWriter!=p && pBt.isExclusive ){
299 sqlite3ConnectionBlocked(p.db, pBt.pWriter.db);
300 return SQLITE_LOCKED_SHAREDCACHE;
301 }
302  
303 for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
304 /* The condition (pIter.eLock!=eLock) in the following if(...)
305 ** statement is a simplification of:
306 **
307 ** (eLock==WRITE_LOCK || pIter.eLock==WRITE_LOCK)
308 **
309 ** since we know that if eLock==WRITE_LOCK, then no other connection
310 ** may hold a WRITE_LOCK on any table in this file (since there can
311 ** only be a single writer).
312 */
313 Debug.Assert( pIter.eLock==READ_LOCK || pIter.eLock==WRITE_LOCK );
314 Debug.Assert( eLock==READ_LOCK || pIter.pBtree==p || pIter.eLock==READ_LOCK);
315 if( pIter.pBtree!=p && pIter.iTable==iTab && pIter.eLock!=eLock ){
316 sqlite3ConnectionBlocked(p.db, pIter.pBtree.db);
317 if( eLock==WRITE_LOCK ){
318 Debug.Assert( p==pBt.pWriter );
319 pBt.isPending = 1;
320 }
321 return SQLITE_LOCKED_SHAREDCACHE;
322 }
323 }
324 return SQLITE_OK;
325 }
326 #endif //* !SQLITE_OMIT_SHARED_CACHE */
327  
328 #if !SQLITE_OMIT_SHARED_CACHE
329 /*
330 ** Add a lock on the table with root-page iTable to the shared-btree used
331 ** by Btree handle p. Parameter eLock must be either READ_LOCK or
332 ** WRITE_LOCK.
333 **
334 ** This function assumes the following:
335 **
336 ** (a) The specified Btree object p is connected to a sharable
337 ** database (one with the BtShared.sharable flag set), and
338 **
339 ** (b) No other Btree objects hold a lock that conflicts
340 ** with the requested lock (i.e. querySharedCacheTableLock() has
341 ** already been called and returned SQLITE_OK).
342 **
343 ** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM
344 ** is returned if a malloc attempt fails.
345 */
346 static int setSharedCacheTableLock(Btree p, Pgno iTable, u8 eLock){
347 BtShared pBt = p.pBt;
348 BtLock pLock = 0;
349 BtLock pIter;
350  
351 Debug.Assert( sqlite3BtreeHoldsMutex(p) );
352 Debug.Assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
353 Debug.Assert( p.db!=null );
354  
355 /* A connection with the read-uncommitted flag set will never try to
356 ** obtain a read-lock using this function. The only read-lock obtained
357 ** by a connection in read-uncommitted mode is on the sqlite_master
358 ** table, and that lock is obtained in BtreeBeginTrans(). */
359 Debug.Assert( 0==(p.db.flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
360  
361 /* This function should only be called on a sharable b-tree after it
362 ** has been determined that no other b-tree holds a conflicting lock. */
363 Debug.Assert( p.sharable );
364 Debug.Assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
365  
366 /* First search the list for an existing lock on this table. */
367 for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
368 if( pIter.iTable==iTable && pIter.pBtree==p ){
369 pLock = pIter;
370 break;
371 }
372 }
373  
374 /* If the above search did not find a BtLock struct associating Btree p
375 ** with table iTable, allocate one and link it into the list.
376 */
377 if( !pLock ){
378 pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
379 if( !pLock ){
380 return SQLITE_NOMEM;
381 }
382 pLock.iTable = iTable;
383 pLock.pBtree = p;
384 pLock.pNext = pBt.pLock;
385 pBt.pLock = pLock;
386 }
387  
388 /* Set the BtLock.eLock variable to the maximum of the current lock
389 ** and the requested lock. This means if a write-lock was already held
390 ** and a read-lock requested, we don't incorrectly downgrade the lock.
391 */
392 Debug.Assert( WRITE_LOCK>READ_LOCK );
393 if( eLock>pLock.eLock ){
394 pLock.eLock = eLock;
395 }
396  
397 return SQLITE_OK;
398 }
399 #endif //* !SQLITE_OMIT_SHARED_CACHE */
400  
401 #if !SQLITE_OMIT_SHARED_CACHE
402 /*
403 ** Release all the table locks (locks obtained via calls to
404 ** the setSharedCacheTableLock() procedure) held by Btree object p.
405 **
406 ** This function assumes that Btree p has an open read or write
407 ** transaction. If it does not, then the BtShared.isPending variable
408 ** may be incorrectly cleared.
409 */
410 static void clearAllSharedCacheTableLocks(Btree p){
411 BtShared pBt = p.pBt;
412 BtLock **ppIter = &pBt.pLock;
413  
414 Debug.Assert( sqlite3BtreeHoldsMutex(p) );
415 Debug.Assert( p.sharable || 0==*ppIter );
416 Debug.Assert( p.inTrans>0 );
417  
418 while( ppIter ){
419 BtLock pLock = ppIter;
420 Debug.Assert( pBt.isExclusive==null || pBt.pWriter==pLock.pBtree );
421 Debug.Assert( pLock.pBtree.inTrans>=pLock.eLock );
422 if( pLock.pBtree==p ){
423 ppIter = pLock.pNext;
424 Debug.Assert( pLock.iTable!=1 || pLock==&p.lock );
425 if( pLock.iTable!=1 ){
426 pLock=null;//sqlite3_free(ref pLock);
427 }
428 }else{
429 ppIter = &pLock.pNext;
430 }
431 }
432  
433 Debug.Assert( pBt.isPending==null || pBt.pWriter );
434 if( pBt.pWriter==p ){
435 pBt.pWriter = 0;
436 pBt.isExclusive = 0;
437 pBt.isPending = 0;
438 }else if( pBt.nTransaction==2 ){
439 /* This function is called when Btree p is concluding its
440 ** transaction. If there currently exists a writer, and p is not
441 ** that writer, then the number of locks held by connections other
442 ** than the writer must be about to drop to zero. In this case
443 ** set the isPending flag to 0.
444 **
445 ** If there is not currently a writer, then BtShared.isPending must
446 ** be zero already. So this next line is harmless in that case.
447 */
448 pBt.isPending = 0;
449 }
450 }
451  
452 /*
453 ** This function changes all write-locks held by Btree p into read-locks.
454 */
455 static void downgradeAllSharedCacheTableLocks(Btree p){
456 BtShared pBt = p.pBt;
457 if( pBt.pWriter==p ){
458 BtLock pLock;
459 pBt.pWriter = 0;
460 pBt.isExclusive = 0;
461 pBt.isPending = 0;
462 for(pLock=pBt.pLock; pLock; pLock=pLock.pNext){
463 Debug.Assert( pLock.eLock==READ_LOCK || pLock.pBtree==p );
464 pLock.eLock = READ_LOCK;
465 }
466 }
467 }
468  
469 #endif //* SQLITE_OMIT_SHARED_CACHE */
470  
471 //static void releasePage(MemPage pPage); /* Forward reference */
472  
473 /*
474 ***** This routine is used inside of assert() only ****
475 **
476 ** Verify that the cursor holds the mutex on its BtShared
477 */
478 #if SQLITE_DEBUG
479 static bool cursorHoldsMutex( BtCursor p )
480 {
481 return sqlite3_mutex_held( p.pBt.mutex );
482 }
483 #else
484 static bool cursorHoldsMutex(BtCursor p) { return true; }
485 #endif
486  
487  
488 #if !SQLITE_OMIT_INCRBLOB
489 /*
490 ** Invalidate the overflow page-list cache for cursor pCur, if any.
491 */
492 static void invalidateOverflowCache(BtCursor pCur){
493 Debug.Assert( cursorHoldsMutex(pCur) );
494 //sqlite3_free(ref pCur.aOverflow);
495 pCur.aOverflow = null;
496 }
497  
498 /*
499 ** Invalidate the overflow page-list cache for all cursors opened
500 ** on the shared btree structure pBt.
501 */
502 static void invalidateAllOverflowCache(BtShared pBt){
503 BtCursor p;
504 Debug.Assert( sqlite3_mutex_held(pBt.mutex) );
505 for(p=pBt.pCursor; p!=null; p=p.pNext){
506 invalidateOverflowCache(p);
507 }
508 }
509  
510 /*
511 ** This function is called before modifying the contents of a table
512 ** to invalidate any incrblob cursors that are open on the
513 ** row or one of the rows being modified.
514 **
515 ** If argument isClearTable is true, then the entire contents of the
516 ** table is about to be deleted. In this case invalidate all incrblob
517 ** cursors open on any row within the table with root-page pgnoRoot.
518 **
519 ** Otherwise, if argument isClearTable is false, then the row with
520 ** rowid iRow is being replaced or deleted. In this case invalidate
521 ** only those incrblob cursors open on that specific row.
522 */
523 static void invalidateIncrblobCursors(
524 Btree pBtree, /* The database file to check */
525 i64 iRow, /* The rowid that might be changing */
526 int isClearTable /* True if all rows are being deleted */
527 ){
528 BtCursor p;
529 BtShared pBt = pBtree.pBt;
530 Debug.Assert( sqlite3BtreeHoldsMutex(pBtree) );
531 for(p=pBt.pCursor; p!=null; p=p.pNext){
532 if( p.isIncrblobHandle && (isClearTable || p.info.nKey==iRow) ){
533 p.eState = CURSOR_INVALID;
534 }
535 }
536 }
537  
538 #else
539 /* Stub functions when INCRBLOB is omitted */
540 //#define invalidateOverflowCache(x)
541 static void invalidateOverflowCache( BtCursor pCur )
542 {
543 }
544 //#define invalidateAllOverflowCache(x)
545 static void invalidateAllOverflowCache( BtShared pBt )
546 {
547 }
548 //#define invalidateIncrblobCursors(x,y,z)
549 static void invalidateIncrblobCursors( Btree x, i64 y, int z )
550 {
551 }
552 #endif //* SQLITE_OMIT_INCRBLOB */
553  
554 /*
555 ** Set bit pgno of the BtShared.pHasContent bitvec. This is called
556 ** when a page that previously contained data becomes a free-list leaf
557 ** page.
558 **
559 ** The BtShared.pHasContent bitvec exists to work around an obscure
560 ** bug caused by the interaction of two useful IO optimizations surrounding
561 ** free-list leaf pages:
562 **
563 ** 1) When all data is deleted from a page and the page becomes
564 ** a free-list leaf page, the page is not written to the database
565 ** (as free-list leaf pages contain no meaningful data). Sometimes
566 ** such a page is not even journalled (as it will not be modified,
567 ** why bother journalling it?).
568 **
569 ** 2) When a free-list leaf page is reused, its content is not read
570 ** from the database or written to the journal file (why should it
571 ** be, if it is not at all meaningful?).
572 **
573 ** By themselves, these optimizations work fine and provide a handy
574 ** performance boost to bulk delete or insert operations. However, if
575 ** a page is moved to the free-list and then reused within the same
576 ** transaction, a problem comes up. If the page is not journalled when
577 ** it is moved to the free-list and it is also not journalled when it
578 ** is extracted from the free-list and reused, then the original data
579 ** may be lost. In the event of a rollback, it may not be possible
580 ** to restore the database to its original configuration.
581 **
582 ** The solution is the BtShared.pHasContent bitvec. Whenever a page is
583 ** moved to become a free-list leaf page, the corresponding bit is
584 ** set in the bitvec. Whenever a leaf page is extracted from the free-list,
585 ** optimization 2 above is omitted if the corresponding bit is already
586 ** set in BtShared.pHasContent. The contents of the bitvec are cleared
587 ** at the end of every transaction.
588 */
589 static int btreeSetHasContent( BtShared pBt, Pgno pgno )
590 {
591 int rc = SQLITE_OK;
592 if ( null == pBt.pHasContent )
593 {
594 Debug.Assert( pgno <= pBt.nPage );
595 pBt.pHasContent = sqlite3BitvecCreate( pBt.nPage );
596 //if ( null == pBt.pHasContent )
597 //{
598 // rc = SQLITE_NOMEM;
599 //}
600 }
601 if ( rc == SQLITE_OK && pgno <= sqlite3BitvecSize( pBt.pHasContent ) )
602 {
603 rc = sqlite3BitvecSet( pBt.pHasContent, pgno );
604 }
605 return rc;
606 }
607  
608 /*
609 ** Query the BtShared.pHasContent vector.
610 **
611 ** This function is called when a free-list leaf page is removed from the
612 ** free-list for reuse. It returns false if it is safe to retrieve the
613 ** page from the pager layer with the 'no-content' flag set. True otherwise.
614 */
615 static bool btreeGetHasContent( BtShared pBt, Pgno pgno )
616 {
617 Bitvec p = pBt.pHasContent;
618 return ( p != null && ( pgno > sqlite3BitvecSize( p ) || sqlite3BitvecTest( p, pgno ) != 0 ) );
619 }
620  
621 /*
622 ** Clear (destroy) the BtShared.pHasContent bitvec. This should be
623 ** invoked at the conclusion of each write-transaction.
624 */
625 static void btreeClearHasContent( BtShared pBt )
626 {
627 sqlite3BitvecDestroy( ref pBt.pHasContent );
628 pBt.pHasContent = null;
629 }
630  
631 /*
632 ** Save the current cursor position in the variables BtCursor.nKey
633 ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
634 **
635 ** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
636 ** prior to calling this routine.
637 */
638 static int saveCursorPosition( BtCursor pCur )
639 {
640 int rc;
641  
642 Debug.Assert( CURSOR_VALID == pCur.eState );
643 Debug.Assert( null == pCur.pKey );
644 Debug.Assert( cursorHoldsMutex( pCur ) );
645  
646 rc = sqlite3BtreeKeySize( pCur, ref pCur.nKey );
647 Debug.Assert( rc == SQLITE_OK ); /* KeySize() cannot fail */
648  
649 /* If this is an intKey table, then the above call to BtreeKeySize()
650 ** stores the integer key in pCur.nKey. In this case this value is
651 ** all that is required. Otherwise, if pCur is not open on an intKey
652 ** table, then malloc space for and store the pCur.nKey bytes of key
653 ** data.
654 */
655 if ( 0 == pCur.apPage[0].intKey )
656 {
657 byte[] pKey = sqlite3Malloc( (int)pCur.nKey );
658 //if( pKey !=null){
659 rc = sqlite3BtreeKey( pCur, 0, (u32)pCur.nKey, pKey );
660 if ( rc == SQLITE_OK )
661 {
662 pCur.pKey = pKey;
663 }
664 //else{
665 // sqlite3_free(ref pKey);
666 //}
667 //}else{
668 // rc = SQLITE_NOMEM;
669 //}
670 }
671 Debug.Assert( 0 == pCur.apPage[0].intKey || null == pCur.pKey );
672  
673 if ( rc == SQLITE_OK )
674 {
675 int i;
676 for ( i = 0; i <= pCur.iPage; i++ )
677 {
678 releasePage( pCur.apPage[i] );
679 pCur.apPage[i] = null;
680 }
681 pCur.iPage = -1;
682 pCur.eState = CURSOR_REQUIRESEEK;
683 }
684  
685 invalidateOverflowCache( pCur );
686 return rc;
687 }
688  
689 /*
690 ** Save the positions of all cursors (except pExcept) that are open on
691 ** the table with root-page iRoot. Usually, this is called just before cursor
692 ** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
693 */
694 static int saveAllCursors( BtShared pBt, Pgno iRoot, BtCursor pExcept )
695 {
696 BtCursor p;
697 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
698 Debug.Assert( pExcept == null || pExcept.pBt == pBt );
699 for ( p = pBt.pCursor; p != null; p = p.pNext )
700 {
701 if ( p != pExcept && ( 0 == iRoot || p.pgnoRoot == iRoot ) &&
702 p.eState == CURSOR_VALID )
703 {
704 int rc = saveCursorPosition( p );
705 if ( SQLITE_OK != rc )
706 {
707 return rc;
708 }
709 }
710 }
711 return SQLITE_OK;
712 }
713  
714 /*
715 ** Clear the current cursor position.
716 */
717 static void sqlite3BtreeClearCursor( BtCursor pCur )
718 {
719 Debug.Assert( cursorHoldsMutex( pCur ) );
720 sqlite3_free( ref pCur.pKey );
721 pCur.eState = CURSOR_INVALID;
722 }
723  
724 /*
725 ** In this version of BtreeMoveto, pKey is a packed index record
726 ** such as is generated by the OP_MakeRecord opcode. Unpack the
727 ** record and then call BtreeMovetoUnpacked() to do the work.
728 */
729 static int btreeMoveto(
730 BtCursor pCur, /* Cursor open on the btree to be searched */
731 byte[] pKey, /* Packed key if the btree is an index */
732 i64 nKey, /* Integer key for tables. Size of pKey for indices */
733 int bias, /* Bias search to the high end */
734 ref int pRes /* Write search results here */
735 )
736 {
737 int rc; /* Status code */
738 UnpackedRecord pIdxKey; /* Unpacked index key */
739 UnpackedRecord aSpace = new UnpackedRecord();//char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
740  
741 if ( pKey != null )
742 {
743 Debug.Assert( nKey == (i64)(int)nKey );
744 pIdxKey = sqlite3VdbeRecordUnpack( pCur.pKeyInfo, (int)nKey, pKey,
745 aSpace, 16 );//sizeof( aSpace ) );
746 //if ( pIdxKey == null )
747 // return SQLITE_NOMEM;
748 }
749 else
750 {
751 pIdxKey = null;
752 }
753 rc = sqlite3BtreeMovetoUnpacked( pCur, pIdxKey, nKey, bias != 0 ? 1 : 0, ref pRes );
754  
755 if ( pKey != null )
756 {
757 sqlite3VdbeDeleteUnpackedRecord( pIdxKey );
758 }
759 return rc;
760 }
761  
762 /*
763 ** Restore the cursor to the position it was in (or as close to as possible)
764 ** when saveCursorPosition() was called. Note that this call deletes the
765 ** saved position info stored by saveCursorPosition(), so there can be
766 ** at most one effective restoreCursorPosition() call after each
767 ** saveCursorPosition().
768 */
769 static int btreeRestoreCursorPosition( BtCursor pCur )
770 {
771 int rc;
772 Debug.Assert( cursorHoldsMutex( pCur ) );
773 Debug.Assert( pCur.eState >= CURSOR_REQUIRESEEK );
774 if ( pCur.eState == CURSOR_FAULT )
775 {
776 return pCur.skipNext;
777 }
778 pCur.eState = CURSOR_INVALID;
779 rc = btreeMoveto( pCur, pCur.pKey, pCur.nKey, 0, ref pCur.skipNext );
780 if ( rc == SQLITE_OK )
781 {
782 //sqlite3_free(ref pCur.pKey);
783 pCur.pKey = null;
784 Debug.Assert( pCur.eState == CURSOR_VALID || pCur.eState == CURSOR_INVALID );
785 }
786 return rc;
787 }
788  
789 //#define restoreCursorPosition(p) \
790 // (p.eState>=CURSOR_REQUIRESEEK ? \
791 // btreeRestoreCursorPosition(p) : \
792 // SQLITE_OK)
793 static int restoreCursorPosition( BtCursor pCur )
794 {
795 if ( pCur.eState >= CURSOR_REQUIRESEEK )
796 return btreeRestoreCursorPosition( pCur );
797 else
798 return SQLITE_OK;
799 }
800  
801 /*
802 ** Determine whether or not a cursor has moved from the position it
803 ** was last placed at. Cursors can move when the row they are pointing
804 ** at is deleted out from under them.
805 **
806 ** This routine returns an error code if something goes wrong. The
807 ** integer pHasMoved is set to one if the cursor has moved and 0 if not.
808 */
809 static int sqlite3BtreeCursorHasMoved( BtCursor pCur, ref int pHasMoved )
810 {
811 int rc;
812  
813 rc = restoreCursorPosition( pCur );
814 if ( rc != 0 )
815 {
816 pHasMoved = 1;
817 return rc;
818 }
819 if ( pCur.eState != CURSOR_VALID || pCur.skipNext != 0 )
820 {
821 pHasMoved = 1;
822 }
823 else
824 {
825 pHasMoved = 0;
826 }
827 return SQLITE_OK;
828 }
829  
830 #if !SQLITE_OMIT_AUTOVACUUM
831 /*
832 ** Given a page number of a regular database page, return the page
833 ** number for the pointer-map page that contains the entry for the
834 ** input page number.
835 **
836 ** Return 0 (not a valid page) for pgno==1 since there is
837 ** no pointer map associated with page 1. The integrity_check logic
838 ** requires that ptrmapPageno(*,1)!=1.
839 */
840 static Pgno ptrmapPageno( BtShared pBt, Pgno pgno )
841 {
842 int nPagesPerMapPage;
843 Pgno iPtrMap, ret;
844 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
845 if ( pgno < 2 )
846 return 0;
847 nPagesPerMapPage = (int)( pBt.usableSize / 5 + 1 );
848 iPtrMap = (Pgno)( ( pgno - 2 ) / nPagesPerMapPage );
849 ret = (Pgno)( iPtrMap * nPagesPerMapPage ) + 2;
850 if ( ret == PENDING_BYTE_PAGE( pBt ) )
851 {
852 ret++;
853 }
854 return ret;
855 }
856  
857 /*
858 ** Write an entry into the pointer map.
859 **
860 ** This routine updates the pointer map entry for page number 'key'
861 ** so that it maps to type 'eType' and parent page number 'pgno'.
862 **
863 ** If pRC is initially non-zero (non-SQLITE_OK) then this routine is
864 ** a no-op. If an error occurs, the appropriate error code is written
865 ** into pRC.
866 */
867 static void ptrmapPut( BtShared pBt, Pgno key, u8 eType, Pgno parent, ref int pRC )
868 {
869 PgHdr pDbPage = new PgHdr(); /* The pointer map page */
870 u8[] pPtrmap; /* The pointer map data */
871 Pgno iPtrmap; /* The pointer map page number */
872 int offset; /* Offset in pointer map page */
873 int rc; /* Return code from subfunctions */
874  
875 if ( pRC != 0 )
876 return;
877  
878 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
879 /* The master-journal page number must never be used as a pointer map page */
880 Debug.Assert( false == PTRMAP_ISPAGE( pBt, PENDING_BYTE_PAGE( pBt ) ) );
881  
882 Debug.Assert( pBt.autoVacuum );
883 if ( key == 0 )
884 {
885 pRC = SQLITE_CORRUPT_BKPT();
886 return;
887 }
888 iPtrmap = PTRMAP_PAGENO( pBt, key );
889 rc = sqlite3PagerGet( pBt.pPager, iPtrmap, ref pDbPage );
890 if ( rc != SQLITE_OK )
891 {
892 pRC = rc;
893 return;
894 }
895 offset = (int)PTRMAP_PTROFFSET( iPtrmap, key );
896 if ( offset < 0 )
897 {
898 pRC = SQLITE_CORRUPT_BKPT();
899 goto ptrmap_exit;
900 }
901 Debug.Assert( offset <= (int)pBt.usableSize - 5 );
902 pPtrmap = sqlite3PagerGetData( pDbPage );
903  
904 if ( eType != pPtrmap[offset] || sqlite3Get4byte( pPtrmap, offset + 1 ) != parent )
905 {
906 TRACE( "PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent );
907 pRC = rc = sqlite3PagerWrite( pDbPage );
908 if ( rc == SQLITE_OK )
909 {
910 pPtrmap[offset] = eType;
911 sqlite3Put4byte( pPtrmap, offset + 1, parent );
912 }
913 }
914  
915 ptrmap_exit:
916 sqlite3PagerUnref( pDbPage );
917 }
918  
919 /*
920 ** Read an entry from the pointer map.
921 **
922 ** This routine retrieves the pointer map entry for page 'key', writing
923 ** the type and parent page number to pEType and pPgno respectively.
924 ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
925 */
926 static int ptrmapGet( BtShared pBt, Pgno key, ref u8 pEType, ref Pgno pPgno )
927 {
928 PgHdr pDbPage = new PgHdr();/* The pointer map page */
929 int iPtrmap; /* Pointer map page index */
930 u8[] pPtrmap; /* Pointer map page data */
931 int offset; /* Offset of entry in pointer map */
932 int rc;
933  
934 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
935  
936 iPtrmap = (int)PTRMAP_PAGENO( pBt, key );
937 rc = sqlite3PagerGet( pBt.pPager, (u32)iPtrmap, ref pDbPage );
938 if ( rc != 0 )
939 {
940 return rc;
941 }
942 pPtrmap = sqlite3PagerGetData( pDbPage );
943  
944 offset = (int)PTRMAP_PTROFFSET( (u32)iPtrmap, key );
945 if ( offset < 0 )
946 {
947 sqlite3PagerUnref( pDbPage );
948 return SQLITE_CORRUPT_BKPT();
949 }
950 Debug.Assert( offset <= (int)pBt.usableSize - 5 );
951 // Under C# pEType will always exist. No need to test; //
952 //Debug.Assert( pEType != 0 );
953 pEType = pPtrmap[offset];
954 // Under C# pPgno will always exist. No need to test; //
955 //if ( pPgno != 0 )
956 pPgno = sqlite3Get4byte( pPtrmap, offset + 1 );
957  
958 sqlite3PagerUnref( pDbPage );
959 if ( pEType < 1 || pEType > 5 )
960 return SQLITE_CORRUPT_BKPT();
961 return SQLITE_OK;
962 }
963  
964 #else //* if defined SQLITE_OMIT_AUTOVACUUM */
965 //#define ptrmapPut(w,x,y,z,rc)
966 //#define ptrmapGet(w,x,y,z) SQLITE_OK
967 //#define ptrmapPutOvflPtr(x, y, rc)
968 #endif
969  
970 /*
971 ** Given a btree page and a cell index (0 means the first cell on
972 ** the page, 1 means the second cell, and so forth) return a pointer
973 ** to the cell content.
974 **
975 ** This routine works only for pages that do not contain overflow cells.
976 */
977 //#define findCell(P,I) \
978 // ((P).aData + ((P).maskPage & get2byte((P).aData[(P).cellOffset+2*(I)])))
979 static int findCell( MemPage pPage, int iCell )
980 {
981 return get2byte( pPage.aData, pPage.cellOffset + 2 * ( iCell ) );
982 }
983  
984 //#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
985 static u8[] findCellv2( u8[] pPage, u16 iCell, u16 O, int I )
986 {
987 Debugger.Break();
988 return pPage;
989 }
990  
991  
992 /*
993 ** This a more complex version of findCell() that works for
994 ** pages that do contain overflow cells.
995 */
996 static int findOverflowCell( MemPage pPage, int iCell )
997 {
998 int i;
999 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1000 for ( i = pPage.nOverflow - 1; i >= 0; i-- )
1001 {
1002 int k;
1003 _OvflCell pOvfl;
1004 pOvfl = pPage.aOvfl[i];
1005 k = pOvfl.idx;
1006 if ( k <= iCell )
1007 {
1008 if ( k == iCell )
1009 {
1010 //return pOvfl.pCell;
1011 return -i - 1; // Negative Offset means overflow cells
1012 }
1013 iCell--;
1014 }
1015 }
1016 return findCell( pPage, iCell );
1017 }
1018  
1019 /*
1020 ** Parse a cell content block and fill in the CellInfo structure. There
1021 ** are two versions of this function. btreeParseCell() takes a
1022 ** cell index as the second argument and btreeParseCellPtr()
1023 ** takes a pointer to the body of the cell as its second argument.
1024 **
1025 ** Within this file, the parseCell() macro can be called instead of
1026 ** btreeParseCellPtr(). Using some compilers, this will be faster.
1027 */
1028 //OVERLOADS
1029 static void btreeParseCellPtr(
1030 MemPage pPage, /* Page containing the cell */
1031 int iCell, /* Pointer to the cell text. */
1032 ref CellInfo pInfo /* Fill in this structure */
1033 )
1034 {
1035 btreeParseCellPtr( pPage, pPage.aData, iCell, ref pInfo );
1036 }
1037 static void btreeParseCellPtr(
1038 MemPage pPage, /* Page containing the cell */
1039 byte[] pCell, /* The actual data */
1040 ref CellInfo pInfo /* Fill in this structure */
1041 )
1042 {
1043 btreeParseCellPtr( pPage, pCell, 0, ref pInfo );
1044 }
1045 static void btreeParseCellPtr(
1046 MemPage pPage, /* Page containing the cell */
1047 u8[] pCell, /* Pointer to the cell text. */
1048 int iCell, /* Pointer to the cell text. */
1049 ref CellInfo pInfo /* Fill in this structure */
1050 )
1051 {
1052 u16 n; /* Number bytes in cell content header */
1053 u32 nPayload = 0; /* Number of bytes of cell payload */
1054  
1055 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1056  
1057 if ( pInfo.pCell != pCell )
1058 pInfo.pCell = pCell;
1059 pInfo.iCell = iCell;
1060 Debug.Assert( pPage.leaf == 0 || pPage.leaf == 1 );
1061 n = pPage.childPtrSize;
1062 Debug.Assert( n == 4 - 4 * pPage.leaf );
1063 if ( pPage.intKey != 0 )
1064 {
1065 if ( pPage.hasData != 0 )
1066 {
1067 n += (u16)getVarint32( pCell, iCell + n, out nPayload );
1068 }
1069 else
1070 {
1071 nPayload = 0;
1072 }
1073 n += (u16)getVarint( pCell, iCell + n, out pInfo.nKey );
1074 pInfo.nData = nPayload;
1075 }
1076 else
1077 {
1078 pInfo.nData = 0;
1079 n += (u16)getVarint32( pCell, iCell + n, out nPayload );
1080 pInfo.nKey = nPayload;
1081 }
1082 pInfo.nPayload = nPayload;
1083 pInfo.nHeader = n;
1084 testcase( nPayload == pPage.maxLocal );
1085 testcase( nPayload == pPage.maxLocal + 1 );
1086 if ( likely( nPayload <= pPage.maxLocal ) )
1087 {
1088 /* This is the (easy) common case where the entire payload fits
1089 ** on the local page. No overflow is required.
1090 */
1091 if ( ( pInfo.nSize = (u16)( n + nPayload ) ) < 4 )
1092 pInfo.nSize = 4;
1093 pInfo.nLocal = (u16)nPayload;
1094 pInfo.iOverflow = 0;
1095 }
1096 else
1097 {
1098 /* If the payload will not fit completely on the local page, we have
1099 ** to decide how much to store locally and how much to spill onto
1100 ** overflow pages. The strategy is to minimize the amount of unused
1101 ** space on overflow pages while keeping the amount of local storage
1102 ** in between minLocal and maxLocal.
1103 **
1104 ** Warning: changing the way overflow payload is distributed in any
1105 ** way will result in an incompatible file format.
1106 */
1107 int minLocal; /* Minimum amount of payload held locally */
1108 int maxLocal; /* Maximum amount of payload held locally */
1109 int surplus; /* Overflow payload available for local storage */
1110  
1111 minLocal = pPage.minLocal;
1112 maxLocal = pPage.maxLocal;
1113 surplus = (int)( minLocal + ( nPayload - minLocal ) % ( pPage.pBt.usableSize - 4 ) );
1114 testcase( surplus == maxLocal );
1115 testcase( surplus == maxLocal + 1 );
1116 if ( surplus <= maxLocal )
1117 {
1118 pInfo.nLocal = (u16)surplus;
1119 }
1120 else
1121 {
1122 pInfo.nLocal = (u16)minLocal;
1123 }
1124 pInfo.iOverflow = (u16)( pInfo.nLocal + n );
1125 pInfo.nSize = (u16)( pInfo.iOverflow + 4 );
1126 }
1127 }
1128 //#define parseCell(pPage, iCell, pInfo) \
1129 // btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
1130 static void parseCell( MemPage pPage, int iCell, ref CellInfo pInfo )
1131 {
1132 btreeParseCellPtr( pPage, findCell( pPage, iCell ), ref pInfo );
1133 }
1134  
1135 static void btreeParseCell(
1136 MemPage pPage, /* Page containing the cell */
1137 int iCell, /* The cell index. First cell is 0 */
1138 ref CellInfo pInfo /* Fill in this structure */
1139 )
1140 {
1141 parseCell( pPage, iCell, ref pInfo );
1142 }
1143  
1144 /*
1145 ** Compute the total number of bytes that a Cell needs in the cell
1146 ** data area of the btree-page. The return number includes the cell
1147 ** data header and the local payload, but not any overflow page or
1148 ** the space used by the cell pointer.
1149 */
1150 // Alternative form for C#
1151 static u16 cellSizePtr( MemPage pPage, int iCell )
1152 {
1153 CellInfo info = new CellInfo();
1154 byte[] pCell = new byte[13];
1155 // Minimum Size = (2 bytes of Header or (4) Child Pointer) + (maximum of) 9 bytes data
1156 if ( iCell < 0 )// Overflow Cell
1157 Buffer.BlockCopy( pPage.aOvfl[-( iCell + 1 )].pCell, 0, pCell, 0, pCell.Length < pPage.aOvfl[-( iCell + 1 )].pCell.Length ? pCell.Length : pPage.aOvfl[-( iCell + 1 )].pCell.Length );
1158 else if ( iCell >= pPage.aData.Length + 1 - pCell.Length )
1159 Buffer.BlockCopy( pPage.aData, iCell, pCell, 0, pPage.aData.Length - iCell );
1160 else
1161 Buffer.BlockCopy( pPage.aData, iCell, pCell, 0, pCell.Length );
1162 btreeParseCellPtr( pPage, pCell, ref info );
1163 return info.nSize;
1164 }
1165  
1166 // Alternative form for C#
1167 static u16 cellSizePtr( MemPage pPage, byte[] pCell, int offset )
1168 {
1169 CellInfo info = new CellInfo();
1170 info.pCell = sqlite3Malloc( pCell.Length );
1171 Buffer.BlockCopy( pCell, offset, info.pCell, 0, pCell.Length - offset );
1172 btreeParseCellPtr( pPage, info.pCell, ref info );
1173 return info.nSize;
1174 }
1175  
1176 static u16 cellSizePtr( MemPage pPage, u8[] pCell )
1177 {
1178 int _pIter = pPage.childPtrSize; //u8 pIter = &pCell[pPage.childPtrSize];
1179 u32 nSize = 0;
1180  
1181 #if SQLITE_DEBUG || DEBUG
1182 /* The value returned by this function should always be the same as
1183 ** the (CellInfo.nSize) value found by doing a full parse of the
1184 ** cell. If SQLITE_DEBUG is defined, an Debug.Assert() at the bottom of
1185 ** this function verifies that this invariant is not violated. */
1186 CellInfo debuginfo = new CellInfo();
1187 btreeParseCellPtr( pPage, pCell, ref debuginfo );
1188 #else
1189 CellInfo debuginfo = new CellInfo();
1190 #endif
1191  
1192 if ( pPage.intKey != 0 )
1193 {
1194 int pEnd;
1195 if ( pPage.hasData != 0 )
1196 {
1197 _pIter += getVarint32( pCell, out nSize );// pIter += getVarint32( pIter, out nSize );
1198 }
1199 else
1200 {
1201 nSize = 0;
1202 }
1203  
1204 /* pIter now points at the 64-bit integer key value, a variable length
1205 ** integer. The following block moves pIter to point at the first byte
1206 ** past the end of the key value. */
1207 pEnd = _pIter + 9;//pEnd = &pIter[9];
1208 while ( ( ( pCell[_pIter++] ) & 0x80 ) != 0 && _pIter < pEnd )
1209 ;//while( (pIter++)&0x80 && pIter<pEnd );
1210 }
1211 else
1212 {
1213 _pIter += getVarint32( pCell, _pIter, out nSize ); //pIter += getVarint32( pIter, out nSize );
1214 }
1215  
1216 testcase( nSize == pPage.maxLocal );
1217 testcase( nSize == pPage.maxLocal + 1 );
1218 if ( nSize > pPage.maxLocal )
1219 {
1220 int minLocal = pPage.minLocal;
1221 nSize = (u32)( minLocal + ( nSize - minLocal ) % ( pPage.pBt.usableSize - 4 ) );
1222 testcase( nSize == pPage.maxLocal );
1223 testcase( nSize == pPage.maxLocal + 1 );
1224 if ( nSize > pPage.maxLocal )
1225 {
1226 nSize = (u32)minLocal;
1227 }
1228 nSize += 4;
1229 }
1230 nSize += (uint)_pIter;//nSize += (u32)(pIter - pCell);
1231  
1232 /* The minimum size of any cell is 4 bytes. */
1233 if ( nSize < 4 )
1234 {
1235 nSize = 4;
1236 }
1237  
1238 Debug.Assert( nSize == debuginfo.nSize );
1239 return (u16)nSize;
1240 }
1241  
1242 #if SQLITE_DEBUG
1243 /* This variation on cellSizePtr() is used inside of assert() statements
1244 ** only. */
1245 static u16 cellSize( MemPage pPage, int iCell )
1246 {
1247 return cellSizePtr( pPage, findCell( pPage, iCell ) );
1248 }
1249 #else
1250 static int cellSize(MemPage pPage, int iCell) { return -1; }
1251 #endif
1252  
1253 #if !SQLITE_OMIT_AUTOVACUUM
1254 /*
1255 ** If the cell pCell, part of page pPage contains a pointer
1256 ** to an overflow page, insert an entry into the pointer-map
1257 ** for the overflow page.
1258 */
1259 static void ptrmapPutOvflPtr( MemPage pPage, int pCell, ref int pRC )
1260 {
1261 if ( pRC != 0 )
1262 return;
1263 CellInfo info = new CellInfo();
1264 Debug.Assert( pCell != 0 );
1265 btreeParseCellPtr( pPage, pCell, ref info );
1266 Debug.Assert( ( info.nData + ( pPage.intKey != 0 ? 0 : info.nKey ) ) == info.nPayload );
1267 if ( info.iOverflow != 0 )
1268 {
1269 Pgno ovfl = sqlite3Get4byte( pPage.aData, pCell, info.iOverflow );
1270 ptrmapPut( pPage.pBt, ovfl, PTRMAP_OVERFLOW1, pPage.pgno, ref pRC );
1271 }
1272 }
1273  
1274 static void ptrmapPutOvflPtr( MemPage pPage, u8[] pCell, ref int pRC )
1275 {
1276 if ( pRC != 0 )
1277 return;
1278 CellInfo info = new CellInfo();
1279 Debug.Assert( pCell != null );
1280 btreeParseCellPtr( pPage, pCell, ref info );
1281 Debug.Assert( ( info.nData + ( pPage.intKey != 0 ? 0 : info.nKey ) ) == info.nPayload );
1282 if ( info.iOverflow != 0 )
1283 {
1284 Pgno ovfl = sqlite3Get4byte( pCell, info.iOverflow );
1285 ptrmapPut( pPage.pBt, ovfl, PTRMAP_OVERFLOW1, pPage.pgno, ref pRC );
1286 }
1287 }
1288 #endif
1289  
1290  
1291 /*
1292 ** Defragment the page given. All Cells are moved to the
1293 ** end of the page and all free space is collected into one
1294 ** big FreeBlk that occurs in between the header and cell
1295 ** pointer array and the cell content area.
1296 */
1297 static int defragmentPage( MemPage pPage )
1298 {
1299 int i; /* Loop counter */
1300 int pc; /* Address of a i-th cell */
1301 int addr; /* Offset of first byte after cell pointer array */
1302 int hdr; /* Offset to the page header */
1303 int size; /* Size of a cell */
1304 int usableSize; /* Number of usable bytes on a page */
1305 int cellOffset; /* Offset to the cell pointer array */
1306 int cbrk; /* Offset to the cell content area */
1307 int nCell; /* Number of cells on the page */
1308 byte[] data; /* The page data */
1309 byte[] temp; /* Temp area for cell content */
1310 int iCellFirst; /* First allowable cell index */
1311 int iCellLast; /* Last possible cell index */
1312  
1313  
1314 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1315 Debug.Assert( pPage.pBt != null );
1316 Debug.Assert( pPage.pBt.usableSize <= SQLITE_MAX_PAGE_SIZE );
1317 Debug.Assert( pPage.nOverflow == 0 );
1318 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1319 temp = sqlite3PagerTempSpace( pPage.pBt.pPager );
1320 data = pPage.aData;
1321 hdr = pPage.hdrOffset;
1322 cellOffset = pPage.cellOffset;
1323 nCell = pPage.nCell;
1324 Debug.Assert( nCell == get2byte( data, hdr + 3 ) );
1325 usableSize = (int)pPage.pBt.usableSize;
1326 cbrk = get2byte( data, hdr + 5 );
1327 Buffer.BlockCopy( data, cbrk, temp, cbrk, usableSize - cbrk );//memcpy( temp[cbrk], ref data[cbrk], usableSize - cbrk );
1328 cbrk = usableSize;
1329 iCellFirst = cellOffset + 2 * nCell;
1330 iCellLast = usableSize - 4;
1331 for ( i = 0; i < nCell; i++ )
1332 {
1333 int pAddr; /* The i-th cell pointer */
1334 pAddr = cellOffset + i * 2; // &data[cellOffset + i * 2];
1335 pc = get2byte( data, pAddr );
1336 testcase( pc == iCellFirst );
1337 testcase( pc == iCellLast );
1338 #if !SQLITE_ENABLE_OVERSIZE_CELL_CHECK
1339 /* These conditions have already been verified in btreeInitPage()
1340 ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
1341 */
1342 if ( pc < iCellFirst || pc > iCellLast )
1343 {
1344 return SQLITE_CORRUPT_BKPT();
1345 }
1346 #endif
1347 Debug.Assert( pc >= iCellFirst && pc <= iCellLast );
1348 size = cellSizePtr( pPage, temp, pc );
1349 cbrk -= size;
1350 #if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
1351 if ( cbrk < iCellFirst || pc + size > usableSize )
1352 {
1353 return SQLITE_CORRUPT_BKPT();
1354 }
1355 #else
1356 if ( cbrk < iCellFirst || pc + size > usableSize )
1357 {
1358 return SQLITE_CORRUPT_BKPT();
1359 }
1360 #endif
1361 Debug.Assert( cbrk + size <= usableSize && cbrk >= iCellFirst );
1362 testcase( cbrk + size == usableSize );
1363 testcase( pc + size == usableSize );
1364 Buffer.BlockCopy( temp, pc, data, cbrk, size );//memcpy(data[cbrk], ref temp[pc], size);
1365 put2byte( data, pAddr, cbrk );
1366 }
1367 Debug.Assert( cbrk >= iCellFirst );
1368 put2byte( data, hdr + 5, cbrk );
1369 data[hdr + 1] = 0;
1370 data[hdr + 2] = 0;
1371 data[hdr + 7] = 0;
1372 addr = cellOffset + 2 * nCell;
1373 Array.Clear( data, addr, cbrk - addr ); //memset(data[iCellFirst], 0, cbrk-iCellFirst);
1374 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1375 if ( cbrk - iCellFirst != pPage.nFree )
1376 {
1377 return SQLITE_CORRUPT_BKPT();
1378 }
1379 return SQLITE_OK;
1380 }
1381  
1382 /*
1383 ** Allocate nByte bytes of space from within the B-Tree page passed
1384 ** as the first argument. Write into pIdx the index into pPage.aData[]
1385 ** of the first byte of allocated space. Return either SQLITE_OK or
1386 ** an error code (usually SQLITE_CORRUPT).
1387 **
1388 ** The caller guarantees that there is sufficient space to make the
1389 ** allocation. This routine might need to defragment in order to bring
1390 ** all the space together, however. This routine will avoid using
1391 ** the first two bytes past the cell pointer area since presumably this
1392 ** allocation is being made in order to insert a new cell, so we will
1393 ** also end up needing a new cell pointer.
1394 */
1395 static int allocateSpace( MemPage pPage, int nByte, ref int pIdx )
1396 {
1397 int hdr = pPage.hdrOffset; /* Local cache of pPage.hdrOffset */
1398 u8[] data = pPage.aData; /* Local cache of pPage.aData */
1399 int nFrag; /* Number of fragmented bytes on pPage */
1400 int top; /* First byte of cell content area */
1401 int gap; /* First byte of gap between cell pointers and cell content */
1402 int rc; /* Integer return code */
1403 u32 usableSize; /* Usable size of the page */
1404  
1405 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1406 Debug.Assert( pPage.pBt != null );
1407 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1408 Debug.Assert( nByte >= 0 ); /* Minimum cell size is 4 */
1409 Debug.Assert( pPage.nFree >= nByte );
1410 Debug.Assert( pPage.nOverflow == 0 );
1411 usableSize = pPage.pBt.usableSize;
1412 Debug.Assert( nByte < usableSize - 8 );
1413  
1414 nFrag = data[hdr + 7];
1415 Debug.Assert( pPage.cellOffset == hdr + 12 - 4 * pPage.leaf );
1416 gap = pPage.cellOffset + 2 * pPage.nCell;
1417 top = get2byteNotZero( data, hdr + 5 );
1418 if ( gap > top )
1419 return SQLITE_CORRUPT_BKPT();
1420 testcase( gap + 2 == top );
1421 testcase( gap + 1 == top );
1422 testcase( gap == top );
1423  
1424 if ( nFrag >= 60 )
1425 {
1426 /* Always defragment highly fragmented pages */
1427 rc = defragmentPage( pPage );
1428 if ( rc != 0 )
1429 return rc;
1430 top = get2byteNotZero( data, hdr + 5 );
1431 }
1432 else if ( gap + 2 <= top )
1433 {
1434 /* Search the freelist looking for a free slot big enough to satisfy
1435 ** the request. The allocation is made from the first free slot in
1436 ** the list that is large enough to accomadate it.
1437 */
1438 int pc, addr;
1439 for ( addr = hdr + 1; ( pc = get2byte( data, addr ) ) > 0; addr = pc )
1440 {
1441 int size; /* Size of free slot */
1442 if ( pc > usableSize - 4 || pc < addr + 4 )
1443 {
1444 return SQLITE_CORRUPT_BKPT();
1445 }
1446 size = get2byte( data, pc + 2 );
1447 if ( size >= nByte )
1448 {
1449 int x = size - nByte;
1450 testcase( x == 4 );
1451 testcase( x == 3 );
1452 if ( x < 4 )
1453 {
1454 /* Remove the slot from the free-list. Update the number of
1455 ** fragmented bytes within the page. */
1456 data[addr + 0] = data[pc + 0];
1457 data[addr + 1] = data[pc + 1]; //memcpy( data[addr], ref data[pc], 2 );
1458 data[hdr + 7] = (u8)( nFrag + x );
1459 }
1460 else if ( size + pc > usableSize )
1461 {
1462 return SQLITE_CORRUPT_BKPT();
1463 }
1464 else
1465 {
1466 /* The slot remains on the free-list. Reduce its size to account
1467 ** for the portion used by the new allocation. */
1468 put2byte( data, pc + 2, x );
1469 }
1470 pIdx = pc + x;
1471 return SQLITE_OK;
1472 }
1473 }
1474 }
1475  
1476 /* Check to make sure there is enough space in the gap to satisfy
1477 ** the allocation. If not, defragment.
1478 */
1479 testcase( gap + 2 + nByte == top );
1480 if ( gap + 2 + nByte > top )
1481 {
1482 rc = defragmentPage( pPage );
1483 if ( rc != 0 )
1484 return rc;
1485 top = get2byteNotZero( data, hdr + 5 );
1486 Debug.Assert( gap + nByte <= top );
1487 }
1488  
1489  
1490 /* Allocate memory from the gap in between the cell pointer array
1491 ** and the cell content area. The btreeInitPage() call has already
1492 ** validated the freelist. Given that the freelist is valid, there
1493 ** is no way that the allocation can extend off the end of the page.
1494 ** The Debug.Assert() below verifies the previous sentence.
1495 */
1496 top -= nByte;
1497 put2byte( data, hdr + 5, top );
1498 Debug.Assert( top + nByte <= (int)pPage.pBt.usableSize );
1499 pIdx = top;
1500 return SQLITE_OK;
1501 }
1502  
1503 /*
1504 ** Return a section of the pPage.aData to the freelist.
1505 ** The first byte of the new free block is pPage.aDisk[start]
1506 ** and the size of the block is "size" bytes.
1507 **
1508 ** Most of the effort here is involved in coalesing adjacent
1509 ** free blocks into a single big free block.
1510 */
1511 static int freeSpace( MemPage pPage, u32 start, int size )
1512 {
1513 return freeSpace( pPage, (int)start, size );
1514 }
1515 static int freeSpace( MemPage pPage, int start, int size )
1516 {
1517 int addr, pbegin, hdr;
1518 int iLast; /* Largest possible freeblock offset */
1519 byte[] data = pPage.aData;
1520  
1521 Debug.Assert( pPage.pBt != null );
1522 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1523 Debug.Assert( start >= pPage.hdrOffset + 6 + pPage.childPtrSize );
1524 Debug.Assert( ( start + size ) <= (int)pPage.pBt.usableSize );
1525 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1526 Debug.Assert( size >= 0 ); /* Minimum cell size is 4 */
1527  
1528 if ( pPage.pBt.secureDelete )
1529 {
1530 /* Overwrite deleted information with zeros when the secure_delete
1531 ** option is enabled */
1532 Array.Clear( data, start, size );// memset(&data[start], 0, size);
1533 }
1534  
1535 /* Add the space back into the linked list of freeblocks. Note that
1536 ** even though the freeblock list was checked by btreeInitPage(),
1537 ** btreeInitPage() did not detect overlapping cells or
1538 ** freeblocks that overlapped cells. Nor does it detect when the
1539 ** cell content area exceeds the value in the page header. If these
1540 ** situations arise, then subsequent insert operations might corrupt
1541 ** the freelist. So we do need to check for corruption while scanning
1542 ** the freelist.
1543 */
1544 hdr = pPage.hdrOffset;
1545 addr = hdr + 1;
1546 iLast = (int)pPage.pBt.usableSize - 4;
1547 Debug.Assert( start <= iLast );
1548 while ( ( pbegin = get2byte( data, addr ) ) < start && pbegin > 0 )
1549 {
1550 if ( pbegin < addr + 4 )
1551 {
1552 return SQLITE_CORRUPT_BKPT();
1553 }
1554 addr = pbegin;
1555 }
1556 if ( pbegin > iLast )
1557 {
1558 return SQLITE_CORRUPT_BKPT();
1559 }
1560 Debug.Assert( pbegin > addr || pbegin == 0 );
1561 put2byte( data, addr, start );
1562 put2byte( data, start, pbegin );
1563 put2byte( data, start + 2, size );
1564 pPage.nFree = (u16)( pPage.nFree + size );
1565  
1566 /* Coalesce adjacent free blocks */
1567 addr = hdr + 1;
1568 while ( ( pbegin = get2byte( data, addr ) ) > 0 )
1569 {
1570 int pnext, psize, x;
1571 Debug.Assert( pbegin > addr );
1572 Debug.Assert( pbegin <= (int)pPage.pBt.usableSize - 4 );
1573 pnext = get2byte( data, pbegin );
1574 psize = get2byte( data, pbegin + 2 );
1575 if ( pbegin + psize + 3 >= pnext && pnext > 0 )
1576 {
1577 int frag = pnext - ( pbegin + psize );
1578 if ( ( frag < 0 ) || ( frag > (int)data[hdr + 7] ) )
1579 {
1580 return SQLITE_CORRUPT_BKPT();
1581 }
1582 data[hdr + 7] -= (u8)frag;
1583 x = get2byte( data, pnext );
1584 put2byte( data, pbegin, x );
1585 x = pnext + get2byte( data, pnext + 2 ) - pbegin;
1586 put2byte( data, pbegin + 2, x );
1587 }
1588 else
1589 {
1590 addr = pbegin;
1591 }
1592 }
1593  
1594 /* If the cell content area begins with a freeblock, remove it. */
1595 if ( data[hdr + 1] == data[hdr + 5] && data[hdr + 2] == data[hdr + 6] )
1596 {
1597 int top;
1598 pbegin = get2byte( data, hdr + 1 );
1599 put2byte( data, hdr + 1, get2byte( data, pbegin ) ); //memcpy( data[hdr + 1], ref data[pbegin], 2 );
1600 top = get2byte( data, hdr + 5 ) + get2byte( data, pbegin + 2 );
1601 put2byte( data, hdr + 5, top );
1602 }
1603 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1604 return SQLITE_OK;
1605 }
1606  
1607 /*
1608 ** Decode the flags byte (the first byte of the header) for a page
1609 ** and initialize fields of the MemPage structure accordingly.
1610 **
1611 ** Only the following combinations are supported. Anything different
1612 ** indicates a corrupt database files:
1613 **
1614 ** PTF_ZERODATA
1615 ** PTF_ZERODATA | PTF_LEAF
1616 ** PTF_LEAFDATA | PTF_INTKEY
1617 ** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
1618 */
1619 static int decodeFlags( MemPage pPage, int flagByte )
1620 {
1621 BtShared pBt; /* A copy of pPage.pBt */
1622  
1623 Debug.Assert( pPage.hdrOffset == ( pPage.pgno == 1 ? 100 : 0 ) );
1624 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1625 pPage.leaf = (u8)( flagByte >> 3 );
1626 Debug.Assert( PTF_LEAF == 1 << 3 );
1627 flagByte &= ~PTF_LEAF;
1628 pPage.childPtrSize = (u8)( 4 - 4 * pPage.leaf );
1629 pBt = pPage.pBt;
1630 if ( flagByte == ( PTF_LEAFDATA | PTF_INTKEY ) )
1631 {
1632 pPage.intKey = 1;
1633 pPage.hasData = pPage.leaf;
1634 pPage.maxLocal = pBt.maxLeaf;
1635 pPage.minLocal = pBt.minLeaf;
1636 }
1637 else if ( flagByte == PTF_ZERODATA )
1638 {
1639 pPage.intKey = 0;
1640 pPage.hasData = 0;
1641 pPage.maxLocal = pBt.maxLocal;
1642 pPage.minLocal = pBt.minLocal;
1643 }
1644 else
1645 {
1646 return SQLITE_CORRUPT_BKPT();
1647 }
1648 return SQLITE_OK;
1649 }
1650  
1651 /*
1652 ** Initialize the auxiliary information for a disk block.
1653 **
1654 ** Return SQLITE_OK on success. If we see that the page does
1655 ** not contain a well-formed database page, then return
1656 ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
1657 ** guarantee that the page is well-formed. It only shows that
1658 ** we failed to detect any corruption.
1659 */
1660 static int btreeInitPage( MemPage pPage )
1661 {
1662  
1663 Debug.Assert( pPage.pBt != null );
1664 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1665 Debug.Assert( pPage.pgno == sqlite3PagerPagenumber( pPage.pDbPage ) );
1666 Debug.Assert( pPage == sqlite3PagerGetExtra( pPage.pDbPage ) );
1667 Debug.Assert( pPage.aData == sqlite3PagerGetData( pPage.pDbPage ) );
1668  
1669 if ( 0 == pPage.isInit )
1670 {
1671 u16 pc; /* Address of a freeblock within pPage.aData[] */
1672 u8 hdr; /* Offset to beginning of page header */
1673 u8[] data; /* Equal to pPage.aData */
1674 BtShared pBt; /* The main btree structure */
1675 int usableSize; /* Amount of usable space on each page */
1676 u16 cellOffset; /* Offset from start of page to first cell pointer */
1677 int nFree; /* Number of unused bytes on the page */
1678 int top; /* First byte of the cell content area */
1679 int iCellFirst; /* First allowable cell or freeblock offset */
1680 int iCellLast; /* Last possible cell or freeblock offset */
1681  
1682 pBt = pPage.pBt;
1683  
1684 hdr = pPage.hdrOffset;
1685 data = pPage.aData;
1686 if ( decodeFlags( pPage, data[hdr] ) != 0 )
1687 return SQLITE_CORRUPT_BKPT();
1688 Debug.Assert( pBt.pageSize >= 512 && pBt.pageSize <= 65536 );
1689 pPage.maskPage = (u16)( pBt.pageSize - 1 );
1690 pPage.nOverflow = 0;
1691 usableSize = (int)pBt.usableSize;
1692 pPage.cellOffset = ( cellOffset = (u16)( hdr + 12 - 4 * pPage.leaf ) );
1693 top = get2byteNotZero( data, hdr + 5 );
1694 pPage.nCell = (u16)( get2byte( data, hdr + 3 ) );
1695 if ( pPage.nCell > MX_CELL( pBt ) )
1696 {
1697 /* To many cells for a single page. The page must be corrupt */
1698 return SQLITE_CORRUPT_BKPT();
1699 }
1700 testcase( pPage.nCell == MX_CELL( pBt ) );
1701  
1702 /* A malformed database page might cause us to read past the end
1703 ** of page when parsing a cell.
1704 **
1705 ** The following block of code checks early to see if a cell extends
1706 ** past the end of a page boundary and causes SQLITE_CORRUPT to be
1707 ** returned if it does.
1708 */
1709 iCellFirst = cellOffset + 2 * pPage.nCell;
1710 iCellLast = usableSize - 4;
1711 #if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
1712 {
1713 int i; /* Index into the cell pointer array */
1714 int sz; /* Size of a cell */
1715  
1716 if ( 0 == pPage.leaf )
1717 iCellLast--;
1718 for ( i = 0; i < pPage.nCell; i++ )
1719 {
1720 pc = (u16)get2byte( data, cellOffset + i * 2 );
1721 testcase( pc == iCellFirst );
1722 testcase( pc == iCellLast );
1723 if ( pc < iCellFirst || pc > iCellLast )
1724 {
1725 return SQLITE_CORRUPT_BKPT();
1726 }
1727 sz = cellSizePtr( pPage, data, pc );
1728 testcase( pc + sz == usableSize );
1729 if ( pc + sz > usableSize )
1730 {
1731 return SQLITE_CORRUPT_BKPT();
1732 }
1733 }
1734 if ( 0 == pPage.leaf )
1735 iCellLast++;
1736 }
1737 #endif
1738  
1739 /* Compute the total free space on the page */
1740 pc = (u16)get2byte( data, hdr + 1 );
1741 nFree = (u16)( data[hdr + 7] + top );
1742 while ( pc > 0 )
1743 {
1744 u16 next, size;
1745 if ( pc < iCellFirst || pc > iCellLast )
1746 {
1747 /* Start of free block is off the page */
1748 return SQLITE_CORRUPT_BKPT();
1749 }
1750 next = (u16)get2byte( data, pc );
1751 size = (u16)get2byte( data, pc + 2 );
1752 if ( ( next > 0 && next <= pc + size + 3 ) || pc + size > usableSize )
1753 {
1754 /* Free blocks must be in ascending order. And the last byte of
1755 ** the free-block must lie on the database page. */
1756 return SQLITE_CORRUPT_BKPT();
1757 }
1758 nFree = (u16)( nFree + size );
1759 pc = next;
1760 }
1761  
1762 /* At this point, nFree contains the sum of the offset to the start
1763 ** of the cell-content area plus the number of free bytes within
1764 ** the cell-content area. If this is greater than the usable-size
1765 ** of the page, then the page must be corrupted. This check also
1766 ** serves to verify that the offset to the start of the cell-content
1767 ** area, according to the page header, lies within the page.
1768 */
1769 if ( nFree > usableSize )
1770 {
1771 return SQLITE_CORRUPT_BKPT();
1772 }
1773 pPage.nFree = (u16)( nFree - iCellFirst );
1774 pPage.isInit = 1;
1775 }
1776 return SQLITE_OK;
1777 }
1778  
1779 /*
1780 ** Set up a raw page so that it looks like a database page holding
1781 ** no entries.
1782 */
1783 static void zeroPage( MemPage pPage, int flags )
1784 {
1785 byte[] data = pPage.aData;
1786 BtShared pBt = pPage.pBt;
1787 u8 hdr = pPage.hdrOffset;
1788 u16 first;
1789  
1790 Debug.Assert( sqlite3PagerPagenumber( pPage.pDbPage ) == pPage.pgno );
1791 Debug.Assert( sqlite3PagerGetExtra( pPage.pDbPage ) == pPage );
1792 Debug.Assert( sqlite3PagerGetData( pPage.pDbPage ) == data );
1793 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
1794 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
1795 if ( pBt.secureDelete )
1796 {
1797 Array.Clear( data, hdr, (int)( pBt.usableSize - hdr ) );//memset(&data[hdr], 0, pBt->usableSize - hdr);
1798 }
1799  
1800 data[hdr] = (u8)flags;
1801 first = (u16)( hdr + 8 + 4 * ( ( flags & PTF_LEAF ) == 0 ? 1 : 0 ) );
1802 Array.Clear( data, hdr + 1, 4 );//memset(data[hdr+1], 0, 4);
1803 data[hdr + 7] = 0;
1804 put2byte( data, hdr + 5, pBt.usableSize );
1805 pPage.nFree = (u16)( pBt.usableSize - first );
1806 decodeFlags( pPage, flags );
1807 pPage.hdrOffset = hdr;
1808 pPage.cellOffset = first;
1809 pPage.nOverflow = 0;
1810 Debug.Assert( pBt.pageSize >= 512 && pBt.pageSize <= 65536 );
1811 pPage.maskPage = (u16)( pBt.pageSize - 1 );
1812 pPage.nCell = 0;
1813 pPage.isInit = 1;
1814 }
1815  
1816  
1817 /*
1818 ** Convert a DbPage obtained from the pager into a MemPage used by
1819 ** the btree layer.
1820 */
1821 static MemPage btreePageFromDbPage( DbPage pDbPage, Pgno pgno, BtShared pBt )
1822 {
1823 MemPage pPage = (MemPage)sqlite3PagerGetExtra( pDbPage );
1824 pPage.aData = sqlite3PagerGetData( pDbPage );
1825 pPage.pDbPage = pDbPage;
1826 pPage.pBt = pBt;
1827 pPage.pgno = pgno;
1828 pPage.hdrOffset = (u8)( pPage.pgno == 1 ? 100 : 0 );
1829 return pPage;
1830 }
1831  
1832 /*
1833 ** Get a page from the pager. Initialize the MemPage.pBt and
1834 ** MemPage.aData elements if needed.
1835 **
1836 ** If the noContent flag is set, it means that we do not care about
1837 ** the content of the page at this time. So do not go to the disk
1838 ** to fetch the content. Just fill in the content with zeros for now.
1839 ** If in the future we call sqlite3PagerWrite() on this page, that
1840 ** means we have started to be concerned about content and the disk
1841 ** read should occur at that point.
1842 */
1843 static int btreeGetPage(
1844 BtShared pBt, /* The btree */
1845 Pgno pgno, /* Number of the page to fetch */
1846 ref MemPage ppPage, /* Return the page in this parameter */
1847 int noContent /* Do not load page content if true */
1848 )
1849 {
1850 int rc;
1851 DbPage pDbPage = null;
1852  
1853 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
1854 rc = sqlite3PagerAcquire( pBt.pPager, pgno, ref pDbPage, (u8)noContent );
1855 if ( rc != 0 )
1856 return rc;
1857 ppPage = btreePageFromDbPage( pDbPage, pgno, pBt );
1858 return SQLITE_OK;
1859 }
1860  
1861 /*
1862 ** Retrieve a page from the pager cache. If the requested page is not
1863 ** already in the pager cache return NULL. Initialize the MemPage.pBt and
1864 ** MemPage.aData elements if needed.
1865 */
1866 static MemPage btreePageLookup( BtShared pBt, Pgno pgno )
1867 {
1868 DbPage pDbPage;
1869 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
1870 pDbPage = sqlite3PagerLookup( pBt.pPager, pgno );
1871 if ( pDbPage )
1872 {
1873 return btreePageFromDbPage( pDbPage, pgno, pBt );
1874 }
1875 return null;
1876 }
1877  
1878 /*
1879 ** Return the size of the database file in pages. If there is any kind of
1880 ** error, return ((unsigned int)-1).
1881 */
1882 static Pgno btreePagecount( BtShared pBt )
1883 {
1884 return pBt.nPage;
1885 }
1886 static Pgno sqlite3BtreeLastPage( Btree p )
1887 {
1888 Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
1889 Debug.Assert( ( ( p.pBt.nPage ) & 0x8000000 ) == 0 );
1890 return (Pgno)btreePagecount( p.pBt );
1891 }
1892  
1893  
1894  
1895 /*
1896 ** Get a page from the pager and initialize it. This routine is just a
1897 ** convenience wrapper around separate calls to btreeGetPage() and
1898 ** btreeInitPage().
1899 **
1900 ** If an error occurs, then the value ppPage is set to is undefined. It
1901 ** may remain unchanged, or it may be set to an invalid value.
1902 */
1903 static int getAndInitPage(
1904 BtShared pBt, /* The database file */
1905 Pgno pgno, /* Number of the page to get */
1906 ref MemPage ppPage /* Write the page pointer here */
1907 )
1908 {
1909 int rc;
1910 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
1911  
1912 if ( pgno > btreePagecount( pBt ) )
1913 {
1914 rc = SQLITE_CORRUPT_BKPT();
1915 }
1916 else
1917 {
1918 rc = btreeGetPage( pBt, pgno, ref ppPage, 0 );
1919 if ( rc == SQLITE_OK )
1920 {
1921 rc = btreeInitPage( ppPage );
1922 if ( rc != SQLITE_OK )
1923 {
1924 releasePage( ppPage );
1925 }
1926 }
1927 }
1928  
1929 testcase( pgno == 0 );
1930 Debug.Assert( pgno != 0 || rc == SQLITE_CORRUPT );
1931  
1932 return rc;
1933 }
1934  
1935 /*
1936 ** Release a MemPage. This should be called once for each prior
1937 ** call to btreeGetPage.
1938 */
1939 static void releasePage( MemPage pPage )
1940 {
1941 if ( pPage != null )
1942 {
1943 Debug.Assert( pPage.aData != null );
1944 Debug.Assert( pPage.pBt != null );
1945 //TODO -- find out why corrupt9 & diskfull fail on this tests
1946 //Debug.Assert( sqlite3PagerGetExtra( pPage.pDbPage ) == pPage );
1947 //Debug.Assert( sqlite3PagerGetData( pPage.pDbPage ) == pPage.aData );
1948 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1949 sqlite3PagerUnref( pPage.pDbPage );
1950 }
1951 }
1952  
1953 /*
1954 ** During a rollback, when the pager reloads information into the cache
1955 ** so that the cache is restored to its original state at the start of
1956 ** the transaction, for each page restored this routine is called.
1957 **
1958 ** This routine needs to reset the extra data section at the end of the
1959 ** page to agree with the restored data.
1960 */
1961 static void pageReinit( DbPage pData )
1962 {
1963 MemPage pPage;
1964 pPage = sqlite3PagerGetExtra( pData );
1965 Debug.Assert( sqlite3PagerPageRefcount( pData ) > 0 );
1966 if ( pPage.isInit != 0 )
1967 {
1968 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
1969 pPage.isInit = 0;
1970 if ( sqlite3PagerPageRefcount( pData ) > 1 )
1971 {
1972 /* pPage might not be a btree page; it might be an overflow page
1973 ** or ptrmap page or a free page. In those cases, the following
1974 ** call to btreeInitPage() will likely return SQLITE_CORRUPT.
1975 ** But no harm is done by this. And it is very important that
1976 ** btreeInitPage() be called on every btree page so we make
1977 ** the call for every page that comes in for re-initing. */
1978 btreeInitPage( pPage );
1979 }
1980 }
1981 }
1982  
1983 /*
1984 ** Invoke the busy handler for a btree.
1985 */
1986 static int btreeInvokeBusyHandler( object pArg )
1987 {
1988 BtShared pBt = (BtShared)pArg;
1989 Debug.Assert( pBt.db != null );
1990 Debug.Assert( sqlite3_mutex_held( pBt.db.mutex ) );
1991 return sqlite3InvokeBusyHandler( pBt.db.busyHandler );
1992 }
1993  
1994 /*
1995 ** Open a database file.
1996 **
1997 ** zFilename is the name of the database file. If zFilename is NULL
1998 ** then an ephemeral database is created. The ephemeral database might
1999 ** be exclusively in memory, or it might use a disk-based memory cache.
2000 ** Either way, the ephemeral database will be automatically deleted
2001 ** when sqlite3BtreeClose() is called.
2002 **
2003 ** If zFilename is ":memory:" then an in-memory database is created
2004 ** that is automatically destroyed when it is closed.
2005 **
2006 ** The "flags" parameter is a bitmask that might contain bits
2007 ** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK
2008 ** bit is also set if the SQLITE_NoReadlock flags is set in db->flags.
2009 ** These flags are passed through into sqlite3PagerOpen() and must
2010 ** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK.
2011 **
2012 ** If the database is already opened in the same database connection
2013 ** and we are in shared cache mode, then the open will fail with an
2014 ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared
2015 ** objects in the same database connection since doing so will lead
2016 ** to problems with locking.
2017 */
2018 static int sqlite3BtreeOpen(
2019 sqlite3_vfs pVfs, /* VFS to use for this b-tree */
2020 string zFilename, /* Name of the file containing the BTree database */
2021 sqlite3 db, /* Associated database handle */
2022 ref Btree ppBtree, /* Pointer to new Btree object written here */
2023 int flags, /* Options */
2024 int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
2025 )
2026 {
2027 BtShared pBt = null; /* Shared part of btree structure */
2028 Btree p; /* Handle to return */
2029 sqlite3_mutex mutexOpen = null; /* Prevents a race condition. Ticket #3537 */
2030 int rc = SQLITE_OK; /* Result code from this function */
2031 u8 nReserve; /* Byte of unused space on each page */
2032 byte[] zDbHeader = new byte[100]; /* Database header content */
2033  
2034 /* True if opening an ephemeral, temporary database */
2035 bool isTempDb = string.IsNullOrEmpty( zFilename );//zFilename==0 || zFilename[0]==0;
2036  
2037 /* Set the variable isMemdb to true for an in-memory database, or
2038 ** false for a file-based database.
2039 */
2040 #if SQLITE_OMIT_MEMORYDB
2041 bool isMemdb = false;
2042 #else
2043 bool isMemdb = ( zFilename == ":memory:" )
2044 || ( isTempDb && sqlite3TempInMemory( db ) );
2045  
2046 #endif
2047  
2048 Debug.Assert( db != null );
2049 Debug.Assert( pVfs != null );
2050 Debug.Assert( sqlite3_mutex_held( db.mutex ) );
2051 Debug.Assert( ( flags & 0xff ) == flags ); /* flags fit in 8 bits */
2052  
2053 /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
2054 Debug.Assert( ( flags & BTREE_UNORDERED ) == 0 || ( flags & BTREE_SINGLE ) != 0 );
2055  
2056 /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
2057 Debug.Assert( ( flags & BTREE_SINGLE ) == 0 || isTempDb );
2058  
2059 if ( ( db.flags & SQLITE_NoReadlock ) != 0 )
2060 {
2061 flags |= BTREE_NO_READLOCK;
2062 }
2063 if ( isMemdb )
2064 {
2065 flags |= BTREE_MEMORY;
2066 }
2067 if ( ( vfsFlags & SQLITE_OPEN_MAIN_DB ) != 0 && ( isMemdb || isTempDb ) )
2068 {
2069 vfsFlags = ( vfsFlags & ~SQLITE_OPEN_MAIN_DB ) | SQLITE_OPEN_TEMP_DB;
2070 }
2071  
2072 p = new Btree();//sqlite3MallocZero(sizeof(Btree));
2073 //if( !p ){
2074 // return SQLITE_NOMEM;
2075 //}
2076 p.inTrans = TRANS_NONE;
2077 p.db = db;
2078 #if !SQLITE_OMIT_SHARED_CACHE
2079 p.lock.pBtree = p;
2080 p.lock.iTable = 1;
2081 #endif
2082  
2083 #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
2084 /*
2085 ** If this Btree is a candidate for shared cache, try to find an
2086 ** existing BtShared object that we can share with
2087 */
2088 if( !isMemdb && !isTempDb ){
2089 if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
2090 int nFullPathname = pVfs.mxPathname+1;
2091 string zFullPathname = sqlite3Malloc(nFullPathname);
2092 sqlite3_mutex *mutexShared;
2093 p.sharable = 1;
2094 if( !zFullPathname ){
2095 p = null;//sqlite3_free(ref p);
2096 return SQLITE_NOMEM;
2097 }
2098 sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
2099 mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
2100 sqlite3_mutex_enter(mutexOpen);
2101 mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
2102 sqlite3_mutex_enter(mutexShared);
2103 for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt.pNext){
2104 Debug.Assert( pBt.nRef>0 );
2105 if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt.pPager))
2106 && sqlite3PagerVfs(pBt.pPager)==pVfs ){
2107 int iDb;
2108 for(iDb=db.nDb-1; iDb>=0; iDb--){
2109 Btree pExisting = db.aDb[iDb].pBt;
2110 if( pExisting && pExisting.pBt==pBt ){
2111 sqlite3_mutex_leave(mutexShared);
2112 sqlite3_mutex_leave(mutexOpen);
2113 zFullPathname = null;//sqlite3_free(ref zFullPathname);
2114 p=null;//sqlite3_free(ref p);
2115 return SQLITE_CONSTRAINT;
2116 }
2117 }
2118 p.pBt = pBt;
2119 pBt.nRef++;
2120 break;
2121 }
2122 }
2123 sqlite3_mutex_leave(mutexShared);
2124 zFullPathname=null;//sqlite3_free(ref zFullPathname);
2125 }
2126 #if SQLITE_DEBUG
2127 else{
2128 /* In debug mode, we mark all persistent databases as sharable
2129 ** even when they are not. This exercises the locking code and
2130 ** gives more opportunity for asserts(sqlite3_mutex_held())
2131 ** statements to find locking problems.
2132 */
2133 p.sharable = 1;
2134 }
2135 #endif
2136 }
2137 #endif
2138 if ( pBt == null )
2139 {
2140 /*
2141 ** The following asserts make sure that structures used by the btree are
2142 ** the right size. This is to guard against size changes that result
2143 ** when compiling on a different architecture.
2144 */
2145 // These are defined as constants in the CLI specifications.
2146 // (See, for example, C# spec sections 18.5.8 and 4.1.4)
2147 ////Debug.Assert( sizeof( i64 ) == 8 || sizeof( i64 ) == 4 );
2148 ////Debug.Assert( sizeof( u64 ) == 8 || sizeof( u64 ) == 4 );
2149 ////Debug.Assert( sizeof( u32 ) == 4 );
2150 ////Debug.Assert( sizeof( u16 ) == 2 );
2151 ////Debug.Assert( sizeof( Pgno ) == 4 );
2152  
2153 pBt = new BtShared();//sqlite3MallocZero( sizeof(pBt) );
2154 //if( pBt==null ){
2155 // rc = SQLITE_NOMEM;
2156 // goto btree_open_out;
2157 //}
2158 rc = sqlite3PagerOpen( pVfs, out pBt.pPager, zFilename,
2159 EXTRA_SIZE, flags, vfsFlags, pageReinit );
2160 if ( rc == SQLITE_OK )
2161 {
2162 rc = sqlite3PagerReadFileheader( pBt.pPager, zDbHeader.Length, zDbHeader );
2163 }
2164 if ( rc != SQLITE_OK )
2165 {
2166 goto btree_open_out;
2167 }
2168 pBt.openFlags = (u8)flags;
2169 pBt.db = db;
2170 sqlite3PagerSetBusyhandler( pBt.pPager, btreeInvokeBusyHandler, pBt );
2171 p.pBt = pBt;
2172  
2173 pBt.pCursor = null;
2174 pBt.pPage1 = null;
2175 pBt.readOnly = sqlite3PagerIsreadonly( pBt.pPager );
2176 #if SQLITE_SECURE_DELETE
2177 pBt.secureDelete = true;
2178 #endif
2179 pBt.pageSize = (u32)( ( zDbHeader[16] << 8 ) | ( zDbHeader[17] << 16 ) );
2180 if ( pBt.pageSize < 512 || pBt.pageSize > SQLITE_MAX_PAGE_SIZE
2181 || ( ( pBt.pageSize - 1 ) & pBt.pageSize ) != 0 )
2182 {
2183 pBt.pageSize = 0;
2184 #if !SQLITE_OMIT_AUTOVACUUM
2185 /* If the magic name ":memory:" will create an in-memory database, then
2186 ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
2187 ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
2188 ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
2189 ** regular file-name. In this case the auto-vacuum applies as per normal.
2190 */
2191 if (zFilename != null && zFilename.Length > 0 && !isMemdb )
2192 {
2193 pBt.autoVacuum = ( SQLITE_DEFAULT_AUTOVACUUM != 0 );
2194 pBt.incrVacuum = ( SQLITE_DEFAULT_AUTOVACUUM == 2 );
2195 }
2196 #endif
2197 nReserve = 0;
2198 }
2199 else
2200 {
2201 nReserve = zDbHeader[20];
2202 pBt.pageSizeFixed = true;
2203 #if !SQLITE_OMIT_AUTOVACUUM
2204 pBt.autoVacuum = sqlite3Get4byte( zDbHeader, 36 + 4 * 4 ) != 0;
2205 pBt.incrVacuum = sqlite3Get4byte( zDbHeader, 36 + 7 * 4 ) != 0;
2206 #endif
2207 }
2208 rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize, nReserve );
2209 if ( rc != 0 )
2210 goto btree_open_out;
2211 pBt.usableSize = (u16)( pBt.pageSize - nReserve );
2212 Debug.Assert( ( pBt.pageSize & 7 ) == 0 ); /* 8-byte alignment of pageSize */
2213  
2214 #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
2215 /* Add the new BtShared object to the linked list sharable BtShareds.
2216 */
2217 if( p.sharable ){
2218 sqlite3_mutex *mutexShared;
2219 pBt.nRef = 1;
2220 mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
2221 if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
2222 pBt.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
2223 if( pBt.mutex==null ){
2224 rc = SQLITE_NOMEM;
2225 db.mallocFailed = 0;
2226 goto btree_open_out;
2227 }
2228 }
2229 sqlite3_mutex_enter(mutexShared);
2230 pBt.pNext = GLOBAL(BtShared*,sqlite3SharedCacheList);
2231 GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt;
2232 sqlite3_mutex_leave(mutexShared);
2233 }
2234 #endif
2235 }
2236  
2237 #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
2238 /* If the new Btree uses a sharable pBtShared, then link the new
2239 ** Btree into the list of all sharable Btrees for the same connection.
2240 ** The list is kept in ascending order by pBt address.
2241 */
2242 if( p.sharable ){
2243 int i;
2244 Btree pSib;
2245 for(i=0; i<db.nDb; i++){
2246 if( (pSib = db.aDb[i].pBt)!=null && pSib.sharable ){
2247 while( pSib.pPrev ){ pSib = pSib.pPrev; }
2248 if( p.pBt<pSib.pBt ){
2249 p.pNext = pSib;
2250 p.pPrev = 0;
2251 pSib.pPrev = p;
2252 }else{
2253 while( pSib.pNext && pSib.pNext.pBt<p.pBt ){
2254 pSib = pSib.pNext;
2255 }
2256 p.pNext = pSib.pNext;
2257 p.pPrev = pSib;
2258 if( p.pNext ){
2259 p.pNext.pPrev = p;
2260 }
2261 pSib.pNext = p;
2262 }
2263 break;
2264 }
2265 }
2266 }
2267 #endif
2268 ppBtree = p;
2269  
2270 btree_open_out:
2271 if ( rc != SQLITE_OK )
2272 {
2273 if ( pBt != null && pBt.pPager != null )
2274 {
2275 sqlite3PagerClose( pBt.pPager );
2276 }
2277 pBt = null; // sqlite3_free(ref pBt);
2278 p = null; // sqlite3_free(ref p);
2279 ppBtree = null;
2280 }
2281 else
2282 {
2283 /* If the B-Tree was successfully opened, set the pager-cache size to the
2284 ** default value. Except, when opening on an existing shared pager-cache,
2285 ** do not change the pager-cache size.
2286 */
2287 if ( sqlite3BtreeSchema( p, 0, null ) == null )
2288 {
2289 sqlite3PagerSetCachesize( p.pBt.pPager, SQLITE_DEFAULT_CACHE_SIZE );
2290 }
2291  
2292 }
2293 if ( mutexOpen != null )
2294 {
2295 Debug.Assert( sqlite3_mutex_held( mutexOpen ) );
2296 sqlite3_mutex_leave( mutexOpen );
2297 }
2298 return rc;
2299 }
2300  
2301 /*
2302 ** Decrement the BtShared.nRef counter. When it reaches zero,
2303 ** remove the BtShared structure from the sharing list. Return
2304 ** true if the BtShared.nRef counter reaches zero and return
2305 ** false if it is still positive.
2306 */
2307 static bool removeFromSharingList( BtShared pBt )
2308 {
2309 #if !SQLITE_OMIT_SHARED_CACHE
2310 sqlite3_mutex pMaster;
2311 BtShared pList;
2312 bool removed = false;
2313  
2314 Debug.Assert( sqlite3_mutex_notheld(pBt.mutex) );
2315 pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
2316 sqlite3_mutex_enter(pMaster);
2317 pBt.nRef--;
2318 if( pBt.nRef<=0 ){
2319 if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
2320 GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt.pNext;
2321 }else{
2322 pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
2323 while( ALWAYS(pList) && pList.pNext!=pBt ){
2324 pList=pList.pNext;
2325 }
2326 if( ALWAYS(pList) ){
2327 pList.pNext = pBt.pNext;
2328 }
2329 }
2330 if( SQLITE_THREADSAFE ){
2331 sqlite3_mutex_free(pBt.mutex);
2332 }
2333 removed = true;
2334 }
2335 sqlite3_mutex_leave(pMaster);
2336 return removed;
2337 #else
2338 return true;
2339 #endif
2340 }
2341  
2342 /*
2343 ** Make sure pBt.pTmpSpace points to an allocation of
2344 ** MX_CELL_SIZE(pBt) bytes.
2345 */
2346 static void allocateTempSpace( BtShared pBt )
2347 {
2348 if ( null == pBt.pTmpSpace )
2349 {
2350 pBt.pTmpSpace = sqlite3Malloc( pBt.pageSize );
2351 }
2352 }
2353  
2354 /*
2355 ** Free the pBt.pTmpSpace allocation
2356 */
2357 static void freeTempSpace( BtShared pBt )
2358 {
2359 sqlite3PageFree( ref pBt.pTmpSpace );
2360 }
2361  
2362 /*
2363 ** Close an open database and invalidate all cursors.
2364 */
2365 static int sqlite3BtreeClose( ref Btree p )
2366 {
2367 BtShared pBt = p.pBt;
2368 BtCursor pCur;
2369  
2370 /* Close all cursors opened via this handle. */
2371 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
2372 sqlite3BtreeEnter( p );
2373 pCur = pBt.pCursor;
2374 while ( pCur != null )
2375 {
2376 BtCursor pTmp = pCur;
2377 pCur = pCur.pNext;
2378 if ( pTmp.pBtree == p )
2379 {
2380 sqlite3BtreeCloseCursor( pTmp );
2381 }
2382 }
2383  
2384 /* Rollback any active transaction and free the handle structure.
2385 ** The call to sqlite3BtreeRollback() drops any table-locks held by
2386 ** this handle.
2387 */
2388 sqlite3BtreeRollback( p );
2389 sqlite3BtreeLeave( p );
2390  
2391 /* If there are still other outstanding references to the shared-btree
2392 ** structure, return now. The remainder of this procedure cleans
2393 ** up the shared-btree.
2394 */
2395 Debug.Assert( p.wantToLock == 0 && !p.locked );
2396 if ( !p.sharable || removeFromSharingList( pBt ) )
2397 {
2398 /* The pBt is no longer on the sharing list, so we can access
2399 ** it without having to hold the mutex.
2400 **
2401 ** Clean out and delete the BtShared object.
2402 */
2403 Debug.Assert( null == pBt.pCursor );
2404 sqlite3PagerClose( pBt.pPager );
2405 if ( pBt.xFreeSchema != null && pBt.pSchema != null )
2406 {
2407 pBt.xFreeSchema( pBt.pSchema );
2408 }
2409 pBt.pSchema = null;// sqlite3DbFree(0, pBt->pSchema);
2410 //freeTempSpace(pBt);
2411 pBt = null; //sqlite3_free(ref pBt);
2412 }
2413  
2414 #if !SQLITE_OMIT_SHARED_CACHE
2415 Debug.Assert( p.wantToLock==null );
2416 Debug.Assert( p.locked==null );
2417 if( p.pPrev ) p.pPrev.pNext = p.pNext;
2418 if( p.pNext ) p.pNext.pPrev = p.pPrev;
2419 #endif
2420  
2421 //sqlite3_free(ref p);
2422 return SQLITE_OK;
2423 }
2424  
2425 /*
2426 ** Change the limit on the number of pages allowed in the cache.
2427 **
2428 ** The maximum number of cache pages is set to the absolute
2429 ** value of mxPage. If mxPage is negative, the pager will
2430 ** operate asynchronously - it will not stop to do fsync()s
2431 ** to insure data is written to the disk surface before
2432 ** continuing. Transactions still work if synchronous is off,
2433 ** and the database cannot be corrupted if this program
2434 ** crashes. But if the operating system crashes or there is
2435 ** an abrupt power failure when synchronous is off, the database
2436 ** could be left in an inconsistent and unrecoverable state.
2437 ** Synchronous is on by default so database corruption is not
2438 ** normally a worry.
2439 */
2440 static int sqlite3BtreeSetCacheSize( Btree p, int mxPage )
2441 {
2442 BtShared pBt = p.pBt;
2443 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
2444 sqlite3BtreeEnter( p );
2445 sqlite3PagerSetCachesize( pBt.pPager, mxPage );
2446 sqlite3BtreeLeave( p );
2447 return SQLITE_OK;
2448 }
2449  
2450 /*
2451 ** Change the way data is synced to disk in order to increase or decrease
2452 ** how well the database resists damage due to OS crashes and power
2453 ** failures. Level 1 is the same as asynchronous (no syncs() occur and
2454 ** there is a high probability of damage) Level 2 is the default. There
2455 ** is a very low but non-zero probability of damage. Level 3 reduces the
2456 ** probability of damage to near zero but with a write performance reduction.
2457 */
2458 #if !SQLITE_OMIT_PAGER_PRAGMAS
2459 static int sqlite3BtreeSetSafetyLevel(
2460 Btree p, /* The btree to set the safety level on */
2461 int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
2462 int fullSync, /* PRAGMA fullfsync. */
2463 int ckptFullSync /* PRAGMA checkpoint_fullfync */
2464 )
2465 {
2466 BtShared pBt = p.pBt;
2467 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
2468 Debug.Assert( level >= 1 && level <= 3 );
2469 sqlite3BtreeEnter( p );
2470 sqlite3PagerSetSafetyLevel( pBt.pPager, level, fullSync, ckptFullSync );
2471 sqlite3BtreeLeave( p );
2472 return SQLITE_OK;
2473 }
2474 #endif
2475  
2476 /*
2477 ** Return TRUE if the given btree is set to safety level 1. In other
2478 ** words, return TRUE if no sync() occurs on the disk files.
2479 */
2480 static int sqlite3BtreeSyncDisabled( Btree p )
2481 {
2482 BtShared pBt = p.pBt;
2483 int rc;
2484 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
2485 sqlite3BtreeEnter( p );
2486 Debug.Assert( pBt != null && pBt.pPager != null );
2487 rc = sqlite3PagerNosync( pBt.pPager ) ? 1 : 0;
2488 sqlite3BtreeLeave( p );
2489 return rc;
2490 }
2491  
2492 /*
2493 ** Change the default pages size and the number of reserved bytes per page.
2494 ** Or, if the page size has already been fixed, return SQLITE_READONLY
2495 ** without changing anything.
2496 **
2497 ** The page size must be a power of 2 between 512 and 65536. If the page
2498 ** size supplied does not meet this constraint then the page size is not
2499 ** changed.
2500 **
2501 ** Page sizes are constrained to be a power of two so that the region
2502 ** of the database file used for locking (beginning at PENDING_BYTE,
2503 ** the first byte past the 1GB boundary, 0x40000000) needs to occur
2504 ** at the beginning of a page.
2505 **
2506 ** If parameter nReserve is less than zero, then the number of reserved
2507 ** bytes per page is left unchanged.
2508 **
2509 ** If iFix!=0 then the pageSizeFixed flag is set so that the page size
2510 ** and autovacuum mode can no longer be changed.
2511 */
2512 static int sqlite3BtreeSetPageSize( Btree p, int pageSize, int nReserve, int iFix )
2513 {
2514 int rc = SQLITE_OK;
2515 BtShared pBt = p.pBt;
2516 Debug.Assert( nReserve >= -1 && nReserve <= 255 );
2517 sqlite3BtreeEnter( p );
2518 if ( pBt.pageSizeFixed )
2519 {
2520 sqlite3BtreeLeave( p );
2521 return SQLITE_READONLY;
2522 }
2523 if ( nReserve < 0 )
2524 {
2525 nReserve = (int)( pBt.pageSize - pBt.usableSize );
2526 }
2527 Debug.Assert( nReserve >= 0 && nReserve <= 255 );
2528 if ( pageSize >= 512 && pageSize <= SQLITE_MAX_PAGE_SIZE &&
2529 ( ( pageSize - 1 ) & pageSize ) == 0 )
2530 {
2531 Debug.Assert( ( pageSize & 7 ) == 0 );
2532 Debug.Assert( null == pBt.pPage1 && null == pBt.pCursor );
2533 pBt.pageSize = (u32)pageSize;
2534 // freeTempSpace(pBt);
2535 }
2536 rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize, nReserve );
2537 pBt.usableSize = (u16)( pBt.pageSize - nReserve );
2538 if ( iFix != 0 )
2539 pBt.pageSizeFixed = true;
2540 sqlite3BtreeLeave( p );
2541 return rc;
2542 }
2543  
2544 /*
2545 ** Return the currently defined page size
2546 */
2547 static int sqlite3BtreeGetPageSize( Btree p )
2548 {
2549 return (int)p.pBt.pageSize;
2550 }
2551  
2552 #if !(SQLITE_OMIT_PAGER_PRAGMAS) || !(SQLITE_OMIT_VACUUM)
2553 /*
2554 ** Return the number of bytes of space at the end of every page that
2555 ** are intentually left unused. This is the "reserved" space that is
2556 ** sometimes used by extensions.
2557 */
2558 static int sqlite3BtreeGetReserve( Btree p )
2559 {
2560 int n;
2561 sqlite3BtreeEnter( p );
2562 n = (int)( p.pBt.pageSize - p.pBt.usableSize );
2563 sqlite3BtreeLeave( p );
2564 return n;
2565 }
2566  
2567 /*
2568 ** Set the maximum page count for a database if mxPage is positive.
2569 ** No changes are made if mxPage is 0 or negative.
2570 ** Regardless of the value of mxPage, return the maximum page count.
2571 */
2572 static Pgno sqlite3BtreeMaxPageCount( Btree p, int mxPage )
2573 {
2574 Pgno n;
2575 sqlite3BtreeEnter( p );
2576 n = sqlite3PagerMaxPageCount( p.pBt.pPager, mxPage );
2577 sqlite3BtreeLeave( p );
2578 return n;
2579 }
2580  
2581 /*
2582 ** Set the secureDelete flag if newFlag is 0 or 1. If newFlag is -1,
2583 ** then make no changes. Always return the value of the secureDelete
2584 ** setting after the change.
2585 */
2586 static int sqlite3BtreeSecureDelete( Btree p, int newFlag )
2587 {
2588 int b;
2589 if ( p == null )
2590 return 0;
2591 sqlite3BtreeEnter( p );
2592 if ( newFlag >= 0 )
2593 {
2594 p.pBt.secureDelete = ( newFlag != 0 );
2595 }
2596 b = p.pBt.secureDelete ? 1 : 0;
2597 sqlite3BtreeLeave( p );
2598 return b;
2599 }
2600 #endif //* !(SQLITE_OMIT_PAGER_PRAGMAS) || !(SQLITE_OMIT_VACUUM) */
2601  
2602 /*
2603 ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
2604 ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
2605 ** is disabled. The default value for the auto-vacuum property is
2606 ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
2607 */
2608 static int sqlite3BtreeSetAutoVacuum( Btree p, int autoVacuum )
2609 {
2610 #if SQLITE_OMIT_AUTOVACUUM
2611 return SQLITE_READONLY;
2612 #else
2613 BtShared pBt = p.pBt;
2614 int rc = SQLITE_OK;
2615 u8 av = (u8)autoVacuum;
2616  
2617 sqlite3BtreeEnter( p );
2618 if ( pBt.pageSizeFixed && ( av != 0 ) != pBt.autoVacuum )
2619 {
2620 rc = SQLITE_READONLY;
2621 }
2622 else
2623 {
2624 pBt.autoVacuum = av != 0;
2625 pBt.incrVacuum = av == 2;
2626 }
2627 sqlite3BtreeLeave( p );
2628 return rc;
2629 #endif
2630 }
2631  
2632 /*
2633 ** Return the value of the 'auto-vacuum' property. If auto-vacuum is
2634 ** enabled 1 is returned. Otherwise 0.
2635 */
2636 static int sqlite3BtreeGetAutoVacuum( Btree p )
2637 {
2638 #if SQLITE_OMIT_AUTOVACUUM
2639 return BTREE_AUTOVACUUM_NONE;
2640 #else
2641 int rc;
2642 sqlite3BtreeEnter( p );
2643 rc = (
2644 ( !p.pBt.autoVacuum ) ? BTREE_AUTOVACUUM_NONE :
2645 ( !p.pBt.incrVacuum ) ? BTREE_AUTOVACUUM_FULL :
2646 BTREE_AUTOVACUUM_INCR
2647 );
2648 sqlite3BtreeLeave( p );
2649 return rc;
2650 #endif
2651 }
2652  
2653  
2654 /*
2655 ** Get a reference to pPage1 of the database file. This will
2656 ** also acquire a readlock on that file.
2657 **
2658 ** SQLITE_OK is returned on success. If the file is not a
2659 ** well-formed database file, then SQLITE_CORRUPT is returned.
2660 ** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
2661 ** is returned if we run out of memory.
2662 */
2663 static int lockBtree( BtShared pBt )
2664 {
2665 int rc; /* Result code from subfunctions */
2666 MemPage pPage1 = null; /* Page 1 of the database file */
2667 Pgno nPage; /* Number of pages in the database */
2668 Pgno nPageFile = 0; /* Number of pages in the database file */
2669 ////Pgno nPageHeader; /* Number of pages in the database according to hdr */
2670  
2671 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
2672 Debug.Assert( pBt.pPage1 == null );
2673 rc = sqlite3PagerSharedLock( pBt.pPager );
2674 if ( rc != SQLITE_OK )
2675 return rc;
2676 rc = btreeGetPage( pBt, 1, ref pPage1, 0 );
2677 if ( rc != SQLITE_OK )
2678 return rc;
2679  
2680 /* Do some checking to help insure the file we opened really is
2681 ** a valid database file.
2682 */
2683 nPage = sqlite3Get4byte( pPage1.aData, 28 );//get4byte(28+(u8*)pPage1->aData);
2684 ////nPageHeader = nPage;
2685 sqlite3PagerPagecount( pBt.pPager, out nPageFile );
2686 if ( nPage == 0 || memcmp( pPage1.aData, 24, pPage1.aData, 92, 4 ) != 0 )//memcmp(24 + (u8*)pPage1.aData, 92 + (u8*)pPage1.aData, 4) != 0)
2687 {
2688 nPage = nPageFile;
2689 }
2690 if ( nPage > 0 )
2691 {
2692 u32 pageSize;
2693 u32 usableSize;
2694 u8[] page1 = pPage1.aData;
2695 rc = SQLITE_NOTADB;
2696 if ( memcmp( page1, zMagicHeader, 16 ) != 0 )
2697 {
2698 goto page1_init_failed;
2699 }
2700  
2701 #if SQLITE_OMIT_WAL
2702 if ( page1[18] > 1 )
2703 {
2704 pBt.readOnly = true;
2705 }
2706 if ( page1[19] > 1 )
2707 {
2708 pBt.pSchema.file_format = page1[19];
2709 goto page1_init_failed;
2710 }
2711 #else
2712 if( page1[18]>2 ){
2713 pBt.readOnly = true;
2714 }
2715 if( page1[19]>2 ){
2716 goto page1_init_failed;
2717 }
2718  
2719 /* If the write version is set to 2, this database should be accessed
2720 ** in WAL mode. If the log is not already open, open it now. Then
2721 ** return SQLITE_OK and return without populating BtShared.pPage1.
2722 ** The caller detects this and calls this function again. This is
2723 ** required as the version of page 1 currently in the page1 buffer
2724 ** may not be the latest version - there may be a newer one in the log
2725 ** file.
2726 */
2727 if( page1[19]==2 && pBt.doNotUseWAL==false ){
2728 int isOpen = 0;
2729 rc = sqlite3PagerOpenWal(pBt.pPager, ref isOpen);
2730 if( rc!=SQLITE_OK ){
2731 goto page1_init_failed;
2732 }else if( isOpen==0 ){
2733 releasePage(pPage1);
2734 return SQLITE_OK;
2735 }
2736 rc = SQLITE_NOTADB;
2737 }
2738 #endif
2739  
2740 /* The maximum embedded fraction must be exactly 25%. And the minimum
2741 ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
2742 ** The original design allowed these amounts to vary, but as of
2743 ** version 3.6.0, we require them to be fixed.
2744 */
2745 if ( memcmp( page1, 21, "\x0040\x0020\x0020", 3 ) != 0 )// "\100\040\040"
2746 {
2747 goto page1_init_failed;
2748 }
2749 pageSize = (u32)( ( page1[16] << 8 ) | ( page1[17] << 16 ) );
2750 if ( ( ( pageSize - 1 ) & pageSize ) != 0
2751 || pageSize > SQLITE_MAX_PAGE_SIZE
2752 || pageSize <= 256
2753 )
2754 {
2755 goto page1_init_failed;
2756 }
2757 Debug.Assert( ( pageSize & 7 ) == 0 );
2758 usableSize = pageSize - page1[20];
2759 if ( pageSize != pBt.pageSize )
2760 {
2761 /* After reading the first page of the database assuming a page size
2762 ** of BtShared.pageSize, we have discovered that the page-size is
2763 ** actually pageSize. Unlock the database, leave pBt.pPage1 at
2764 ** zero and return SQLITE_OK. The caller will call this function
2765 ** again with the correct page-size.
2766 */
2767 releasePage( pPage1 );
2768 pBt.usableSize = usableSize;
2769 pBt.pageSize = pageSize;
2770 // freeTempSpace(pBt);
2771 rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize,
2772 (int)( pageSize - usableSize ) );
2773 return rc;
2774 }
2775 if ( ( pBt.db.flags & SQLITE_RecoveryMode ) == 0 && nPage > nPageFile )
2776 {
2777 rc = SQLITE_CORRUPT_BKPT();
2778 goto page1_init_failed;
2779 }
2780 if ( usableSize < 480 )
2781 {
2782 goto page1_init_failed;
2783 }
2784 pBt.pageSize = pageSize;
2785 pBt.usableSize = usableSize;
2786 #if !SQLITE_OMIT_AUTOVACUUM
2787 pBt.autoVacuum = ( sqlite3Get4byte( page1, 36 + 4 * 4 ) != 0 );
2788 pBt.incrVacuum = ( sqlite3Get4byte( page1, 36 + 7 * 4 ) != 0 );
2789 #endif
2790 }
2791  
2792 /* maxLocal is the maximum amount of payload to store locally for
2793 ** a cell. Make sure it is small enough so that at least minFanout
2794 ** cells can will fit on one page. We assume a 10-byte page header.
2795 ** Besides the payload, the cell must store:
2796 ** 2-byte pointer to the cell
2797 ** 4-byte child pointer
2798 ** 9-byte nKey value
2799 ** 4-byte nData value
2800 ** 4-byte overflow page pointer
2801 ** So a cell consists of a 2-byte pointer, a header which is as much as
2802 ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
2803 ** page pointer.
2804 */
2805 pBt.maxLocal = (u16)( ( pBt.usableSize - 12 ) * 64 / 255 - 23 );
2806 pBt.minLocal = (u16)( ( pBt.usableSize - 12 ) * 32 / 255 - 23 );
2807 pBt.maxLeaf = (u16)( pBt.usableSize - 35 );
2808 pBt.minLeaf = (u16)( ( pBt.usableSize - 12 ) * 32 / 255 - 23 );
2809 Debug.Assert( pBt.maxLeaf + 23 <= MX_CELL_SIZE( pBt ) );
2810 pBt.pPage1 = pPage1;
2811 pBt.nPage = nPage;
2812 return SQLITE_OK;
2813  
2814 page1_init_failed:
2815 releasePage( pPage1 );
2816 pBt.pPage1 = null;
2817 return rc;
2818 }
2819  
2820 /*
2821 ** If there are no outstanding cursors and we are not in the middle
2822 ** of a transaction but there is a read lock on the database, then
2823 ** this routine unrefs the first page of the database file which
2824 ** has the effect of releasing the read lock.
2825 **
2826 ** If there is a transaction in progress, this routine is a no-op.
2827 */
2828 static void unlockBtreeIfUnused( BtShared pBt )
2829 {
2830 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
2831 Debug.Assert( pBt.pCursor == null || pBt.inTransaction > TRANS_NONE );
2832 if ( pBt.inTransaction == TRANS_NONE && pBt.pPage1 != null )
2833 {
2834 Debug.Assert( pBt.pPage1.aData != null );
2835 //Debug.Assert( sqlite3PagerRefcount( pBt.pPager ) == 1 );
2836 releasePage( pBt.pPage1 );
2837 pBt.pPage1 = null;
2838 }
2839 }
2840  
2841 /*
2842 ** If pBt points to an empty file then convert that empty file
2843 ** into a new empty database by initializing the first page of
2844 ** the database.
2845 */
2846 static int newDatabase( BtShared pBt )
2847 {
2848 MemPage pP1;
2849 byte[] data;
2850 int rc;
2851  
2852 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
2853 if ( pBt.nPage > 0 )
2854 {
2855 return SQLITE_OK;
2856 }
2857 pP1 = pBt.pPage1;
2858 Debug.Assert( pP1 != null );
2859 data = pP1.aData;
2860 rc = sqlite3PagerWrite( pP1.pDbPage );
2861 if ( rc != 0 )
2862 return rc;
2863 Buffer.BlockCopy( zMagicHeader, 0, data, 0, 16 );// memcpy(data, zMagicHeader, sizeof(zMagicHeader));
2864 Debug.Assert( zMagicHeader.Length == 16 );
2865 data[16] = (u8)( ( pBt.pageSize >> 8 ) & 0xff );
2866 data[17] = (u8)( ( pBt.pageSize >> 16 ) & 0xff );
2867 data[18] = 1;
2868 data[19] = 1;
2869 Debug.Assert( pBt.usableSize <= pBt.pageSize && pBt.usableSize + 255 >= pBt.pageSize );
2870 data[20] = (u8)( pBt.pageSize - pBt.usableSize );
2871 data[21] = 64;
2872 data[22] = 32;
2873 data[23] = 32;
2874 //memset(&data[24], 0, 100-24);
2875 zeroPage( pP1, PTF_INTKEY | PTF_LEAF | PTF_LEAFDATA );
2876 pBt.pageSizeFixed = true;
2877 #if !SQLITE_OMIT_AUTOVACUUM
2878 Debug.Assert( pBt.autoVacuum == true || pBt.autoVacuum == false );
2879 Debug.Assert( pBt.incrVacuum == true || pBt.incrVacuum == false );
2880 sqlite3Put4byte( data, 36 + 4 * 4, pBt.autoVacuum ? 1 : 0 );
2881 sqlite3Put4byte( data, 36 + 7 * 4, pBt.incrVacuum ? 1 : 0 );
2882 #endif
2883 pBt.nPage = 1;
2884 data[31] = 1;
2885 return SQLITE_OK;
2886 }
2887  
2888 /*
2889 ** Attempt to start a new transaction. A write-transaction
2890 ** is started if the second argument is nonzero, otherwise a read-
2891 ** transaction. If the second argument is 2 or more and exclusive
2892 ** transaction is started, meaning that no other process is allowed
2893 ** to access the database. A preexisting transaction may not be
2894 ** upgraded to exclusive by calling this routine a second time - the
2895 ** exclusivity flag only works for a new transaction.
2896 **
2897 ** A write-transaction must be started before attempting any
2898 ** changes to the database. None of the following routines
2899 ** will work unless a transaction is started first:
2900 **
2901 ** sqlite3BtreeCreateTable()
2902 ** sqlite3BtreeCreateIndex()
2903 ** sqlite3BtreeClearTable()
2904 ** sqlite3BtreeDropTable()
2905 ** sqlite3BtreeInsert()
2906 ** sqlite3BtreeDelete()
2907 ** sqlite3BtreeUpdateMeta()
2908 **
2909 ** If an initial attempt to acquire the lock fails because of lock contention
2910 ** and the database was previously unlocked, then invoke the busy handler
2911 ** if there is one. But if there was previously a read-lock, do not
2912 ** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is
2913 ** returned when there is already a read-lock in order to avoid a deadlock.
2914 **
2915 ** Suppose there are two processes A and B. A has a read lock and B has
2916 ** a reserved lock. B tries to promote to exclusive but is blocked because
2917 ** of A's read lock. A tries to promote to reserved but is blocked by B.
2918 ** One or the other of the two processes must give way or there can be
2919 ** no progress. By returning SQLITE_BUSY and not invoking the busy callback
2920 ** when A already has a read lock, we encourage A to give up and let B
2921 ** proceed.
2922 */
2923 static int sqlite3BtreeBeginTrans( Btree p, int wrflag )
2924 {
2925 BtShared pBt = p.pBt;
2926 int rc = SQLITE_OK;
2927  
2928 sqlite3BtreeEnter( p );
2929 btreeIntegrity( p );
2930  
2931 /* If the btree is already in a write-transaction, or it
2932 ** is already in a read-transaction and a read-transaction
2933 ** is requested, this is a no-op.
2934 */
2935 if ( p.inTrans == TRANS_WRITE || ( p.inTrans == TRANS_READ && 0 == wrflag ) )
2936 {
2937 goto trans_begun;
2938 }
2939  
2940 /* Write transactions are not possible on a read-only database */
2941 if ( pBt.readOnly && wrflag != 0 )
2942 {
2943 rc = SQLITE_READONLY;
2944 goto trans_begun;
2945 }
2946  
2947 #if !SQLITE_OMIT_SHARED_CACHE
2948 /* If another database handle has already opened a write transaction
2949 ** on this shared-btree structure and a second write transaction is
2950 ** requested, return SQLITE_LOCKED.
2951 */
2952 if( (wrflag && pBt.inTransaction==TRANS_WRITE) || pBt.isPending ){
2953 sqlite3 pBlock = pBt.pWriter.db;
2954 }else if( wrflag>1 ){
2955 BtLock pIter;
2956 for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
2957 if( pIter.pBtree!=p ){
2958 pBlock = pIter.pBtree.db;
2959 break;
2960 }
2961 }
2962 }
2963 if( pBlock ){
2964 sqlite3ConnectionBlocked(p.db, pBlock);
2965 rc = SQLITE_LOCKED_SHAREDCACHE;
2966 goto trans_begun;
2967 }
2968 #endif
2969  
2970 /* Any read-only or read-write transaction implies a read-lock on
2971 ** page 1. So if some other shared-cache client already has a write-lock
2972 ** on page 1, the transaction cannot be opened. */
2973 rc = querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK );
2974 if ( SQLITE_OK != rc )
2975 goto trans_begun;
2976  
2977 pBt.initiallyEmpty = pBt.nPage == 0;
2978 do
2979 {
2980 /* Call lockBtree() until either pBt.pPage1 is populated or
2981 ** lockBtree() returns something other than SQLITE_OK. lockBtree()
2982 ** may return SQLITE_OK but leave pBt.pPage1 set to 0 if after
2983 ** reading page 1 it discovers that the page-size of the database
2984 ** file is not pBt.pageSize. In this case lockBtree() will update
2985 ** pBt.pageSize to the page-size of the file on disk.
2986 */
2987 while ( pBt.pPage1 == null && SQLITE_OK == ( rc = lockBtree( pBt ) ) )
2988 ;
2989  
2990 if ( rc == SQLITE_OK && wrflag != 0 )
2991 {
2992 if ( pBt.readOnly )
2993 {
2994 rc = SQLITE_READONLY;
2995 }
2996 else
2997 {
2998 rc = sqlite3PagerBegin( pBt.pPager, wrflag > 1, sqlite3TempInMemory( p.db ) ? 1 : 0 );
2999 if ( rc == SQLITE_OK )
3000 {
3001 rc = newDatabase( pBt );
3002 }
3003 }
3004 }
3005  
3006 if ( rc != SQLITE_OK )
3007 {
3008 unlockBtreeIfUnused( pBt );
3009 }
3010 } while ( ( rc & 0xFF ) == SQLITE_BUSY && pBt.inTransaction == TRANS_NONE &&
3011 btreeInvokeBusyHandler( pBt ) != 0 );
3012  
3013 if ( rc == SQLITE_OK )
3014 {
3015 if ( p.inTrans == TRANS_NONE )
3016 {
3017 pBt.nTransaction++;
3018 #if !SQLITE_OMIT_SHARED_CACHE
3019 if( p.sharable ){
3020 Debug.Assert( p.lock.pBtree==p && p.lock.iTable==1 );
3021 p.lock.eLock = READ_LOCK;
3022 p.lock.pNext = pBt.pLock;
3023 pBt.pLock = &p.lock;
3024 }
3025 #endif
3026 }
3027 p.inTrans = ( wrflag != 0 ? TRANS_WRITE : TRANS_READ );
3028 if ( p.inTrans > pBt.inTransaction )
3029 {
3030 pBt.inTransaction = p.inTrans;
3031 }
3032 if ( wrflag != 0 )
3033 {
3034 MemPage pPage1 = pBt.pPage1;
3035 #if !SQLITE_OMIT_SHARED_CACHE
3036 Debug.Assert( !pBt.pWriter );
3037 pBt.pWriter = p;
3038 pBt.isExclusive = (u8)(wrflag>1);
3039 #endif
3040 /* If the db-size header field is incorrect (as it may be if an old
3041 ** client has been writing the database file), update it now. Doing
3042 ** this sooner rather than later means the database size can safely
3043 ** re-read the database size from page 1 if a savepoint or transaction
3044 ** rollback occurs within the transaction.
3045 */
3046 if ( pBt.nPage != sqlite3Get4byte( pPage1.aData, 28 ) )
3047 {
3048 rc = sqlite3PagerWrite( pPage1.pDbPage );
3049 if ( rc == SQLITE_OK )
3050 {
3051 sqlite3Put4byte( pPage1.aData, (u32)28, pBt.nPage );
3052 }
3053 }
3054 }
3055 }
3056  
3057  
3058 trans_begun:
3059 if ( rc == SQLITE_OK && wrflag != 0 )
3060 {
3061 /* This call makes sure that the pager has the correct number of
3062 ** open savepoints. If the second parameter is greater than 0 and
3063 ** the sub-journal is not already open, then it will be opened here.
3064 */
3065 rc = sqlite3PagerOpenSavepoint( pBt.pPager, p.db.nSavepoint );
3066 }
3067  
3068 btreeIntegrity( p );
3069 sqlite3BtreeLeave( p );
3070 return rc;
3071 }
3072  
3073 #if !SQLITE_OMIT_AUTOVACUUM
3074  
3075 /*
3076 ** Set the pointer-map entries for all children of page pPage. Also, if
3077 ** pPage contains cells that point to overflow pages, set the pointer
3078 ** map entries for the overflow pages as well.
3079 */
3080 static int setChildPtrmaps( MemPage pPage )
3081 {
3082 int i; /* Counter variable */
3083 int nCell; /* Number of cells in page pPage */
3084 int rc; /* Return code */
3085 BtShared pBt = pPage.pBt;
3086 u8 isInitOrig = pPage.isInit;
3087 Pgno pgno = pPage.pgno;
3088  
3089 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
3090 rc = btreeInitPage( pPage );
3091 if ( rc != SQLITE_OK )
3092 {
3093 goto set_child_ptrmaps_out;
3094 }
3095 nCell = pPage.nCell;
3096  
3097 for ( i = 0; i < nCell; i++ )
3098 {
3099 int pCell = findCell( pPage, i );
3100  
3101 ptrmapPutOvflPtr( pPage, pCell, ref rc );
3102  
3103 if ( 0 == pPage.leaf )
3104 {
3105 Pgno childPgno = sqlite3Get4byte( pPage.aData, pCell );
3106 ptrmapPut( pBt, childPgno, PTRMAP_BTREE, pgno, ref rc );
3107 }
3108 }
3109  
3110 if ( 0 == pPage.leaf )
3111 {
3112 Pgno childPgno = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
3113 ptrmapPut( pBt, childPgno, PTRMAP_BTREE, pgno, ref rc );
3114 }
3115  
3116 set_child_ptrmaps_out:
3117 pPage.isInit = isInitOrig;
3118 return rc;
3119 }
3120  
3121 /*
3122 ** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so
3123 ** that it points to iTo. Parameter eType describes the type of pointer to
3124 ** be modified, as follows:
3125 **
3126 ** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child
3127 ** page of pPage.
3128 **
3129 ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
3130 ** page pointed to by one of the cells on pPage.
3131 **
3132 ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
3133 ** overflow page in the list.
3134 */
3135 static int modifyPagePointer( MemPage pPage, Pgno iFrom, Pgno iTo, u8 eType )
3136 {
3137 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
3138 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
3139 if ( eType == PTRMAP_OVERFLOW2 )
3140 {
3141 /* The pointer is always the first 4 bytes of the page in this case. */
3142 if ( sqlite3Get4byte( pPage.aData ) != iFrom )
3143 {
3144 return SQLITE_CORRUPT_BKPT();
3145 }
3146 sqlite3Put4byte( pPage.aData, iTo );
3147 }
3148 else
3149 {
3150 u8 isInitOrig = pPage.isInit;
3151 int i;
3152 int nCell;
3153  
3154 btreeInitPage( pPage );
3155 nCell = pPage.nCell;
3156  
3157 for ( i = 0; i < nCell; i++ )
3158 {
3159 int pCell = findCell( pPage, i );
3160 if ( eType == PTRMAP_OVERFLOW1 )
3161 {
3162 CellInfo info = new CellInfo();
3163 btreeParseCellPtr( pPage, pCell, ref info );
3164 if ( info.iOverflow != 0 )
3165 {
3166 if ( iFrom == sqlite3Get4byte( pPage.aData, pCell, info.iOverflow ) )
3167 {
3168 sqlite3Put4byte( pPage.aData, pCell + info.iOverflow, (int)iTo );
3169 break;
3170 }
3171 }
3172 }
3173 else
3174 {
3175 if ( sqlite3Get4byte( pPage.aData, pCell ) == iFrom )
3176 {
3177 sqlite3Put4byte( pPage.aData, pCell, (int)iTo );
3178 break;
3179 }
3180 }
3181 }
3182  
3183 if ( i == nCell )
3184 {
3185 if ( eType != PTRMAP_BTREE ||
3186 sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) != iFrom )
3187 {
3188 return SQLITE_CORRUPT_BKPT();
3189 }
3190 sqlite3Put4byte( pPage.aData, pPage.hdrOffset + 8, iTo );
3191 }
3192  
3193 pPage.isInit = isInitOrig;
3194 }
3195 return SQLITE_OK;
3196 }
3197  
3198  
3199 /*
3200 ** Move the open database page pDbPage to location iFreePage in the
3201 ** database. The pDbPage reference remains valid.
3202 **
3203 ** The isCommit flag indicates that there is no need to remember that
3204 ** the journal needs to be sync()ed before database page pDbPage.pgno
3205 ** can be written to. The caller has already promised not to write to that
3206 ** page.
3207 */
3208 static int relocatePage(
3209 BtShared pBt, /* Btree */
3210 MemPage pDbPage, /* Open page to move */
3211 u8 eType, /* Pointer map 'type' entry for pDbPage */
3212 Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
3213 Pgno iFreePage, /* The location to move pDbPage to */
3214 int isCommit /* isCommit flag passed to sqlite3PagerMovepage */
3215 )
3216 {
3217 MemPage pPtrPage = new MemPage(); /* The page that contains a pointer to pDbPage */
3218 Pgno iDbPage = pDbPage.pgno;
3219 Pager pPager = pBt.pPager;
3220 int rc;
3221  
3222 Debug.Assert( eType == PTRMAP_OVERFLOW2 || eType == PTRMAP_OVERFLOW1 ||
3223 eType == PTRMAP_BTREE || eType == PTRMAP_ROOTPAGE );
3224 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
3225 Debug.Assert( pDbPage.pBt == pBt );
3226  
3227 /* Move page iDbPage from its current location to page number iFreePage */
3228 TRACE( "AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
3229 iDbPage, iFreePage, iPtrPage, eType );
3230 rc = sqlite3PagerMovepage( pPager, pDbPage.pDbPage, iFreePage, isCommit );
3231 if ( rc != SQLITE_OK )
3232 {
3233 return rc;
3234 }
3235 pDbPage.pgno = iFreePage;
3236  
3237 /* If pDbPage was a btree-page, then it may have child pages and/or cells
3238 ** that point to overflow pages. The pointer map entries for all these
3239 ** pages need to be changed.
3240 **
3241 ** If pDbPage is an overflow page, then the first 4 bytes may store a
3242 ** pointer to a subsequent overflow page. If this is the case, then
3243 ** the pointer map needs to be updated for the subsequent overflow page.
3244 */
3245 if ( eType == PTRMAP_BTREE || eType == PTRMAP_ROOTPAGE )
3246 {
3247 rc = setChildPtrmaps( pDbPage );
3248 if ( rc != SQLITE_OK )
3249 {
3250 return rc;
3251 }
3252 }
3253 else
3254 {
3255 Pgno nextOvfl = sqlite3Get4byte( pDbPage.aData );
3256 if ( nextOvfl != 0 )
3257 {
3258 ptrmapPut( pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, ref rc );
3259 if ( rc != SQLITE_OK )
3260 {
3261 return rc;
3262 }
3263 }
3264 }
3265  
3266 /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
3267 ** that it points at iFreePage. Also fix the pointer map entry for
3268 ** iPtrPage.
3269 */
3270 if ( eType != PTRMAP_ROOTPAGE )
3271 {
3272 rc = btreeGetPage( pBt, iPtrPage, ref pPtrPage, 0 );
3273 if ( rc != SQLITE_OK )
3274 {
3275 return rc;
3276 }
3277 rc = sqlite3PagerWrite( pPtrPage.pDbPage );
3278 if ( rc != SQLITE_OK )
3279 {
3280 releasePage( pPtrPage );
3281 return rc;
3282 }
3283 rc = modifyPagePointer( pPtrPage, iDbPage, iFreePage, eType );
3284 releasePage( pPtrPage );
3285 if ( rc == SQLITE_OK )
3286 {
3287 ptrmapPut( pBt, iFreePage, eType, iPtrPage, ref rc );
3288 }
3289 }
3290 return rc;
3291 }
3292  
3293 /* Forward declaration required by incrVacuumStep(). */
3294 //static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
3295  
3296 /*
3297 ** Perform a single step of an incremental-vacuum. If successful,
3298 ** return SQLITE_OK. If there is no work to do (and therefore no
3299 ** point in calling this function again), return SQLITE_DONE.
3300 **
3301 ** More specificly, this function attempts to re-organize the
3302 ** database so that the last page of the file currently in use
3303 ** is no longer in use.
3304 **
3305 ** If the nFin parameter is non-zero, this function assumes
3306 ** that the caller will keep calling incrVacuumStep() until
3307 ** it returns SQLITE_DONE or an error, and that nFin is the
3308 ** number of pages the database file will contain after this
3309 ** process is complete. If nFin is zero, it is assumed that
3310 ** incrVacuumStep() will be called a finite amount of times
3311 ** which may or may not empty the freelist. A full autovacuum
3312 ** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==null.
3313 */
3314 static int incrVacuumStep( BtShared pBt, Pgno nFin, Pgno iLastPg )
3315 {
3316 Pgno nFreeList; /* Number of pages still on the free-list */
3317 int rc;
3318  
3319 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
3320 Debug.Assert( iLastPg > nFin );
3321  
3322 if ( !PTRMAP_ISPAGE( pBt, iLastPg ) && iLastPg != PENDING_BYTE_PAGE( pBt ) )
3323 {
3324 u8 eType = 0;
3325 Pgno iPtrPage = 0;
3326  
3327 nFreeList = sqlite3Get4byte( pBt.pPage1.aData, 36 );
3328 if ( nFreeList == 0 )
3329 {
3330 return SQLITE_DONE;
3331 }
3332  
3333 rc = ptrmapGet( pBt, iLastPg, ref eType, ref iPtrPage );
3334 if ( rc != SQLITE_OK )
3335 {
3336 return rc;
3337 }
3338 if ( eType == PTRMAP_ROOTPAGE )
3339 {
3340 return SQLITE_CORRUPT_BKPT();
3341 }
3342  
3343 if ( eType == PTRMAP_FREEPAGE )
3344 {
3345 if ( nFin == 0 )
3346 {
3347 /* Remove the page from the files free-list. This is not required
3348 ** if nFin is non-zero. In that case, the free-list will be
3349 ** truncated to zero after this function returns, so it doesn't
3350 ** matter if it still contains some garbage entries.
3351 */
3352 Pgno iFreePg = 0;
3353 MemPage pFreePg = new MemPage();
3354 rc = allocateBtreePage( pBt, ref pFreePg, ref iFreePg, iLastPg, 1 );
3355 if ( rc != SQLITE_OK )
3356 {
3357 return rc;
3358 }
3359 Debug.Assert( iFreePg == iLastPg );
3360 releasePage( pFreePg );
3361 }
3362 }
3363 else
3364 {
3365 Pgno iFreePg = 0; /* Index of free page to move pLastPg to */
3366 MemPage pLastPg = new MemPage();
3367  
3368 rc = btreeGetPage( pBt, iLastPg, ref pLastPg, 0 );
3369 if ( rc != SQLITE_OK )
3370 {
3371 return rc;
3372 }
3373  
3374 /* If nFin is zero, this loop runs exactly once and page pLastPg
3375 ** is swapped with the first free page pulled off the free list.
3376 **
3377 ** On the other hand, if nFin is greater than zero, then keep
3378 ** looping until a free-page located within the first nFin pages
3379 ** of the file is found.
3380 */
3381 do
3382 {
3383 MemPage pFreePg = new MemPage();
3384 rc = allocateBtreePage( pBt, ref pFreePg, ref iFreePg, 0, 0 );
3385 if ( rc != SQLITE_OK )
3386 {
3387 releasePage( pLastPg );
3388 return rc;
3389 }
3390 releasePage( pFreePg );
3391 } while ( nFin != 0 && iFreePg > nFin );
3392 Debug.Assert( iFreePg < iLastPg );
3393  
3394 rc = sqlite3PagerWrite( pLastPg.pDbPage );
3395 if ( rc == SQLITE_OK )
3396 {
3397 rc = relocatePage( pBt, pLastPg, eType, iPtrPage, iFreePg, ( nFin != 0 ) ? 1 : 0 );
3398 }
3399 releasePage( pLastPg );
3400 if ( rc != SQLITE_OK )
3401 {
3402 return rc;
3403 }
3404 }
3405 }
3406  
3407 if ( nFin == 0 )
3408 {
3409 iLastPg--;
3410 while ( iLastPg == PENDING_BYTE_PAGE( pBt ) || PTRMAP_ISPAGE( pBt, iLastPg ) )
3411 {
3412 if ( PTRMAP_ISPAGE( pBt, iLastPg ) )
3413 {
3414 MemPage pPg = new MemPage();
3415 rc = btreeGetPage( pBt, iLastPg, ref pPg, 0 );
3416 if ( rc != SQLITE_OK )
3417 {
3418 return rc;
3419 }
3420 rc = sqlite3PagerWrite( pPg.pDbPage );
3421 releasePage( pPg );
3422 if ( rc != SQLITE_OK )
3423 {
3424 return rc;
3425 }
3426 }
3427 iLastPg--;
3428 }
3429 sqlite3PagerTruncateImage( pBt.pPager, iLastPg );
3430 pBt.nPage = iLastPg;
3431 }
3432 return SQLITE_OK;
3433 }
3434  
3435 /*
3436 ** A write-transaction must be opened before calling this function.
3437 ** It performs a single unit of work towards an incremental vacuum.
3438 **
3439 ** If the incremental vacuum is finished after this function has run,
3440 ** SQLITE_DONE is returned. If it is not finished, but no error occurred,
3441 ** SQLITE_OK is returned. Otherwise an SQLite error code.
3442 */
3443 static int sqlite3BtreeIncrVacuum( Btree p )
3444 {
3445 int rc;
3446 BtShared pBt = p.pBt;
3447  
3448 sqlite3BtreeEnter( p );
3449 Debug.Assert( pBt.inTransaction == TRANS_WRITE && p.inTrans == TRANS_WRITE );
3450 if ( !pBt.autoVacuum )
3451 {
3452 rc = SQLITE_DONE;
3453 }
3454 else
3455 {
3456 invalidateAllOverflowCache( pBt );
3457 rc = incrVacuumStep( pBt, 0, btreePagecount( pBt ) );
3458 if ( rc == SQLITE_OK )
3459 {
3460 rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
3461 sqlite3Put4byte( pBt.pPage1.aData, (u32)28, pBt.nPage );//put4byte(&pBt->pPage1->aData[28], pBt->nPage);
3462 }
3463 }
3464 sqlite3BtreeLeave( p );
3465 return rc;
3466 }
3467  
3468 /*
3469 ** This routine is called prior to sqlite3PagerCommit when a transaction
3470 ** is commited for an auto-vacuum database.
3471 **
3472 ** If SQLITE_OK is returned, then pnTrunc is set to the number of pages
3473 ** the database file should be truncated to during the commit process.
3474 ** i.e. the database has been reorganized so that only the first pnTrunc
3475 ** pages are in use.
3476 */
3477 static int autoVacuumCommit( BtShared pBt )
3478 {
3479 int rc = SQLITE_OK;
3480 Pager pPager = pBt.pPager;
3481 // VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
3482 #if !NDEBUG || DEBUG
3483 int nRef = sqlite3PagerRefcount( pPager );
3484 #else
3485 int nRef=0;
3486 #endif
3487  
3488  
3489 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
3490 invalidateAllOverflowCache( pBt );
3491 Debug.Assert( pBt.autoVacuum );
3492 if ( !pBt.incrVacuum )
3493 {
3494 Pgno nFin; /* Number of pages in database after autovacuuming */
3495 Pgno nFree; /* Number of pages on the freelist initially */
3496 Pgno nPtrmap; /* Number of PtrMap pages to be freed */
3497 Pgno iFree; /* The next page to be freed */
3498 int nEntry; /* Number of entries on one ptrmap page */
3499 Pgno nOrig; /* Database size before freeing */
3500  
3501 nOrig = btreePagecount( pBt );
3502 if ( PTRMAP_ISPAGE( pBt, nOrig ) || nOrig == PENDING_BYTE_PAGE( pBt ) )
3503 {
3504 /* It is not possible to create a database for which the final page
3505 ** is either a pointer-map page or the pending-byte page. If one
3506 ** is encountered, this indicates corruption.
3507 */
3508 return SQLITE_CORRUPT_BKPT();
3509 }
3510  
3511 nFree = sqlite3Get4byte( pBt.pPage1.aData, 36 );
3512 nEntry = (int)pBt.usableSize / 5;
3513 nPtrmap = (Pgno)( ( nFree - nOrig + PTRMAP_PAGENO( pBt, nOrig ) + (Pgno)nEntry ) / nEntry );
3514 nFin = nOrig - nFree - nPtrmap;
3515 if ( nOrig > PENDING_BYTE_PAGE( pBt ) && nFin < PENDING_BYTE_PAGE( pBt ) )
3516 {
3517 nFin--;
3518 }
3519 while ( PTRMAP_ISPAGE( pBt, nFin ) || nFin == PENDING_BYTE_PAGE( pBt ) )
3520 {
3521 nFin--;
3522 }
3523 if ( nFin > nOrig )
3524 return SQLITE_CORRUPT_BKPT();
3525  
3526 for ( iFree = nOrig; iFree > nFin && rc == SQLITE_OK; iFree-- )
3527 {
3528 rc = incrVacuumStep( pBt, nFin, iFree );
3529 }
3530 if ( ( rc == SQLITE_DONE || rc == SQLITE_OK ) && nFree > 0 )
3531 {
3532 rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
3533 sqlite3Put4byte( pBt.pPage1.aData, 32, 0 );
3534 sqlite3Put4byte( pBt.pPage1.aData, 36, 0 );
3535 sqlite3Put4byte( pBt.pPage1.aData, (u32)28, nFin );
3536 sqlite3PagerTruncateImage( pBt.pPager, nFin );
3537 pBt.nPage = nFin;
3538 }
3539 if ( rc != SQLITE_OK )
3540 {
3541 sqlite3PagerRollback( pPager );
3542 }
3543 }
3544  
3545 Debug.Assert( nRef == sqlite3PagerRefcount( pPager ) );
3546 return rc;
3547 }
3548  
3549 #else //* ifndef SQLITE_OMIT_AUTOVACUUM */
3550 //# define setChildPtrmaps(x) SQLITE_OK
3551 #endif
3552  
3553 /*
3554 ** This routine does the first phase of a two-phase commit. This routine
3555 ** causes a rollback journal to be created (if it does not already exist)
3556 ** and populated with enough information so that if a power loss occurs
3557 ** the database can be restored to its original state by playing back
3558 ** the journal. Then the contents of the journal are flushed out to
3559 ** the disk. After the journal is safely on oxide, the changes to the
3560 ** database are written into the database file and flushed to oxide.
3561 ** At the end of this call, the rollback journal still exists on the
3562 ** disk and we are still holding all locks, so the transaction has not
3563 ** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the
3564 ** commit process.
3565 **
3566 ** This call is a no-op if no write-transaction is currently active on pBt.
3567 **
3568 ** Otherwise, sync the database file for the btree pBt. zMaster points to
3569 ** the name of a master journal file that should be written into the
3570 ** individual journal file, or is NULL, indicating no master journal file
3571 ** (single database transaction).
3572 **
3573 ** When this is called, the master journal should already have been
3574 ** created, populated with this journal pointer and synced to disk.
3575 **
3576 ** Once this is routine has returned, the only thing required to commit
3577 ** the write-transaction for this database file is to delete the journal.
3578 */
3579 static int sqlite3BtreeCommitPhaseOne( Btree p, string zMaster )
3580 {
3581 int rc = SQLITE_OK;
3582 if ( p.inTrans == TRANS_WRITE )
3583 {
3584 BtShared pBt = p.pBt;
3585 sqlite3BtreeEnter( p );
3586 #if !SQLITE_OMIT_AUTOVACUUM
3587 if ( pBt.autoVacuum )
3588 {
3589 rc = autoVacuumCommit( pBt );
3590 if ( rc != SQLITE_OK )
3591 {
3592 sqlite3BtreeLeave( p );
3593 return rc;
3594 }
3595 }
3596 #endif
3597 rc = sqlite3PagerCommitPhaseOne( pBt.pPager, zMaster, false );
3598 sqlite3BtreeLeave( p );
3599 }
3600 return rc;
3601 }
3602  
3603 /*
3604 ** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
3605 ** at the conclusion of a transaction.
3606 */
3607 static void btreeEndTransaction( Btree p )
3608 {
3609 BtShared pBt = p.pBt;
3610 Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
3611  
3612 btreeClearHasContent( pBt );
3613 if ( p.inTrans > TRANS_NONE && p.db.activeVdbeCnt > 1 )
3614 {
3615 /* If there are other active statements that belong to this database
3616 ** handle, downgrade to a read-only transaction. The other statements
3617 ** may still be reading from the database. */
3618  
3619 downgradeAllSharedCacheTableLocks( p );
3620 p.inTrans = TRANS_READ;
3621 }
3622 else
3623 {
3624 /* If the handle had any kind of transaction open, decrement the
3625 ** transaction count of the shared btree. If the transaction count
3626 ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
3627 ** call below will unlock the pager. */
3628 if ( p.inTrans != TRANS_NONE )
3629 {
3630 clearAllSharedCacheTableLocks( p );
3631 pBt.nTransaction--;
3632 if ( 0 == pBt.nTransaction )
3633 {
3634 pBt.inTransaction = TRANS_NONE;
3635 }
3636 }
3637  
3638 /* Set the current transaction state to TRANS_NONE and unlock the
3639 ** pager if this call closed the only read or write transaction. */
3640 p.inTrans = TRANS_NONE;
3641 unlockBtreeIfUnused( pBt );
3642 }
3643  
3644 btreeIntegrity( p );
3645 }
3646  
3647 /*
3648 ** Commit the transaction currently in progress.
3649 **
3650 ** This routine implements the second phase of a 2-phase commit. The
3651 ** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
3652 ** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne()
3653 ** routine did all the work of writing information out to disk and flushing the
3654 ** contents so that they are written onto the disk platter. All this
3655 ** routine has to do is delete or truncate or zero the header in the
3656 ** the rollback journal (which causes the transaction to commit) and
3657 ** drop locks.
3658 **
3659 ** Normally, if an error occurs while the pager layer is attempting to
3660 ** finalize the underlying journal file, this function returns an error and
3661 ** the upper layer will attempt a rollback. However, if the second argument
3662 ** is non-zero then this b-tree transaction is part of a multi-file
3663 ** transaction. In this case, the transaction has already been committed
3664 ** (by deleting a master journal file) and the caller will ignore this
3665 ** functions return code. So, even if an error occurs in the pager layer,
3666 ** reset the b-tree objects internal state to indicate that the write
3667 ** transaction has been closed. This is quite safe, as the pager will have
3668 ** transitioned to the error state.
3669 **
3670 ** This will release the write lock on the database file. If there
3671 ** are no active cursors, it also releases the read lock.
3672 */
3673 static int sqlite3BtreeCommitPhaseTwo( Btree p, int bCleanup)
3674 {
3675 if ( p.inTrans == TRANS_NONE )
3676 return SQLITE_OK;
3677 sqlite3BtreeEnter( p );
3678 btreeIntegrity( p );
3679  
3680 /* If the handle has a write-transaction open, commit the shared-btrees
3681 ** transaction and set the shared state to TRANS_READ.
3682 */
3683 if ( p.inTrans == TRANS_WRITE )
3684 {
3685 int rc;
3686 BtShared pBt = p.pBt;
3687 Debug.Assert( pBt.inTransaction == TRANS_WRITE );
3688 Debug.Assert( pBt.nTransaction > 0 );
3689 rc = sqlite3PagerCommitPhaseTwo( pBt.pPager );
3690 if ( rc != SQLITE_OK && bCleanup == 0 )
3691 {
3692 sqlite3BtreeLeave( p );
3693 return rc;
3694 }
3695 pBt.inTransaction = TRANS_READ;
3696 }
3697  
3698 btreeEndTransaction( p );
3699 sqlite3BtreeLeave( p );
3700 return SQLITE_OK;
3701 }
3702  
3703 /*
3704 ** Do both phases of a commit.
3705 */
3706 static int sqlite3BtreeCommit( Btree p )
3707 {
3708 int rc;
3709 sqlite3BtreeEnter( p );
3710 rc = sqlite3BtreeCommitPhaseOne( p, null );
3711 if ( rc == SQLITE_OK )
3712 {
3713 rc = sqlite3BtreeCommitPhaseTwo( p, 0 );
3714 }
3715 sqlite3BtreeLeave( p );
3716 return rc;
3717 }
3718  
3719 #if !NDEBUG || DEBUG
3720 /*
3721 ** Return the number of write-cursors open on this handle. This is for use
3722 ** in Debug.Assert() expressions, so it is only compiled if NDEBUG is not
3723 ** defined.
3724 **
3725 ** For the purposes of this routine, a write-cursor is any cursor that
3726 ** is capable of writing to the databse. That means the cursor was
3727 ** originally opened for writing and the cursor has not be disabled
3728 ** by having its state changed to CURSOR_FAULT.
3729 */
3730 static int countWriteCursors( BtShared pBt )
3731 {
3732 BtCursor pCur;
3733 int r = 0;
3734 for ( pCur = pBt.pCursor; pCur != null; pCur = pCur.pNext )
3735 {
3736 if ( pCur.wrFlag != 0 && pCur.eState != CURSOR_FAULT )
3737 r++;
3738 }
3739 return r;
3740 }
3741 #else
3742 static int countWriteCursors(BtShared pBt) { return -1; }
3743 #endif
3744  
3745 /*
3746 ** This routine sets the state to CURSOR_FAULT and the error
3747 ** code to errCode for every cursor on BtShared that pBtree
3748 ** references.
3749 **
3750 ** Every cursor is tripped, including cursors that belong
3751 ** to other database connections that happen to be sharing
3752 ** the cache with pBtree.
3753 **
3754 ** This routine gets called when a rollback occurs.
3755 ** All cursors using the same cache must be tripped
3756 ** to prevent them from trying to use the btree after
3757 ** the rollback. The rollback may have deleted tables
3758 ** or moved root pages, so it is not sufficient to
3759 ** save the state of the cursor. The cursor must be
3760 ** invalidated.
3761 */
3762 static void sqlite3BtreeTripAllCursors( Btree pBtree, int errCode )
3763 {
3764 BtCursor p;
3765 sqlite3BtreeEnter( pBtree );
3766 for ( p = pBtree.pBt.pCursor; p != null; p = p.pNext )
3767 {
3768 int i;
3769 sqlite3BtreeClearCursor( p );
3770 p.eState = CURSOR_FAULT;
3771 p.skipNext = errCode;
3772 for ( i = 0; i <= p.iPage; i++ )
3773 {
3774 releasePage( p.apPage[i] );
3775 p.apPage[i] = null;
3776 }
3777 }
3778 sqlite3BtreeLeave( pBtree );
3779 }
3780  
3781 /*
3782 ** Rollback the transaction in progress. All cursors will be
3783 ** invalided by this operation. Any attempt to use a cursor
3784 ** that was open at the beginning of this operation will result
3785 ** in an error.
3786 **
3787 ** This will release the write lock on the database file. If there
3788 ** are no active cursors, it also releases the read lock.
3789 */
3790 static int sqlite3BtreeRollback( Btree p )
3791 {
3792 int rc;
3793 BtShared pBt = p.pBt;
3794 MemPage pPage1 = new MemPage();
3795  
3796 sqlite3BtreeEnter( p );
3797 rc = saveAllCursors( pBt, 0, null );
3798 #if !SQLITE_OMIT_SHARED_CACHE
3799 if( rc!=SQLITE_OK ){
3800 /* This is a horrible situation. An IO or malloc() error occurred whilst
3801 ** trying to save cursor positions. If this is an automatic rollback (as
3802 ** the result of a constraint, malloc() failure or IO error) then
3803 ** the cache may be internally inconsistent (not contain valid trees) so
3804 ** we cannot simply return the error to the caller. Instead, abort
3805 ** all queries that may be using any of the cursors that failed to save.
3806 */
3807 sqlite3BtreeTripAllCursors(p, rc);
3808 }
3809 #endif
3810 btreeIntegrity( p );
3811  
3812 if ( p.inTrans == TRANS_WRITE )
3813 {
3814 int rc2;
3815  
3816 Debug.Assert( TRANS_WRITE == pBt.inTransaction );
3817 rc2 = sqlite3PagerRollback( pBt.pPager );
3818 if ( rc2 != SQLITE_OK )
3819 {
3820 rc = rc2;
3821 }
3822  
3823 /* The rollback may have destroyed the pPage1.aData value. So
3824 ** call btreeGetPage() on page 1 again to make
3825 ** sure pPage1.aData is set correctly. */
3826 if ( btreeGetPage( pBt, 1, ref pPage1, 0 ) == SQLITE_OK )
3827 {
3828 Pgno nPage = sqlite3Get4byte( pPage1.aData, 28 );
3829 testcase( nPage == 0 );
3830 if ( nPage == 0 )
3831 sqlite3PagerPagecount( pBt.pPager, out nPage );
3832 testcase( pBt.nPage != nPage );
3833 pBt.nPage = nPage;
3834 releasePage( pPage1 );
3835 }
3836 Debug.Assert( countWriteCursors( pBt ) == 0 );
3837 pBt.inTransaction = TRANS_READ;
3838 }
3839  
3840 btreeEndTransaction( p );
3841 sqlite3BtreeLeave( p );
3842 return rc;
3843 }
3844  
3845 /*
3846 ** Start a statement subtransaction. The subtransaction can can be rolled
3847 ** back independently of the main transaction. You must start a transaction
3848 ** before starting a subtransaction. The subtransaction is ended automatically
3849 ** if the main transaction commits or rolls back.
3850 **
3851 ** Statement subtransactions are used around individual SQL statements
3852 ** that are contained within a BEGIN...COMMIT block. If a constraint
3853 ** error occurs within the statement, the effect of that one statement
3854 ** can be rolled back without having to rollback the entire transaction.
3855 **
3856 ** A statement sub-transaction is implemented as an anonymous savepoint. The
3857 ** value passed as the second parameter is the total number of savepoints,
3858 ** including the new anonymous savepoint, open on the B-Tree. i.e. if there
3859 ** are no active savepoints and no other statement-transactions open,
3860 ** iStatement is 1. This anonymous savepoint can be released or rolled back
3861 ** using the sqlite3BtreeSavepoint() function.
3862 */
3863 static int sqlite3BtreeBeginStmt( Btree p, int iStatement )
3864 {
3865 int rc;
3866 BtShared pBt = p.pBt;
3867 sqlite3BtreeEnter( p );
3868 Debug.Assert( p.inTrans == TRANS_WRITE );
3869 Debug.Assert( !pBt.readOnly );
3870 Debug.Assert( iStatement > 0 );
3871 Debug.Assert( iStatement > p.db.nSavepoint );
3872 Debug.Assert( pBt.inTransaction == TRANS_WRITE );
3873 /* At the pager level, a statement transaction is a savepoint with
3874 ** an index greater than all savepoints created explicitly using
3875 ** SQL statements. It is illegal to open, release or rollback any
3876 ** such savepoints while the statement transaction savepoint is active.
3877 */
3878 rc = sqlite3PagerOpenSavepoint( pBt.pPager, iStatement );
3879 sqlite3BtreeLeave( p );
3880 return rc;
3881 }
3882  
3883 /*
3884 ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
3885 ** or SAVEPOINT_RELEASE. This function either releases or rolls back the
3886 ** savepoint identified by parameter iSavepoint, depending on the value
3887 ** of op.
3888 **
3889 ** Normally, iSavepoint is greater than or equal to zero. However, if op is
3890 ** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
3891 ** contents of the entire transaction are rolled back. This is different
3892 ** from a normal transaction rollback, as no locks are released and the
3893 ** transaction remains open.
3894 */
3895 static int sqlite3BtreeSavepoint( Btree p, int op, int iSavepoint )
3896 {
3897 int rc = SQLITE_OK;
3898 if ( p != null && p.inTrans == TRANS_WRITE )
3899 {
3900 BtShared pBt = p.pBt;
3901 Debug.Assert( op == SAVEPOINT_RELEASE || op == SAVEPOINT_ROLLBACK );
3902 Debug.Assert( iSavepoint >= 0 || ( iSavepoint == -1 && op == SAVEPOINT_ROLLBACK ) );
3903 sqlite3BtreeEnter( p );
3904 rc = sqlite3PagerSavepoint( pBt.pPager, op, iSavepoint );
3905 if ( rc == SQLITE_OK )
3906 {
3907 if ( iSavepoint < 0 && pBt.initiallyEmpty )
3908 pBt.nPage = 0;
3909 rc = newDatabase( pBt );
3910 pBt.nPage = sqlite3Get4byte( pBt.pPage1.aData, 28 );
3911 /* The database size was written into the offset 28 of the header
3912 ** when the transaction started, so we know that the value at offset
3913 ** 28 is nonzero. */
3914 Debug.Assert( pBt.nPage > 0 );
3915 }
3916 sqlite3BtreeLeave( p );
3917 }
3918 return rc;
3919 }
3920  
3921 /*
3922 ** Create a new cursor for the BTree whose root is on the page
3923 ** iTable. If a read-only cursor is requested, it is assumed that
3924 ** the caller already has at least a read-only transaction open
3925 ** on the database already. If a write-cursor is requested, then
3926 ** the caller is assumed to have an open write transaction.
3927 **
3928 ** If wrFlag==null, then the cursor can only be used for reading.
3929 ** If wrFlag==1, then the cursor can be used for reading or for
3930 ** writing if other conditions for writing are also met. These
3931 ** are the conditions that must be met in order for writing to
3932 ** be allowed:
3933 **
3934 ** 1: The cursor must have been opened with wrFlag==1
3935 **
3936 ** 2: Other database connections that share the same pager cache
3937 ** but which are not in the READ_UNCOMMITTED state may not have
3938 ** cursors open with wrFlag==null on the same table. Otherwise
3939 ** the changes made by this write cursor would be visible to
3940 ** the read cursors in the other database connection.
3941 **
3942 ** 3: The database must be writable (not on read-only media)
3943 **
3944 ** 4: There must be an active transaction.
3945 **
3946 ** No checking is done to make sure that page iTable really is the
3947 ** root page of a b-tree. If it is not, then the cursor acquired
3948 ** will not work correctly.
3949 **
3950 ** It is assumed that the sqlite3BtreeCursorZero() has been called
3951 ** on pCur to initialize the memory space prior to invoking this routine.
3952 */
3953 static int btreeCursor(
3954 Btree p, /* The btree */
3955 int iTable, /* Root page of table to open */
3956 int wrFlag, /* 1 to write. 0 read-only */
3957 KeyInfo pKeyInfo, /* First arg to comparison function */
3958 BtCursor pCur /* Space for new cursor */
3959 )
3960 {
3961 BtShared pBt = p.pBt; /* Shared b-tree handle */
3962  
3963 Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
3964 Debug.Assert( wrFlag == 0 || wrFlag == 1 );
3965  
3966 /* The following Debug.Assert statements verify that if this is a sharable
3967 ** b-tree database, the connection is holding the required table locks,
3968 ** and that no other connection has any open cursor that conflicts with
3969 ** this lock. */
3970 Debug.Assert( hasSharedCacheTableLock( p, (u32)iTable, pKeyInfo != null ? 1 : 0, wrFlag + 1 ) );
3971 Debug.Assert( wrFlag == 0 || !hasReadConflicts( p, (u32)iTable ) );
3972  
3973 /* Assert that the caller has opened the required transaction. */
3974 Debug.Assert( p.inTrans > TRANS_NONE );
3975 Debug.Assert( wrFlag == 0 || p.inTrans == TRANS_WRITE );
3976 Debug.Assert( pBt.pPage1 != null && pBt.pPage1.aData != null );
3977  
3978 if ( NEVER( wrFlag != 0 && pBt.readOnly ) )
3979 {
3980 return SQLITE_READONLY;
3981 }
3982 if ( iTable == 1 && btreePagecount( pBt ) == 0 )
3983 {
3984 return SQLITE_EMPTY;
3985 }
3986  
3987 /* Now that no other errors can occur, finish filling in the BtCursor
3988 ** variables and link the cursor into the BtShared list. */
3989 pCur.pgnoRoot = (Pgno)iTable;
3990 pCur.iPage = -1;
3991 pCur.pKeyInfo = pKeyInfo;
3992 pCur.pBtree = p;
3993 pCur.pBt = pBt;
3994 pCur.wrFlag = (u8)wrFlag;
3995 pCur.pNext = pBt.pCursor;
3996 if ( pCur.pNext != null )
3997 {
3998 pCur.pNext.pPrev = pCur;
3999 }
4000 pBt.pCursor = pCur;
4001 pCur.eState = CURSOR_INVALID;
4002 pCur.cachedRowid = 0;
4003 return SQLITE_OK;
4004 }
4005 static int sqlite3BtreeCursor(
4006 Btree p, /* The btree */
4007 int iTable, /* Root page of table to open */
4008 int wrFlag, /* 1 to write. 0 read-only */
4009 KeyInfo pKeyInfo, /* First arg to xCompare() */
4010 BtCursor pCur /* Write new cursor here */
4011 )
4012 {
4013 int rc;
4014 sqlite3BtreeEnter( p );
4015 rc = btreeCursor( p, iTable, wrFlag, pKeyInfo, pCur );
4016 sqlite3BtreeLeave( p );
4017 return rc;
4018 }
4019  
4020 /*
4021 ** Return the size of a BtCursor object in bytes.
4022 **
4023 ** This interfaces is needed so that users of cursors can preallocate
4024 ** sufficient storage to hold a cursor. The BtCursor object is opaque
4025 ** to users so they cannot do the sizeof() themselves - they must call
4026 ** this routine.
4027 */
4028 static int sqlite3BtreeCursorSize()
4029 {
4030 return -1; // Not Used -- return ROUND8(sizeof(BtCursor));
4031 }
4032  
4033 /*
4034 ** Initialize memory that will be converted into a BtCursor object.
4035 **
4036 ** The simple approach here would be to memset() the entire object
4037 ** to zero. But it turns out that the apPage[] and aiIdx[] arrays
4038 ** do not need to be zeroed and they are large, so we can save a lot
4039 ** of run-time by skipping the initialization of those elements.
4040 */
4041 static void sqlite3BtreeCursorZero( BtCursor p )
4042 {
4043 p.Clear(); // memset( p, 0, offsetof( BtCursor, iPage ) );
4044 }
4045  
4046 /*
4047 ** Set the cached rowid value of every cursor in the same database file
4048 ** as pCur and having the same root page number as pCur. The value is
4049 ** set to iRowid.
4050 **
4051 ** Only positive rowid values are considered valid for this cache.
4052 ** The cache is initialized to zero, indicating an invalid cache.
4053 ** A btree will work fine with zero or negative rowids. We just cannot
4054 ** cache zero or negative rowids, which means tables that use zero or
4055 ** negative rowids might run a little slower. But in practice, zero
4056 ** or negative rowids are very uncommon so this should not be a problem.
4057 */
4058 static void sqlite3BtreeSetCachedRowid( BtCursor pCur, sqlite3_int64 iRowid )
4059 {
4060 BtCursor p;
4061 for ( p = pCur.pBt.pCursor; p != null; p = p.pNext )
4062 {
4063 if ( p.pgnoRoot == pCur.pgnoRoot )
4064 p.cachedRowid = iRowid;
4065 }
4066 Debug.Assert( pCur.cachedRowid == iRowid );
4067 }
4068  
4069 /*
4070 ** Return the cached rowid for the given cursor. A negative or zero
4071 ** return value indicates that the rowid cache is invalid and should be
4072 ** ignored. If the rowid cache has never before been set, then a
4073 ** zero is returned.
4074 */
4075 static sqlite3_int64 sqlite3BtreeGetCachedRowid( BtCursor pCur )
4076 {
4077 return pCur.cachedRowid;
4078 }
4079  
4080 /*
4081 ** Close a cursor. The read lock on the database file is released
4082 ** when the last cursor is closed.
4083 */
4084 static int sqlite3BtreeCloseCursor( BtCursor pCur )
4085 {
4086 Btree pBtree = pCur.pBtree;
4087 if ( pBtree != null )
4088 {
4089 int i;
4090 BtShared pBt = pCur.pBt;
4091 sqlite3BtreeEnter( pBtree );
4092 sqlite3BtreeClearCursor( pCur );
4093 if ( pCur.pPrev != null )
4094 {
4095 pCur.pPrev.pNext = pCur.pNext;
4096 }
4097 else
4098 {
4099 pBt.pCursor = pCur.pNext;
4100 }
4101 if ( pCur.pNext != null )
4102 {
4103 pCur.pNext.pPrev = pCur.pPrev;
4104 }
4105 for ( i = 0; i <= pCur.iPage; i++ )
4106 {
4107 releasePage( pCur.apPage[i] );
4108 }
4109 unlockBtreeIfUnused( pBt );
4110 invalidateOverflowCache( pCur );
4111 /* sqlite3_free(ref pCur); */
4112 sqlite3BtreeLeave( pBtree );
4113 }
4114 return SQLITE_OK;
4115 }
4116  
4117 /*
4118 ** Make sure the BtCursor* given in the argument has a valid
4119 ** BtCursor.info structure. If it is not already valid, call
4120 ** btreeParseCell() to fill it in.
4121 **
4122 ** BtCursor.info is a cache of the information in the current cell.
4123 ** Using this cache reduces the number of calls to btreeParseCell().
4124 **
4125 ** 2007-06-25: There is a bug in some versions of MSVC that cause the
4126 ** compiler to crash when getCellInfo() is implemented as a macro.
4127 ** But there is a measureable speed advantage to using the macro on gcc
4128 ** (when less compiler optimizations like -Os or -O0 are used and the
4129 ** compiler is not doing agressive inlining.) So we use a real function
4130 ** for MSVC and a macro for everything else. Ticket #2457.
4131 */
4132 #if !NDEBUG
4133 static void assertCellInfo( BtCursor pCur )
4134 {
4135 CellInfo info;
4136 int iPage = pCur.iPage;
4137 info = new CellInfo();//memset(info, 0, sizeof(info));
4138 btreeParseCell( pCur.apPage[iPage], pCur.aiIdx[iPage], ref info );
4139 Debug.Assert( info.GetHashCode() == pCur.info.GetHashCode() || info.Equals( pCur.info ) );//memcmp(info, pCur.info, sizeof(info))==0 );
4140 }
4141 #else
4142 // #define assertCellInfo(x)
4143 static void assertCellInfo(BtCursor pCur) { }
4144 #endif
4145  
4146 ////#if _MSC_VER
4147 /* Use a real function in MSVC to work around bugs in that compiler. */
4148 static void getCellInfo( BtCursor pCur )
4149 {
4150 if ( pCur.info.nSize == 0 )
4151 {
4152 int iPage = pCur.iPage;
4153 btreeParseCell( pCur.apPage[iPage], pCur.aiIdx[iPage], ref pCur.info );
4154 pCur.validNKey = true;
4155 }
4156 else
4157 {
4158 assertCellInfo( pCur );
4159 }
4160 }
4161 ////#else //* if not _MSC_VER */
4162 ///* Use a macro in all other compilers so that the function is inlined */
4163 ////#define getCellInfo(pCur) \
4164 //// if( pCur.info.nSize==null ){ \
4165 //// int iPage = pCur.iPage; \
4166 //// btreeParseCell(pCur.apPage[iPage],pCur.aiIdx[iPage],&pCur.info); \
4167 //// pCur.validNKey = true; \
4168 //// }else{ \
4169 //// assertCellInfo(pCur); \
4170 //// }
4171 ////#endif //* _MSC_VER */
4172  
4173 #if !NDEBUG //* The next routine used only within Debug.Assert() statements */
4174 /*
4175 ** Return true if the given BtCursor is valid. A valid cursor is one
4176 ** that is currently pointing to a row in a (non-empty) table.
4177 ** This is a verification routine is used only within Debug.Assert() statements.
4178 */
4179 static bool sqlite3BtreeCursorIsValid( BtCursor pCur )
4180 {
4181 return pCur != null && pCur.eState == CURSOR_VALID;
4182 }
4183 #else
4184 static bool sqlite3BtreeCursorIsValid(BtCursor pCur) { return true; }
4185 #endif //* NDEBUG */
4186  
4187 /*
4188 ** Set pSize to the size of the buffer needed to hold the value of
4189 ** the key for the current entry. If the cursor is not pointing
4190 ** to a valid entry, pSize is set to 0.
4191 **
4192 ** For a table with the INTKEY flag set, this routine returns the key
4193 ** itself, not the number of bytes in the key.
4194 **
4195 ** The caller must position the cursor prior to invoking this routine.
4196 **
4197 ** This routine cannot fail. It always returns SQLITE_OK.
4198 */
4199 static int sqlite3BtreeKeySize( BtCursor pCur, ref i64 pSize )
4200 {
4201 Debug.Assert( cursorHoldsMutex( pCur ) );
4202 Debug.Assert( pCur.eState == CURSOR_INVALID || pCur.eState == CURSOR_VALID );
4203 if ( pCur.eState != CURSOR_VALID )
4204 {
4205 pSize = 0;
4206 }
4207 else
4208 {
4209 getCellInfo( pCur );
4210 pSize = pCur.info.nKey;
4211 }
4212 return SQLITE_OK;
4213 }
4214  
4215 /*
4216 ** Set pSize to the number of bytes of data in the entry the
4217 ** cursor currently points to.
4218 **
4219 ** The caller must guarantee that the cursor is pointing to a non-NULL
4220 ** valid entry. In other words, the calling procedure must guarantee
4221 ** that the cursor has Cursor.eState==CURSOR_VALID.
4222 **
4223 ** Failure is not possible. This function always returns SQLITE_OK.
4224 ** It might just as well be a procedure (returning void) but we continue
4225 ** to return an integer result code for historical reasons.
4226 */
4227 static int sqlite3BtreeDataSize( BtCursor pCur, ref u32 pSize )
4228 {
4229 Debug.Assert( cursorHoldsMutex( pCur ) );
4230 Debug.Assert( pCur.eState == CURSOR_VALID );
4231 getCellInfo( pCur );
4232 pSize = pCur.info.nData;
4233 return SQLITE_OK;
4234 }
4235  
4236 /*
4237 ** Given the page number of an overflow page in the database (parameter
4238 ** ovfl), this function finds the page number of the next page in the
4239 ** linked list of overflow pages. If possible, it uses the auto-vacuum
4240 ** pointer-map data instead of reading the content of page ovfl to do so.
4241 **
4242 ** If an error occurs an SQLite error code is returned. Otherwise:
4243 **
4244 ** The page number of the next overflow page in the linked list is
4245 ** written to pPgnoNext. If page ovfl is the last page in its linked
4246 ** list, pPgnoNext is set to zero.
4247 **
4248 ** If ppPage is not NULL, and a reference to the MemPage object corresponding
4249 ** to page number pOvfl was obtained, then ppPage is set to point to that
4250 ** reference. It is the responsibility of the caller to call releasePage()
4251 ** on ppPage to free the reference. In no reference was obtained (because
4252 ** the pointer-map was used to obtain the value for pPgnoNext), then
4253 ** ppPage is set to zero.
4254 */
4255 static int getOverflowPage(
4256 BtShared pBt, /* The database file */
4257 Pgno ovfl, /* Current overflow page number */
4258 out MemPage ppPage, /* OUT: MemPage handle (may be NULL) */
4259 out Pgno pPgnoNext /* OUT: Next overflow page number */
4260 )
4261 {
4262 Pgno next = 0;
4263 MemPage pPage = null;
4264 ppPage = null;
4265 int rc = SQLITE_OK;
4266  
4267 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
4268 // Debug.Assert( pPgnoNext);
4269  
4270 #if !SQLITE_OMIT_AUTOVACUUM
4271 /* Try to find the next page in the overflow list using the
4272 ** autovacuum pointer-map pages. Guess that the next page in
4273 ** the overflow list is page number (ovfl+1). If that guess turns
4274 ** out to be wrong, fall back to loading the data of page
4275 ** number ovfl to determine the next page number.
4276 */
4277 if ( pBt.autoVacuum )
4278 {
4279 Pgno pgno = 0;
4280 Pgno iGuess = ovfl + 1;
4281 u8 eType = 0;
4282  
4283 while ( PTRMAP_ISPAGE( pBt, iGuess ) || iGuess == PENDING_BYTE_PAGE( pBt ) )
4284 {
4285 iGuess++;
4286 }
4287  
4288 if ( iGuess <= btreePagecount( pBt ) )
4289 {
4290 rc = ptrmapGet( pBt, iGuess, ref eType, ref pgno );
4291 if ( rc == SQLITE_OK && eType == PTRMAP_OVERFLOW2 && pgno == ovfl )
4292 {
4293 next = iGuess;
4294 rc = SQLITE_DONE;
4295 }
4296 }
4297 }
4298 #endif
4299  
4300 Debug.Assert( next == 0 || rc == SQLITE_DONE );
4301 if ( rc == SQLITE_OK )
4302 {
4303 rc = btreeGetPage( pBt, ovfl, ref pPage, 0 );
4304 Debug.Assert( rc == SQLITE_OK || pPage == null );
4305 if ( rc == SQLITE_OK )
4306 {
4307 next = sqlite3Get4byte( pPage.aData );
4308 }
4309 }
4310  
4311 pPgnoNext = next;
4312 if ( ppPage != null )
4313 {
4314 ppPage = pPage;
4315 }
4316 else
4317 {
4318 releasePage( pPage );
4319 }
4320 return ( rc == SQLITE_DONE ? SQLITE_OK : rc );
4321 }
4322  
4323 /*
4324 ** Copy data from a buffer to a page, or from a page to a buffer.
4325 **
4326 ** pPayload is a pointer to data stored on database page pDbPage.
4327 ** If argument eOp is false, then nByte bytes of data are copied
4328 ** from pPayload to the buffer pointed at by pBuf. If eOp is true,
4329 ** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
4330 ** of data are copied from the buffer pBuf to pPayload.
4331 **
4332 ** SQLITE_OK is returned on success, otherwise an error code.
4333 */
4334 static int copyPayload(
4335 byte[] pPayload, /* Pointer to page data */
4336 u32 payloadOffset, /* Offset into page data */
4337 byte[] pBuf, /* Pointer to buffer */
4338 u32 pBufOffset, /* Offset into buffer */
4339 u32 nByte, /* Number of bytes to copy */
4340 int eOp, /* 0 . copy from page, 1 . copy to page */
4341 DbPage pDbPage /* Page containing pPayload */
4342 )
4343 {
4344 if ( eOp != 0 )
4345 {
4346 /* Copy data from buffer to page (a write operation) */
4347 int rc = sqlite3PagerWrite( pDbPage );
4348 if ( rc != SQLITE_OK )
4349 {
4350 return rc;
4351 }
4352 Buffer.BlockCopy( pBuf, (int)pBufOffset, pPayload, (int)payloadOffset, (int)nByte );// memcpy( pPayload, pBuf, nByte );
4353 }
4354 else
4355 {
4356 /* Copy data from page to buffer (a read operation) */
4357 Buffer.BlockCopy( pPayload, (int)payloadOffset, pBuf, (int)pBufOffset, (int)nByte );//memcpy(pBuf, pPayload, nByte);
4358 }
4359 return SQLITE_OK;
4360 }
4361 //static int copyPayload(
4362 // byte[] pPayload, /* Pointer to page data */
4363 // byte[] pBuf, /* Pointer to buffer */
4364 // int nByte, /* Number of bytes to copy */
4365 // int eOp, /* 0 -> copy from page, 1 -> copy to page */
4366 // DbPage pDbPage /* Page containing pPayload */
4367 //){
4368 // if( eOp!=0 ){
4369 // /* Copy data from buffer to page (a write operation) */
4370 // int rc = sqlite3PagerWrite(pDbPage);
4371 // if( rc!=SQLITE_OK ){
4372 // return rc;
4373 // }
4374 // memcpy(pPayload, pBuf, nByte);
4375 // }else{
4376 // /* Copy data from page to buffer (a read operation) */
4377 // memcpy(pBuf, pPayload, nByte);
4378 // }
4379 // return SQLITE_OK;
4380 //}
4381  
4382 /*
4383 ** This function is used to read or overwrite payload information
4384 ** for the entry that the pCur cursor is pointing to. If the eOp
4385 ** parameter is 0, this is a read operation (data copied into
4386 ** buffer pBuf). If it is non-zero, a write (data copied from
4387 ** buffer pBuf).
4388 **
4389 ** A total of "amt" bytes are read or written beginning at "offset".
4390 ** Data is read to or from the buffer pBuf.
4391 **
4392 ** The content being read or written might appear on the main page
4393 ** or be scattered out on multiple overflow pages.
4394 **
4395 ** If the BtCursor.isIncrblobHandle flag is set, and the current
4396 ** cursor entry uses one or more overflow pages, this function
4397 ** allocates space for and lazily popluates the overflow page-list
4398 ** cache array (BtCursor.aOverflow). Subsequent calls use this
4399 ** cache to make seeking to the supplied offset more efficient.
4400 **
4401 ** Once an overflow page-list cache has been allocated, it may be
4402 ** invalidated if some other cursor writes to the same table, or if
4403 ** the cursor is moved to a different row. Additionally, in auto-vacuum
4404 ** mode, the following events may invalidate an overflow page-list cache.
4405 **
4406 ** * An incremental vacuum,
4407 ** * A commit in auto_vacuum="full" mode,
4408 ** * Creating a table (may require moving an overflow page).
4409 */
4410 static int accessPayload(
4411 BtCursor pCur, /* Cursor pointing to entry to read from */
4412 u32 offset, /* Begin reading this far into payload */
4413 u32 amt, /* Read this many bytes */
4414 byte[] pBuf, /* Write the bytes into this buffer */
4415 int eOp /* zero to read. non-zero to write. */
4416 )
4417 {
4418 u32 pBufOffset = 0;
4419 byte[] aPayload;
4420 int rc = SQLITE_OK;
4421 u32 nKey;
4422 int iIdx = 0;
4423 MemPage pPage = pCur.apPage[pCur.iPage]; /* Btree page of current entry */
4424 BtShared pBt = pCur.pBt; /* Btree this cursor belongs to */
4425  
4426 Debug.Assert( pPage != null );
4427 Debug.Assert( pCur.eState == CURSOR_VALID );
4428 Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
4429 Debug.Assert( cursorHoldsMutex( pCur ) );
4430  
4431 getCellInfo( pCur );
4432 aPayload = pCur.info.pCell; //pCur.info.pCell + pCur.info.nHeader;
4433 nKey = (u32)( pPage.intKey != 0 ? 0 : (int)pCur.info.nKey );
4434  
4435 if ( NEVER( offset + amt > nKey + pCur.info.nData )
4436 || pCur.info.nLocal > pBt.usableSize//&aPayload[pCur.info.nLocal] > &pPage.aData[pBt.usableSize]
4437 )
4438 {
4439 /* Trying to read or write past the end of the data is an error */
4440 return SQLITE_CORRUPT_BKPT();
4441 }
4442  
4443 /* Check if data must be read/written to/from the btree page itself. */
4444 if ( offset < pCur.info.nLocal )
4445 {
4446 int a = (int)amt;
4447 if ( a + offset > pCur.info.nLocal )
4448 {
4449 a = (int)( pCur.info.nLocal - offset );
4450 }
4451 rc = copyPayload( aPayload, (u32)( offset + pCur.info.iCell + pCur.info.nHeader ), pBuf, pBufOffset, (u32)a, eOp, pPage.pDbPage );
4452 offset = 0;
4453 pBufOffset += (u32)a; //pBuf += a;
4454 amt -= (u32)a;
4455 }
4456 else
4457 {
4458 offset -= pCur.info.nLocal;
4459 }
4460  
4461 if ( rc == SQLITE_OK && amt > 0 )
4462 {
4463 u32 ovflSize = (u32)( pBt.usableSize - 4 ); /* Bytes content per ovfl page */
4464 Pgno nextPage;
4465  
4466 nextPage = sqlite3Get4byte( aPayload, pCur.info.nLocal + pCur.info.iCell + pCur.info.nHeader );
4467  
4468 #if !SQLITE_OMIT_INCRBLOB
4469 /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
4470 ** has not been allocated, allocate it now. The array is sized at
4471 ** one entry for each overflow page in the overflow chain. The
4472 ** page number of the first overflow page is stored in aOverflow[0],
4473 ** etc. A value of 0 in the aOverflow[] array means "not yet known"
4474 ** (the cache is lazily populated).
4475 */
4476 if( pCur.isIncrblobHandle && !pCur.aOverflow ){
4477 int nOvfl = (pCur.info.nPayload-pCur.info.nLocal+ovflSize-1)/ovflSize;
4478 pCur.aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
4479 /* nOvfl is always positive. If it were zero, fetchPayload would have
4480 ** been used instead of this routine. */
4481 if( ALWAYS(nOvfl) && !pCur.aOverflow ){
4482 rc = SQLITE_NOMEM;
4483 }
4484 }
4485  
4486 /* If the overflow page-list cache has been allocated and the
4487 ** entry for the first required overflow page is valid, skip
4488 ** directly to it.
4489 */
4490 if( pCur.aOverflow && pCur.aOverflow[offset/ovflSize] ){
4491 iIdx = (offset/ovflSize);
4492 nextPage = pCur.aOverflow[iIdx];
4493 offset = (offset%ovflSize);
4494 }
4495 #endif
4496  
4497 for ( ; rc == SQLITE_OK && amt > 0 && nextPage != 0; iIdx++ )
4498 {
4499  
4500 #if !SQLITE_OMIT_INCRBLOB
4501 /* If required, populate the overflow page-list cache. */
4502 if( pCur.aOverflow ){
4503 Debug.Assert(!pCur.aOverflow[iIdx] || pCur.aOverflow[iIdx]==nextPage);
4504 pCur.aOverflow[iIdx] = nextPage;
4505 }
4506 #endif
4507  
4508 MemPage MemPageDummy = null;
4509 if ( offset >= ovflSize )
4510 {
4511 /* The only reason to read this page is to obtain the page
4512 ** number for the next page in the overflow chain. The page
4513 ** data is not required. So first try to lookup the overflow
4514 ** page-list cache, if any, then fall back to the getOverflowPage()
4515 ** function.
4516 */
4517 #if !SQLITE_OMIT_INCRBLOB
4518 if( pCur.aOverflow && pCur.aOverflow[iIdx+1] ){
4519 nextPage = pCur.aOverflow[iIdx+1];
4520 } else
4521 #endif
4522 rc = getOverflowPage( pBt, nextPage, out MemPageDummy, out nextPage );
4523 offset -= ovflSize;
4524 }
4525 else
4526 {
4527 /* Need to read this page properly. It contains some of the
4528 ** range of data that is being read (eOp==null) or written (eOp!=null).
4529 */
4530 PgHdr pDbPage = new PgHdr();
4531 int a = (int)amt;
4532 rc = sqlite3PagerGet( pBt.pPager, nextPage, ref pDbPage );
4533 if ( rc == SQLITE_OK )
4534 {
4535 aPayload = sqlite3PagerGetData( pDbPage );
4536 nextPage = sqlite3Get4byte( aPayload );
4537 if ( a + offset > ovflSize )
4538 {
4539 a = (int)( ovflSize - offset );
4540 }
4541 rc = copyPayload( aPayload, offset + 4, pBuf, pBufOffset, (u32)a, eOp, pDbPage );
4542 sqlite3PagerUnref( pDbPage );
4543 offset = 0;
4544 amt -= (u32)a;
4545 pBufOffset += (u32)a;//pBuf += a;
4546 }
4547 }
4548 }
4549 }
4550  
4551 if ( rc == SQLITE_OK && amt > 0 )
4552 {
4553 return SQLITE_CORRUPT_BKPT();
4554 }
4555 return rc;
4556 }
4557  
4558 /*
4559 ** Read part of the key associated with cursor pCur. Exactly
4560 ** "amt" bytes will be transfered into pBuf[]. The transfer
4561 ** begins at "offset".
4562 **
4563 ** The caller must ensure that pCur is pointing to a valid row
4564 ** in the table.
4565 **
4566 ** Return SQLITE_OK on success or an error code if anything goes
4567 ** wrong. An error is returned if "offset+amt" is larger than
4568 ** the available payload.
4569 */
4570 static int sqlite3BtreeKey( BtCursor pCur, u32 offset, u32 amt, byte[] pBuf )
4571 {
4572 Debug.Assert( cursorHoldsMutex( pCur ) );
4573 Debug.Assert( pCur.eState == CURSOR_VALID );
4574 Debug.Assert( pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
4575 Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
4576 return accessPayload( pCur, offset, amt, pBuf, 0 );
4577 }
4578  
4579 /*
4580 ** Read part of the data associated with cursor pCur. Exactly
4581 ** "amt" bytes will be transfered into pBuf[]. The transfer
4582 ** begins at "offset".
4583 **
4584 ** Return SQLITE_OK on success or an error code if anything goes
4585 ** wrong. An error is returned if "offset+amt" is larger than
4586 ** the available payload.
4587 */
4588 static int sqlite3BtreeData( BtCursor pCur, u32 offset, u32 amt, byte[] pBuf )
4589 {
4590 int rc;
4591  
4592 #if !SQLITE_OMIT_INCRBLOB
4593 if ( pCur.eState==CURSOR_INVALID ){
4594 return SQLITE_ABORT;
4595 }
4596 #endif
4597  
4598 Debug.Assert( cursorHoldsMutex( pCur ) );
4599 rc = restoreCursorPosition( pCur );
4600 if ( rc == SQLITE_OK )
4601 {
4602 Debug.Assert( pCur.eState == CURSOR_VALID );
4603 Debug.Assert( pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
4604 Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
4605 rc = accessPayload( pCur, offset, amt, pBuf, 0 );
4606 }
4607 return rc;
4608 }
4609  
4610 /*
4611 ** Return a pointer to payload information from the entry that the
4612 ** pCur cursor is pointing to. The pointer is to the beginning of
4613 ** the key if skipKey==null and it points to the beginning of data if
4614 ** skipKey==1. The number of bytes of available key/data is written
4615 ** into pAmt. If pAmt==null, then the value returned will not be
4616 ** a valid pointer.
4617 **
4618 ** This routine is an optimization. It is common for the entire key
4619 ** and data to fit on the local page and for there to be no overflow
4620 ** pages. When that is so, this routine can be used to access the
4621 ** key and data without making a copy. If the key and/or data spills
4622 ** onto overflow pages, then accessPayload() must be used to reassemble
4623 ** the key/data and copy it into a preallocated buffer.
4624 **
4625 ** The pointer returned by this routine looks directly into the cached
4626 ** page of the database. The data might change or move the next time
4627 ** any btree routine is called.
4628 */
4629 static byte[] fetchPayload(
4630 BtCursor pCur, /* Cursor pointing to entry to read from */
4631 ref int pAmt, /* Write the number of available bytes here */
4632 ref int outOffset, /* Offset into Buffer */
4633 bool skipKey /* read beginning at data if this is true */
4634 )
4635 {
4636 byte[] aPayload;
4637 MemPage pPage;
4638 u32 nKey;
4639 u32 nLocal;
4640  
4641 Debug.Assert( pCur != null && pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
4642 Debug.Assert( pCur.eState == CURSOR_VALID );
4643 Debug.Assert( cursorHoldsMutex( pCur ) );
4644 outOffset = -1;
4645 pPage = pCur.apPage[pCur.iPage];
4646 Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
4647 if ( NEVER( pCur.info.nSize == 0 ) )
4648 {
4649 btreeParseCell( pCur.apPage[pCur.iPage], pCur.aiIdx[pCur.iPage],
4650 ref pCur.info );
4651 }
4652 //aPayload = pCur.info.pCell;
4653 //aPayload += pCur.info.nHeader;
4654 aPayload = sqlite3Malloc( pCur.info.nSize - pCur.info.nHeader );
4655 if ( pPage.intKey != 0 )
4656 {
4657 nKey = 0;
4658 }
4659 else
4660 {
4661 nKey = (u32)pCur.info.nKey;
4662 }
4663 if ( skipKey )
4664 {
4665 //aPayload += nKey;
4666 outOffset = (int)( pCur.info.iCell + pCur.info.nHeader + nKey );
4667 Buffer.BlockCopy( pCur.info.pCell, outOffset, aPayload, 0, (int)( pCur.info.nSize - pCur.info.nHeader - nKey ) );
4668 nLocal = pCur.info.nLocal - nKey;
4669 }
4670 else
4671 {
4672 outOffset = (int)( pCur.info.iCell + pCur.info.nHeader );
4673 Buffer.BlockCopy( pCur.info.pCell, outOffset, aPayload, 0, pCur.info.nSize - pCur.info.nHeader );
4674 nLocal = pCur.info.nLocal;
4675 Debug.Assert( nLocal <= nKey );
4676 }
4677 pAmt = (int)nLocal;
4678 return aPayload;
4679 }
4680  
4681 /*
4682 ** For the entry that cursor pCur is point to, return as
4683 ** many bytes of the key or data as are available on the local
4684 ** b-tree page. Write the number of available bytes into pAmt.
4685 **
4686 ** The pointer returned is ephemeral. The key/data may move
4687 ** or be destroyed on the next call to any Btree routine,
4688 ** including calls from other threads against the same cache.
4689 ** Hence, a mutex on the BtShared should be held prior to calling
4690 ** this routine.
4691 **
4692 ** These routines is used to get quick access to key and data
4693 ** in the common case where no overflow pages are used.
4694 */
4695 static byte[] sqlite3BtreeKeyFetch( BtCursor pCur, ref int pAmt, ref int outOffset )
4696 {
4697 byte[] p = null;
4698 Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
4699 Debug.Assert( cursorHoldsMutex( pCur ) );
4700 if ( ALWAYS( pCur.eState == CURSOR_VALID ) )
4701 {
4702 p = fetchPayload( pCur, ref pAmt, ref outOffset, false );
4703 }
4704 return p;
4705 }
4706 static byte[] sqlite3BtreeDataFetch( BtCursor pCur, ref int pAmt, ref int outOffset )
4707 {
4708 byte[] p = null;
4709 Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
4710 Debug.Assert( cursorHoldsMutex( pCur ) );
4711 if ( ALWAYS( pCur.eState == CURSOR_VALID ) )
4712 {
4713 p = fetchPayload( pCur, ref pAmt, ref outOffset, true );
4714 }
4715 return p;
4716 }
4717  
4718 /*
4719 ** Move the cursor down to a new child page. The newPgno argument is the
4720 ** page number of the child page to move to.
4721 **
4722 ** This function returns SQLITE_CORRUPT if the page-header flags field of
4723 ** the new child page does not match the flags field of the parent (i.e.
4724 ** if an intkey page appears to be the parent of a non-intkey page, or
4725 ** vice-versa).
4726 */
4727 static int moveToChild( BtCursor pCur, u32 newPgno )
4728 {
4729 int rc;
4730 int i = pCur.iPage;
4731 MemPage pNewPage = new MemPage();
4732 BtShared pBt = pCur.pBt;
4733  
4734 Debug.Assert( cursorHoldsMutex( pCur ) );
4735 Debug.Assert( pCur.eState == CURSOR_VALID );
4736 Debug.Assert( pCur.iPage < BTCURSOR_MAX_DEPTH );
4737 if ( pCur.iPage >= ( BTCURSOR_MAX_DEPTH - 1 ) )
4738 {
4739 return SQLITE_CORRUPT_BKPT();
4740 }
4741 rc = getAndInitPage( pBt, newPgno, ref pNewPage );
4742 if ( rc != 0 )
4743 return rc;
4744 pCur.apPage[i + 1] = pNewPage;
4745 pCur.aiIdx[i + 1] = 0;
4746 pCur.iPage++;
4747  
4748 pCur.info.nSize = 0;
4749 pCur.validNKey = false;
4750 if ( pNewPage.nCell < 1 || pNewPage.intKey != pCur.apPage[i].intKey )
4751 {
4752 return SQLITE_CORRUPT_BKPT();
4753 }
4754 return SQLITE_OK;
4755 }
4756  
4757 #if !NDEBUG
4758 /*
4759 ** Page pParent is an internal (non-leaf) tree page. This function
4760 ** asserts that page number iChild is the left-child if the iIdx'th
4761 ** cell in page pParent. Or, if iIdx is equal to the total number of
4762 ** cells in pParent, that page number iChild is the right-child of
4763 ** the page.
4764 */
4765 static void assertParentIndex( MemPage pParent, int iIdx, Pgno iChild )
4766 {
4767 Debug.Assert( iIdx <= pParent.nCell );
4768 if ( iIdx == pParent.nCell )
4769 {
4770 Debug.Assert( sqlite3Get4byte( pParent.aData, pParent.hdrOffset + 8 ) == iChild );
4771 }
4772 else
4773 {
4774 Debug.Assert( sqlite3Get4byte( pParent.aData, findCell( pParent, iIdx ) ) == iChild );
4775 }
4776 }
4777 #else
4778 //# define assertParentIndex(x,y,z)
4779 static void assertParentIndex(MemPage pParent, int iIdx, Pgno iChild) { }
4780 #endif
4781  
4782 /*
4783 ** Move the cursor up to the parent page.
4784 **
4785 ** pCur.idx is set to the cell index that contains the pointer
4786 ** to the page we are coming from. If we are coming from the
4787 ** right-most child page then pCur.idx is set to one more than
4788 ** the largest cell index.
4789 */
4790 static void moveToParent( BtCursor pCur )
4791 {
4792 Debug.Assert( cursorHoldsMutex( pCur ) );
4793 Debug.Assert( pCur.eState == CURSOR_VALID );
4794 Debug.Assert( pCur.iPage > 0 );
4795 Debug.Assert( pCur.apPage[pCur.iPage] != null );
4796 assertParentIndex(
4797 pCur.apPage[pCur.iPage - 1],
4798 pCur.aiIdx[pCur.iPage - 1],
4799 pCur.apPage[pCur.iPage].pgno
4800 );
4801 releasePage( pCur.apPage[pCur.iPage] );
4802 pCur.iPage--;
4803 pCur.info.nSize = 0;
4804 pCur.validNKey = false;
4805 }
4806  
4807 /*
4808 ** Move the cursor to point to the root page of its b-tree structure.
4809 **
4810 ** If the table has a virtual root page, then the cursor is moved to point
4811 ** to the virtual root page instead of the actual root page. A table has a
4812 ** virtual root page when the actual root page contains no cells and a
4813 ** single child page. This can only happen with the table rooted at page 1.
4814 **
4815 ** If the b-tree structure is empty, the cursor state is set to
4816 ** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
4817 ** cell located on the root (or virtual root) page and the cursor state
4818 ** is set to CURSOR_VALID.
4819 **
4820 ** If this function returns successfully, it may be assumed that the
4821 ** page-header flags indicate that the [virtual] root-page is the expected
4822 ** kind of b-tree page (i.e. if when opening the cursor the caller did not
4823 ** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
4824 ** indicating a table b-tree, or if the caller did specify a KeyInfo
4825 ** structure the flags byte is set to 0x02 or 0x0A, indicating an index
4826 ** b-tree).
4827 */
4828 static int moveToRoot( BtCursor pCur )
4829 {
4830 MemPage pRoot;
4831 int rc = SQLITE_OK;
4832 Btree p = pCur.pBtree;
4833 BtShared pBt = p.pBt;
4834  
4835 Debug.Assert( cursorHoldsMutex( pCur ) );
4836 Debug.Assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
4837 Debug.Assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
4838 Debug.Assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
4839 if ( pCur.eState >= CURSOR_REQUIRESEEK )
4840 {
4841 if ( pCur.eState == CURSOR_FAULT )
4842 {
4843 Debug.Assert( pCur.skipNext != SQLITE_OK );
4844 return pCur.skipNext;
4845 }
4846 sqlite3BtreeClearCursor( pCur );
4847 }
4848  
4849 if ( pCur.iPage >= 0 )
4850 {
4851 int i;
4852 for ( i = 1; i <= pCur.iPage; i++ )
4853 {
4854 releasePage( pCur.apPage[i] );
4855 }
4856 pCur.iPage = 0;
4857 }
4858 else
4859 {
4860 rc = getAndInitPage( pBt, pCur.pgnoRoot, ref pCur.apPage[0] );
4861 if ( rc != SQLITE_OK )
4862 {
4863 pCur.eState = CURSOR_INVALID;
4864 return rc;
4865 }
4866 pCur.iPage = 0;
4867  
4868 /* If pCur.pKeyInfo is not NULL, then the caller that opened this cursor
4869 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
4870 ** NULL, the caller expects a table b-tree. If this is not the case,
4871 ** return an SQLITE_CORRUPT error. */
4872 Debug.Assert( pCur.apPage[0].intKey == 1 || pCur.apPage[0].intKey == 0 );
4873 if ( ( pCur.pKeyInfo == null ) != ( pCur.apPage[0].intKey != 0 ) )
4874 {
4875 return SQLITE_CORRUPT_BKPT();
4876 }
4877 }
4878  
4879 /* Assert that the root page is of the correct type. This must be the
4880 ** case as the call to this function that loaded the root-page (either
4881 ** this call or a previous invocation) would have detected corruption
4882 ** if the assumption were not true, and it is not possible for the flags
4883 ** byte to have been modified while this cursor is holding a reference
4884 ** to the page. */
4885 pRoot = pCur.apPage[0];
4886 Debug.Assert( pRoot.pgno == pCur.pgnoRoot );
4887 Debug.Assert( pRoot.isInit != 0 && ( pCur.pKeyInfo == null ) == ( pRoot.intKey != 0 ) );
4888  
4889 pCur.aiIdx[0] = 0;
4890 pCur.info.nSize = 0;
4891 pCur.atLast = 0;
4892 pCur.validNKey = false;
4893  
4894 if ( pRoot.nCell == 0 && 0 == pRoot.leaf )
4895 {
4896 Pgno subpage;
4897 if ( pRoot.pgno != 1 )
4898 return SQLITE_CORRUPT_BKPT();
4899 subpage = sqlite3Get4byte( pRoot.aData, pRoot.hdrOffset + 8 );
4900 pCur.eState = CURSOR_VALID;
4901 rc = moveToChild( pCur, subpage );
4902 }
4903 else
4904 {
4905 pCur.eState = ( ( pRoot.nCell > 0 ) ? CURSOR_VALID : CURSOR_INVALID );
4906 }
4907 return rc;
4908 }
4909  
4910 /*
4911 ** Move the cursor down to the left-most leaf entry beneath the
4912 ** entry to which it is currently pointing.
4913 **
4914 ** The left-most leaf is the one with the smallest key - the first
4915 ** in ascending order.
4916 */
4917 static int moveToLeftmost( BtCursor pCur )
4918 {
4919 Pgno pgno;
4920 int rc = SQLITE_OK;
4921 MemPage pPage;
4922  
4923 Debug.Assert( cursorHoldsMutex( pCur ) );
4924 Debug.Assert( pCur.eState == CURSOR_VALID );
4925 while ( rc == SQLITE_OK && 0 == ( pPage = pCur.apPage[pCur.iPage] ).leaf )
4926 {
4927 Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
4928 pgno = sqlite3Get4byte( pPage.aData, findCell( pPage, pCur.aiIdx[pCur.iPage] ) );
4929 rc = moveToChild( pCur, pgno );
4930 }
4931 return rc;
4932 }
4933  
4934 /*
4935 ** Move the cursor down to the right-most leaf entry beneath the
4936 ** page to which it is currently pointing. Notice the difference
4937 ** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
4938 ** finds the left-most entry beneath the *entry* whereas moveToRightmost()
4939 ** finds the right-most entry beneath the page*.
4940 **
4941 ** The right-most entry is the one with the largest key - the last
4942 ** key in ascending order.
4943 */
4944 static int moveToRightmost( BtCursor pCur )
4945 {
4946 Pgno pgno;
4947 int rc = SQLITE_OK;
4948 MemPage pPage = null;
4949  
4950 Debug.Assert( cursorHoldsMutex( pCur ) );
4951 Debug.Assert( pCur.eState == CURSOR_VALID );
4952 while ( rc == SQLITE_OK && 0 == ( pPage = pCur.apPage[pCur.iPage] ).leaf )
4953 {
4954 pgno = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
4955 pCur.aiIdx[pCur.iPage] = pPage.nCell;
4956 rc = moveToChild( pCur, pgno );
4957 }
4958 if ( rc == SQLITE_OK )
4959 {
4960 pCur.aiIdx[pCur.iPage] = (u16)( pPage.nCell - 1 );
4961 pCur.info.nSize = 0;
4962 pCur.validNKey = false;
4963 }
4964 return rc;
4965 }
4966  
4967 /* Move the cursor to the first entry in the table. Return SQLITE_OK
4968 ** on success. Set pRes to 0 if the cursor actually points to something
4969 ** or set pRes to 1 if the table is empty.
4970 */
4971 static int sqlite3BtreeFirst( BtCursor pCur, ref int pRes )
4972 {
4973 int rc;
4974  
4975 Debug.Assert( cursorHoldsMutex( pCur ) );
4976 Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
4977 rc = moveToRoot( pCur );
4978 if ( rc == SQLITE_OK )
4979 {
4980 if ( pCur.eState == CURSOR_INVALID )
4981 {
4982 Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
4983 pRes = 1;
4984 }
4985 else
4986 {
4987 Debug.Assert( pCur.apPage[pCur.iPage].nCell > 0 );
4988 pRes = 0;
4989 rc = moveToLeftmost( pCur );
4990 }
4991 }
4992 return rc;
4993 }
4994  
4995 /* Move the cursor to the last entry in the table. Return SQLITE_OK
4996 ** on success. Set pRes to 0 if the cursor actually points to something
4997 ** or set pRes to 1 if the table is empty.
4998 */
4999 static int sqlite3BtreeLast( BtCursor pCur, ref int pRes )
5000 {
5001 int rc;
5002  
5003 Debug.Assert( cursorHoldsMutex( pCur ) );
5004 Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
5005  
5006 /* If the cursor already points to the last entry, this is a no-op. */
5007 if ( CURSOR_VALID == pCur.eState && pCur.atLast != 0 )
5008 {
5009 #if SQLITE_DEBUG
5010 /* This block serves to Debug.Assert() that the cursor really does point
5011 ** to the last entry in the b-tree. */
5012 int ii;
5013 for ( ii = 0; ii < pCur.iPage; ii++ )
5014 {
5015 Debug.Assert( pCur.aiIdx[ii] == pCur.apPage[ii].nCell );
5016 }
5017 Debug.Assert( pCur.aiIdx[pCur.iPage] == pCur.apPage[pCur.iPage].nCell - 1 );
5018 Debug.Assert( pCur.apPage[pCur.iPage].leaf != 0 );
5019 #endif
5020 return SQLITE_OK;
5021 }
5022  
5023 rc = moveToRoot( pCur );
5024 if ( rc == SQLITE_OK )
5025 {
5026 if ( CURSOR_INVALID == pCur.eState )
5027 {
5028 Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
5029 pRes = 1;
5030 }
5031 else
5032 {
5033 Debug.Assert( pCur.eState == CURSOR_VALID );
5034 pRes = 0;
5035 rc = moveToRightmost( pCur );
5036 pCur.atLast = (u8)( rc == SQLITE_OK ? 1 : 0 );
5037 }
5038 }
5039 return rc;
5040 }
5041  
5042 /* Move the cursor so that it points to an entry near the key
5043 ** specified by pIdxKey or intKey. Return a success code.
5044 **
5045 ** For INTKEY tables, the intKey parameter is used. pIdxKey
5046 ** must be NULL. For index tables, pIdxKey is used and intKey
5047 ** is ignored.
5048 **
5049 ** If an exact match is not found, then the cursor is always
5050 ** left pointing at a leaf page which would hold the entry if it
5051 ** were present. The cursor might point to an entry that comes
5052 ** before or after the key.
5053 **
5054 ** An integer is written into pRes which is the result of
5055 ** comparing the key with the entry to which the cursor is
5056 ** pointing. The meaning of the integer written into
5057 ** pRes is as follows:
5058 **
5059 ** pRes<0 The cursor is left pointing at an entry that
5060 ** is smaller than intKey/pIdxKey or if the table is empty
5061 ** and the cursor is therefore left point to nothing.
5062 **
5063 ** pRes==null The cursor is left pointing at an entry that
5064 ** exactly matches intKey/pIdxKey.
5065 **
5066 ** pRes>0 The cursor is left pointing at an entry that
5067 ** is larger than intKey/pIdxKey.
5068 **
5069 */
5070 static int sqlite3BtreeMovetoUnpacked(
5071 BtCursor pCur, /* The cursor to be moved */
5072 UnpackedRecord pIdxKey, /* Unpacked index key */
5073 i64 intKey, /* The table key */
5074 int biasRight, /* If true, bias the search to the high end */
5075 ref int pRes /* Write search results here */
5076 )
5077 {
5078 int rc;
5079  
5080 Debug.Assert( cursorHoldsMutex( pCur ) );
5081 Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
5082 // Not needed in C# // Debug.Assert( pRes != 0 );
5083 Debug.Assert( ( pIdxKey == null ) == ( pCur.pKeyInfo == null ) );
5084  
5085 /* If the cursor is already positioned at the point we are trying
5086 ** to move to, then just return without doing any work */
5087 if ( pCur.eState == CURSOR_VALID && pCur.validNKey
5088 && pCur.apPage[0].intKey != 0
5089 )
5090 {
5091 if ( pCur.info.nKey == intKey )
5092 {
5093 pRes = 0;
5094 return SQLITE_OK;
5095 }
5096 if ( pCur.atLast != 0 && pCur.info.nKey < intKey )
5097 {
5098 pRes = -1;
5099 return SQLITE_OK;
5100 }
5101 }
5102  
5103 rc = moveToRoot( pCur );
5104 if ( rc != 0 )
5105 {
5106 return rc;
5107 }
5108 Debug.Assert( pCur.apPage[pCur.iPage] != null );
5109 Debug.Assert( pCur.apPage[pCur.iPage].isInit != 0 );
5110 Debug.Assert( pCur.apPage[pCur.iPage].nCell > 0 || pCur.eState == CURSOR_INVALID );
5111 if ( pCur.eState == CURSOR_INVALID )
5112 {
5113 pRes = -1;
5114 Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
5115 return SQLITE_OK;
5116 }
5117 Debug.Assert( pCur.apPage[0].intKey != 0 || pIdxKey != null );
5118 for ( ; ; )
5119 {
5120 int lwr, upr, idx;
5121 Pgno chldPg;
5122 MemPage pPage = pCur.apPage[pCur.iPage];
5123 int c;
5124  
5125 /* pPage.nCell must be greater than zero. If this is the root-page
5126 ** the cursor would have been INVALID above and this for(;;) loop
5127 ** not run. If this is not the root-page, then the moveToChild() routine
5128 ** would have already detected db corruption. Similarly, pPage must
5129 ** be the right kind (index or table) of b-tree page. Otherwise
5130 ** a moveToChild() or moveToRoot() call would have detected corruption. */
5131 Debug.Assert( pPage.nCell > 0 );
5132 Debug.Assert( pPage.intKey == ( ( pIdxKey == null ) ? 1 : 0 ) );
5133 lwr = 0;
5134 upr = pPage.nCell - 1;
5135 if ( biasRight != 0 )
5136 {
5137 pCur.aiIdx[pCur.iPage] = (u16)( idx = upr );
5138 }
5139 else
5140 {
5141 pCur.aiIdx[pCur.iPage] = (u16)( idx = ( upr + lwr ) / 2 );
5142 }
5143 for ( ; ; )
5144 {
5145 int pCell; /* Pointer to current cell in pPage */
5146  
5147 Debug.Assert( idx == pCur.aiIdx[pCur.iPage] );
5148 pCur.info.nSize = 0;
5149 pCell = findCell( pPage, idx ) + pPage.childPtrSize;
5150 if ( pPage.intKey != 0 )
5151 {
5152 i64 nCellKey = 0;
5153 if ( pPage.hasData != 0 )
5154 {
5155 u32 Dummy0 = 0;
5156 pCell += getVarint32( pPage.aData, pCell, out Dummy0 );
5157 }
5158 getVarint( pPage.aData, pCell, out nCellKey );
5159 if ( nCellKey == intKey )
5160 {
5161 c = 0;
5162 }
5163 else if ( nCellKey < intKey )
5164 {
5165 c = -1;
5166 }
5167 else
5168 {
5169 Debug.Assert( nCellKey > intKey );
5170 c = +1;
5171 }
5172 pCur.validNKey = true;
5173 pCur.info.nKey = nCellKey;
5174 }
5175 else
5176 {
5177 /* The maximum supported page-size is 65536 bytes. This means that
5178 ** the maximum number of record bytes stored on an index B-Tree
5179 ** page is less than 16384 bytes and may be stored as a 2-byte
5180 ** varint. This information is used to attempt to avoid parsing
5181 ** the entire cell by checking for the cases where the record is
5182 ** stored entirely within the b-tree page by inspecting the first
5183 ** 2 bytes of the cell.
5184 */
5185 int nCell = pPage.aData[pCell + 0]; //pCell[0];
5186 if ( 0 == ( nCell & 0x80 ) && nCell <= pPage.maxLocal )
5187 {
5188 /* This branch runs if the record-size field of the cell is a
5189 ** single byte varint and the record fits entirely on the main
5190 ** b-tree page. */
5191 c = sqlite3VdbeRecordCompare( nCell, pPage.aData, pCell + 1, pIdxKey ); //c = sqlite3VdbeRecordCompare( nCell, (void*)&pCell[1], pIdxKey );
5192 }
5193 else if ( 0 == ( pPage.aData[pCell + 1] & 0x80 )//!(pCell[1] & 0x80)
5194 && ( nCell = ( ( nCell & 0x7f ) << 7 ) + pPage.aData[pCell + 1] ) <= pPage.maxLocal//pCell[1])<=pPage.maxLocal
5195 )
5196 {
5197 /* The record-size field is a 2 byte varint and the record
5198 ** fits entirely on the main b-tree page. */
5199 c = sqlite3VdbeRecordCompare( nCell, pPage.aData, pCell + 2, pIdxKey ); //c = sqlite3VdbeRecordCompare( nCell, (void*)&pCell[2], pIdxKey );
5200 }
5201 else
5202 {
5203 /* The record flows over onto one or more overflow pages. In
5204 ** this case the whole cell needs to be parsed, a buffer allocated
5205 ** and accessPayload() used to retrieve the record into the
5206 ** buffer before VdbeRecordCompare() can be called. */
5207 u8[] pCellKey;
5208 u8[] pCellBody = new u8[pPage.aData.Length - pCell + pPage.childPtrSize];
5209 Buffer.BlockCopy( pPage.aData, pCell - pPage.childPtrSize, pCellBody, 0, pCellBody.Length );// u8 * const pCellBody = pCell - pPage->childPtrSize;
5210 btreeParseCellPtr( pPage, pCellBody, ref pCur.info );
5211 nCell = (int)pCur.info.nKey;
5212 pCellKey = sqlite3Malloc( nCell );
5213 //if ( pCellKey == null )
5214 //{
5215 // rc = SQLITE_NOMEM;
5216 // goto moveto_finish;
5217 //}
5218 rc = accessPayload( pCur, 0, (u32)nCell, pCellKey, 0 );
5219 if ( rc != 0 )
5220 {
5221 pCellKey = null;// sqlite3_free(ref pCellKey );
5222 goto moveto_finish;
5223 }
5224 c = sqlite3VdbeRecordCompare( nCell, pCellKey, pIdxKey );
5225 pCellKey = null;// sqlite3_free(ref pCellKey );
5226 }
5227 }
5228 if ( c == 0 )
5229 {
5230 if ( pPage.intKey != 0 && 0 == pPage.leaf )
5231 {
5232 lwr = idx;
5233 upr = lwr - 1;
5234 break;
5235 }
5236 else
5237 {
5238 pRes = 0;
5239 rc = SQLITE_OK;
5240 goto moveto_finish;
5241 }
5242 }
5243 if ( c < 0 )
5244 {
5245 lwr = idx + 1;
5246 }
5247 else
5248 {
5249 upr = idx - 1;
5250 }
5251 if ( lwr > upr )
5252 {
5253 break;
5254 }
5255 pCur.aiIdx[pCur.iPage] = (u16)( idx = ( lwr + upr ) / 2 );
5256 }
5257 Debug.Assert( lwr == upr + 1 );
5258 Debug.Assert( pPage.isInit != 0 );
5259 if ( pPage.leaf != 0 )
5260 {
5261 chldPg = 0;
5262 }
5263 else if ( lwr >= pPage.nCell )
5264 {
5265 chldPg = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
5266 }
5267 else
5268 {
5269 chldPg = sqlite3Get4byte( pPage.aData, findCell( pPage, lwr ) );
5270 }
5271 if ( chldPg == 0 )
5272 {
5273 Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
5274 pRes = c;
5275 rc = SQLITE_OK;
5276 goto moveto_finish;
5277 }
5278 pCur.aiIdx[pCur.iPage] = (u16)lwr;
5279 pCur.info.nSize = 0;
5280 pCur.validNKey = false;
5281 rc = moveToChild( pCur, chldPg );
5282 if ( rc != 0 )
5283 goto moveto_finish;
5284 }
5285 moveto_finish:
5286 return rc;
5287 }
5288  
5289  
5290 /*
5291 ** Return TRUE if the cursor is not pointing at an entry of the table.
5292 **
5293 ** TRUE will be returned after a call to sqlite3BtreeNext() moves
5294 ** past the last entry in the table or sqlite3BtreePrev() moves past
5295 ** the first entry. TRUE is also returned if the table is empty.
5296 */
5297 static bool sqlite3BtreeEof( BtCursor pCur )
5298 {
5299 /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
5300 ** have been deleted? This API will need to change to return an error code
5301 ** as well as the boolean result value.
5302 */
5303 return ( CURSOR_VALID != pCur.eState );
5304 }
5305  
5306 /*
5307 ** Advance the cursor to the next entry in the database. If
5308 ** successful then set pRes=0. If the cursor
5309 ** was already pointing to the last entry in the database before
5310 ** this routine was called, then set pRes=1.
5311 */
5312 static int sqlite3BtreeNext( BtCursor pCur, ref int pRes )
5313 {
5314 int rc;
5315 int idx;
5316 MemPage pPage;
5317  
5318 Debug.Assert( cursorHoldsMutex( pCur ) );
5319 rc = restoreCursorPosition( pCur );
5320 if ( rc != SQLITE_OK )
5321 {
5322 return rc;
5323 }
5324 // Not needed in C# // Debug.Assert( pRes != 0 );
5325 if ( CURSOR_INVALID == pCur.eState )
5326 {
5327 pRes = 1;
5328 return SQLITE_OK;
5329 }
5330 if ( pCur.skipNext > 0 )
5331 {
5332 pCur.skipNext = 0;
5333 pRes = 0;
5334 return SQLITE_OK;
5335 }
5336 pCur.skipNext = 0;
5337  
5338 pPage = pCur.apPage[pCur.iPage];
5339 idx = ++pCur.aiIdx[pCur.iPage];
5340 Debug.Assert( pPage.isInit != 0 );
5341 Debug.Assert( idx <= pPage.nCell );
5342  
5343 pCur.info.nSize = 0;
5344 pCur.validNKey = false;
5345 if ( idx >= pPage.nCell )
5346 {
5347 if ( 0 == pPage.leaf )
5348 {
5349 rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) );
5350 if ( rc != 0 )
5351 return rc;
5352 rc = moveToLeftmost( pCur );
5353 pRes = 0;
5354 return rc;
5355 }
5356 do
5357 {
5358 if ( pCur.iPage == 0 )
5359 {
5360 pRes = 1;
5361 pCur.eState = CURSOR_INVALID;
5362 return SQLITE_OK;
5363 }
5364 moveToParent( pCur );
5365 pPage = pCur.apPage[pCur.iPage];
5366 } while ( pCur.aiIdx[pCur.iPage] >= pPage.nCell );
5367 pRes = 0;
5368 if ( pPage.intKey != 0 )
5369 {
5370 rc = sqlite3BtreeNext( pCur, ref pRes );
5371 }
5372 else
5373 {
5374 rc = SQLITE_OK;
5375 }
5376 return rc;
5377 }
5378 pRes = 0;
5379 if ( pPage.leaf != 0 )
5380 {
5381 return SQLITE_OK;
5382 }
5383 rc = moveToLeftmost( pCur );
5384 return rc;
5385 }
5386  
5387  
5388 /*
5389 ** Step the cursor to the back to the previous entry in the database. If
5390 ** successful then set pRes=0. If the cursor
5391 ** was already pointing to the first entry in the database before
5392 ** this routine was called, then set pRes=1.
5393 */
5394 static int sqlite3BtreePrevious( BtCursor pCur, ref int pRes )
5395 {
5396 int rc;
5397 MemPage pPage;
5398  
5399 Debug.Assert( cursorHoldsMutex( pCur ) );
5400 rc = restoreCursorPosition( pCur );
5401 if ( rc != SQLITE_OK )
5402 {
5403 return rc;
5404 }
5405 pCur.atLast = 0;
5406 if ( CURSOR_INVALID == pCur.eState )
5407 {
5408 pRes = 1;
5409 return SQLITE_OK;
5410 }
5411 if ( pCur.skipNext < 0 )
5412 {
5413 pCur.skipNext = 0;
5414 pRes = 0;
5415 return SQLITE_OK;
5416 }
5417 pCur.skipNext = 0;
5418  
5419 pPage = pCur.apPage[pCur.iPage];
5420 Debug.Assert( pPage.isInit != 0 );
5421 if ( 0 == pPage.leaf )
5422 {
5423 int idx = pCur.aiIdx[pCur.iPage];
5424 rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, findCell( pPage, idx ) ) );
5425 if ( rc != 0 )
5426 {
5427 return rc;
5428 }
5429 rc = moveToRightmost( pCur );
5430 }
5431 else
5432 {
5433 while ( pCur.aiIdx[pCur.iPage] == 0 )
5434 {
5435 if ( pCur.iPage == 0 )
5436 {
5437 pCur.eState = CURSOR_INVALID;
5438 pRes = 1;
5439 return SQLITE_OK;
5440 }
5441 moveToParent( pCur );
5442 }
5443 pCur.info.nSize = 0;
5444 pCur.validNKey = false;
5445  
5446 pCur.aiIdx[pCur.iPage]--;
5447 pPage = pCur.apPage[pCur.iPage];
5448 if ( pPage.intKey != 0 && 0 == pPage.leaf )
5449 {
5450 rc = sqlite3BtreePrevious( pCur, ref pRes );
5451 }
5452 else
5453 {
5454 rc = SQLITE_OK;
5455 }
5456 }
5457 pRes = 0;
5458 return rc;
5459 }
5460  
5461 /*
5462 ** Allocate a new page from the database file.
5463 **
5464 ** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
5465 ** has already been called on the new page.) The new page has also
5466 ** been referenced and the calling routine is responsible for calling
5467 ** sqlite3PagerUnref() on the new page when it is done.
5468 **
5469 ** SQLITE_OK is returned on success. Any other return value indicates
5470 ** an error. ppPage and pPgno are undefined in the event of an error.
5471 ** Do not invoke sqlite3PagerUnref() on ppPage if an error is returned.
5472 **
5473 ** If the "nearby" parameter is not 0, then a (feeble) effort is made to
5474 ** locate a page close to the page number "nearby". This can be used in an
5475 ** attempt to keep related pages close to each other in the database file,
5476 ** which in turn can make database access faster.
5477 **
5478 ** If the "exact" parameter is not 0, and the page-number nearby exists
5479 ** anywhere on the free-list, then it is guarenteed to be returned. This
5480 ** is only used by auto-vacuum databases when allocating a new table.
5481 */
5482 static int allocateBtreePage(
5483 BtShared pBt,
5484 ref MemPage ppPage,
5485 ref Pgno pPgno,
5486 Pgno nearby,
5487 u8 exact
5488 )
5489 {
5490 MemPage pPage1;
5491 int rc;
5492 u32 n; /* Number of pages on the freelist */
5493 u32 k; /* Number of leaves on the trunk of the freelist */
5494 MemPage pTrunk = null;
5495 MemPage pPrevTrunk = null;
5496 Pgno mxPage; /* Total size of the database file */
5497  
5498 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
5499 pPage1 = pBt.pPage1;
5500 mxPage = btreePagecount( pBt );
5501 n = sqlite3Get4byte( pPage1.aData, 36 );
5502 testcase( n == mxPage - 1 );
5503 if ( n >= mxPage )
5504 {
5505 return SQLITE_CORRUPT_BKPT();
5506 }
5507 if ( n > 0 )
5508 {
5509 /* There are pages on the freelist. Reuse one of those pages. */
5510 Pgno iTrunk;
5511 u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
5512  
5513 /* If the 'exact' parameter was true and a query of the pointer-map
5514 ** shows that the page 'nearby' is somewhere on the free-list, then
5515 ** the entire-list will be searched for that page.
5516 */
5517 #if !SQLITE_OMIT_AUTOVACUUM
5518 if ( exact != 0 && nearby <= mxPage )
5519 {
5520 u8 eType = 0;
5521 Debug.Assert( nearby > 0 );
5522 Debug.Assert( pBt.autoVacuum );
5523 u32 Dummy0 = 0;
5524 rc = ptrmapGet( pBt, nearby, ref eType, ref Dummy0 );
5525 if ( rc != 0 )
5526 return rc;
5527 if ( eType == PTRMAP_FREEPAGE )
5528 {
5529 searchList = 1;
5530 }
5531 pPgno = nearby;
5532 }
5533 #endif
5534  
5535 /* Decrement the free-list count by 1. Set iTrunk to the index of the
5536 ** first free-list trunk page. iPrevTrunk is initially 1.
5537 */
5538 rc = sqlite3PagerWrite( pPage1.pDbPage );
5539 if ( rc != 0 )
5540 return rc;
5541 sqlite3Put4byte( pPage1.aData, (u32)36, n - 1 );
5542  
5543 /* The code within this loop is run only once if the 'searchList' variable
5544 ** is not true. Otherwise, it runs once for each trunk-page on the
5545 ** free-list until the page 'nearby' is located.
5546 */
5547 do
5548 {
5549 pPrevTrunk = pTrunk;
5550 if ( pPrevTrunk != null )
5551 {
5552 iTrunk = sqlite3Get4byte( pPrevTrunk.aData, 0 );
5553 }
5554 else
5555 {
5556 iTrunk = sqlite3Get4byte( pPage1.aData, 32 );
5557 }
5558 testcase( iTrunk == mxPage );
5559 if ( iTrunk > mxPage )
5560 {
5561 rc = SQLITE_CORRUPT_BKPT();
5562 }
5563 else
5564 {
5565 rc = btreeGetPage( pBt, iTrunk, ref pTrunk, 0 );
5566 }
5567 if ( rc != 0 )
5568 {
5569 pTrunk = null;
5570 goto end_allocate_page;
5571 }
5572  
5573 k = sqlite3Get4byte( pTrunk.aData, 4 ); /* # of leaves on this trunk page */
5574 if ( k == 0 && 0 == searchList )
5575 {
5576 /* The trunk has no leaves and the list is not being searched.
5577 ** So extract the trunk page itself and use it as the newly
5578 ** allocated page */
5579 Debug.Assert( pPrevTrunk == null );
5580 rc = sqlite3PagerWrite( pTrunk.pDbPage );
5581 if ( rc != 0 )
5582 {
5583 goto end_allocate_page;
5584 }
5585 pPgno = iTrunk;
5586 Buffer.BlockCopy( pTrunk.aData, 0, pPage1.aData, 32, 4 );//memcpy( pPage1.aData[32], ref pTrunk.aData[0], 4 );
5587 ppPage = pTrunk;
5588 pTrunk = null;
5589 TRACE( "ALLOCATE: %d trunk - %d free pages left\n", pPgno, n - 1 );
5590 }
5591 else if ( k > (u32)( pBt.usableSize / 4 - 2 ) )
5592 {
5593 /* Value of k is out of range. Database corruption */
5594 rc = SQLITE_CORRUPT_BKPT();
5595 goto end_allocate_page;
5596 #if !SQLITE_OMIT_AUTOVACUUM
5597 }
5598 else if ( searchList != 0 && nearby == iTrunk )
5599 {
5600 /* The list is being searched and this trunk page is the page
5601 ** to allocate, regardless of whether it has leaves.
5602 */
5603 Debug.Assert( pPgno == iTrunk );
5604 ppPage = pTrunk;
5605 searchList = 0;
5606 rc = sqlite3PagerWrite( pTrunk.pDbPage );
5607 if ( rc != 0 )
5608 {
5609 goto end_allocate_page;
5610 }
5611 if ( k == 0 )
5612 {
5613 if ( null == pPrevTrunk )
5614 {
5615 //memcpy(pPage1.aData[32], pTrunk.aData[0], 4);
5616 pPage1.aData[32 + 0] = pTrunk.aData[0 + 0];
5617 pPage1.aData[32 + 1] = pTrunk.aData[0 + 1];
5618 pPage1.aData[32 + 2] = pTrunk.aData[0 + 2];
5619 pPage1.aData[32 + 3] = pTrunk.aData[0 + 3];
5620 }
5621 else
5622 {
5623 rc = sqlite3PagerWrite( pPrevTrunk.pDbPage );
5624 if ( rc != SQLITE_OK )
5625 {
5626 goto end_allocate_page;
5627 }
5628 //memcpy(pPrevTrunk.aData[0], pTrunk.aData[0], 4);
5629 pPrevTrunk.aData[0 + 0] = pTrunk.aData[0 + 0];
5630 pPrevTrunk.aData[0 + 1] = pTrunk.aData[0 + 1];
5631 pPrevTrunk.aData[0 + 2] = pTrunk.aData[0 + 2];
5632 pPrevTrunk.aData[0 + 3] = pTrunk.aData[0 + 3];
5633 }
5634 }
5635 else
5636 {
5637 /* The trunk page is required by the caller but it contains
5638 ** pointers to free-list leaves. The first leaf becomes a trunk
5639 ** page in this case.
5640 */
5641 MemPage pNewTrunk = new MemPage();
5642 Pgno iNewTrunk = sqlite3Get4byte( pTrunk.aData, 8 );
5643 if ( iNewTrunk > mxPage )
5644 {
5645 rc = SQLITE_CORRUPT_BKPT();
5646 goto end_allocate_page;
5647 }
5648 testcase( iNewTrunk == mxPage );
5649 rc = btreeGetPage( pBt, iNewTrunk, ref pNewTrunk, 0 );
5650 if ( rc != SQLITE_OK )
5651 {
5652 goto end_allocate_page;
5653 }
5654 rc = sqlite3PagerWrite( pNewTrunk.pDbPage );
5655 if ( rc != SQLITE_OK )
5656 {
5657 releasePage( pNewTrunk );
5658 goto end_allocate_page;
5659 }
5660 //memcpy(pNewTrunk.aData[0], pTrunk.aData[0], 4);
5661 pNewTrunk.aData[0 + 0] = pTrunk.aData[0 + 0];
5662 pNewTrunk.aData[0 + 1] = pTrunk.aData[0 + 1];
5663 pNewTrunk.aData[0 + 2] = pTrunk.aData[0 + 2];
5664 pNewTrunk.aData[0 + 3] = pTrunk.aData[0 + 3];
5665 sqlite3Put4byte( pNewTrunk.aData, (u32)4, (u32)( k - 1 ) );
5666 Buffer.BlockCopy( pTrunk.aData, 12, pNewTrunk.aData, 8, (int)( k - 1 ) * 4 );//memcpy( pNewTrunk.aData[8], ref pTrunk.aData[12], ( k - 1 ) * 4 );
5667 releasePage( pNewTrunk );
5668 if ( null == pPrevTrunk )
5669 {
5670 Debug.Assert( sqlite3PagerIswriteable( pPage1.pDbPage ) );
5671 sqlite3Put4byte( pPage1.aData, (u32)32, iNewTrunk );
5672 }
5673 else
5674 {
5675 rc = sqlite3PagerWrite( pPrevTrunk.pDbPage );
5676 if ( rc != 0 )
5677 {
5678 goto end_allocate_page;
5679 }
5680 sqlite3Put4byte( pPrevTrunk.aData, (u32)0, iNewTrunk );
5681 }
5682 }
5683 pTrunk = null;
5684 TRACE( "ALLOCATE: %d trunk - %d free pages left\n", pPgno, n - 1 );
5685 #endif
5686 }
5687 else if ( k > 0 )
5688 {
5689 /* Extract a leaf from the trunk */
5690 u32 closest;
5691 Pgno iPage;
5692 byte[] aData = pTrunk.aData;
5693 if ( nearby > 0 )
5694 {
5695 u32 i;
5696 int dist;
5697 closest = 0;
5698 dist = sqlite3AbsInt32( (int)(sqlite3Get4byte( aData, 8 ) - nearby ));
5699 for ( i = 1; i < k; i++ )
5700 {
5701 int d2 = sqlite3AbsInt32( (int)(sqlite3Get4byte( aData, 8 + i * 4 ) - nearby ));
5702 if ( d2 < dist )
5703 {
5704 closest = i;
5705 dist = d2;
5706 }
5707 }
5708 }
5709 else
5710 {
5711 closest = 0;
5712 }
5713  
5714 iPage = sqlite3Get4byte( aData, 8 + closest * 4 );
5715 testcase( iPage == mxPage );
5716 if ( iPage > mxPage )
5717 {
5718 rc = SQLITE_CORRUPT_BKPT();
5719 goto end_allocate_page;
5720 }
5721 testcase( iPage == mxPage );
5722 if ( 0 == searchList || iPage == nearby )
5723 {
5724 int noContent;
5725 pPgno = iPage;
5726 TRACE( "ALLOCATE: %d was leaf %d of %d on trunk %d" +
5727 ": %d more free pages\n",
5728 pPgno, closest + 1, k, pTrunk.pgno, n - 1 );
5729 rc = sqlite3PagerWrite( pTrunk.pDbPage );
5730 if ( rc != 0)
5731 goto end_allocate_page;
5732 if ( closest < k - 1 )
5733 {
5734 Buffer.BlockCopy( aData, (int)( 4 + k * 4 ), aData, 8 + (int)closest * 4, 4 );//memcpy( aData[8 + closest * 4], ref aData[4 + k * 4], 4 );
5735 }
5736 sqlite3Put4byte( aData, (u32)4, ( k - 1 ) );// sqlite3Put4byte( aData, 4, k - 1 );
5737 noContent = !btreeGetHasContent( pBt, pPgno ) ? 1 : 0;
5738 rc = btreeGetPage( pBt, pPgno, ref ppPage, noContent );
5739 if ( rc == SQLITE_OK )
5740 {
5741 rc = sqlite3PagerWrite( ( ppPage ).pDbPage );
5742 if ( rc != SQLITE_OK )
5743 {
5744 releasePage( ppPage );
5745 }
5746 }
5747 searchList = 0;
5748 }
5749 }
5750 releasePage( pPrevTrunk );
5751 pPrevTrunk = null;
5752 } while ( searchList != 0 );
5753 }
5754 else
5755 {
5756 /* There are no pages on the freelist, so create a new page at the
5757 ** end of the file */
5758 rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
5759 if ( rc != 0 )
5760 return rc;
5761 pBt.nPage++;
5762 if ( pBt.nPage == PENDING_BYTE_PAGE( pBt ) )
5763 pBt.nPage++;
5764  
5765 #if !SQLITE_OMIT_AUTOVACUUM
5766 if ( pBt.autoVacuum && PTRMAP_ISPAGE( pBt, pBt.nPage ) )
5767 {
5768 /* If pPgno refers to a pointer-map page, allocate two new pages
5769 ** at the end of the file instead of one. The first allocated page
5770 ** becomes a new pointer-map page, the second is used by the caller.
5771 */
5772 MemPage pPg = null;
5773 TRACE( "ALLOCATE: %d from end of file (pointer-map page)\n", pPgno );
5774 Debug.Assert( pBt.nPage != PENDING_BYTE_PAGE( pBt ) );
5775 rc = btreeGetPage( pBt, pBt.nPage, ref pPg, 1 );
5776 if ( rc == SQLITE_OK )
5777 {
5778 rc = sqlite3PagerWrite( pPg.pDbPage );
5779 releasePage( pPg );
5780 }
5781 if ( rc != 0 )
5782 return rc;
5783 pBt.nPage++;
5784 if ( pBt.nPage == PENDING_BYTE_PAGE( pBt ) )
5785 {
5786 pBt.nPage++;
5787 }
5788 }
5789 #endif
5790 sqlite3Put4byte( pBt.pPage1.aData, (u32)28, pBt.nPage );
5791 pPgno = pBt.nPage;
5792  
5793 Debug.Assert( pPgno != PENDING_BYTE_PAGE( pBt ) );
5794 rc = btreeGetPage( pBt, pPgno, ref ppPage, 1 );
5795 if ( rc != 0 )
5796 return rc;
5797 rc = sqlite3PagerWrite( ( ppPage ).pDbPage );
5798 if ( rc != SQLITE_OK )
5799 {
5800 releasePage( ppPage );
5801 }
5802 TRACE( "ALLOCATE: %d from end of file\n", pPgno );
5803 }
5804  
5805 Debug.Assert( pPgno != PENDING_BYTE_PAGE( pBt ) );
5806  
5807 end_allocate_page:
5808 releasePage( pTrunk );
5809 releasePage( pPrevTrunk );
5810 if ( rc == SQLITE_OK )
5811 {
5812 if ( sqlite3PagerPageRefcount( ( ppPage ).pDbPage ) > 1 )
5813 {
5814 releasePage( ppPage );
5815 return SQLITE_CORRUPT_BKPT();
5816 }
5817 ( ppPage ).isInit = 0;
5818 }
5819 else
5820 {
5821 ppPage = null;
5822 }
5823 Debug.Assert( rc != SQLITE_OK || sqlite3PagerIswriteable( ( ppPage ).pDbPage ) );
5824 return rc;
5825 }
5826  
5827 /*
5828 ** This function is used to add page iPage to the database file free-list.
5829 ** It is assumed that the page is not already a part of the free-list.
5830 **
5831 ** The value passed as the second argument to this function is optional.
5832 ** If the caller happens to have a pointer to the MemPage object
5833 ** corresponding to page iPage handy, it may pass it as the second value.
5834 ** Otherwise, it may pass NULL.
5835 **
5836 ** If a pointer to a MemPage object is passed as the second argument,
5837 ** its reference count is not altered by this function.
5838 */
5839 static int freePage2( BtShared pBt, MemPage pMemPage, Pgno iPage )
5840 {
5841 MemPage pTrunk = null; /* Free-list trunk page */
5842 Pgno iTrunk = 0; /* Page number of free-list trunk page */
5843 MemPage pPage1 = pBt.pPage1; /* Local reference to page 1 */
5844 MemPage pPage; /* Page being freed. May be NULL. */
5845 int rc; /* Return Code */
5846 int nFree; /* Initial number of pages on free-list */
5847  
5848 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
5849 Debug.Assert( iPage > 1 );
5850 Debug.Assert( null == pMemPage || pMemPage.pgno == iPage );
5851  
5852 if ( pMemPage != null )
5853 {
5854 pPage = pMemPage;
5855 sqlite3PagerRef( pPage.pDbPage );
5856 }
5857 else
5858 {
5859 pPage = btreePageLookup( pBt, iPage );
5860 }
5861  
5862 /* Increment the free page count on pPage1 */
5863 rc = sqlite3PagerWrite( pPage1.pDbPage );
5864 if ( rc != 0 )
5865 goto freepage_out;
5866 nFree = (int)sqlite3Get4byte( pPage1.aData, 36 );
5867 sqlite3Put4byte( pPage1.aData, 36, nFree + 1 );
5868  
5869 if ( pBt.secureDelete )
5870 {
5871 /* If the secure_delete option is enabled, then
5872 ** always fully overwrite deleted information with zeros.
5873 */
5874 if ( ( null == pPage && ( ( rc = btreeGetPage( pBt, iPage, ref pPage, 0 ) ) != 0 ) )
5875 || ( ( rc = sqlite3PagerWrite( pPage.pDbPage ) ) != 0 )
5876 )
5877 {
5878 goto freepage_out;
5879 }
5880 Array.Clear( pPage.aData, 0, (int)pPage.pBt.pageSize );//memset(pPage->aData, 0, pPage->pBt->pageSize);
5881 }
5882  
5883 /* If the database supports auto-vacuum, write an entry in the pointer-map
5884 ** to indicate that the page is free.
5885 */
5886 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
5887 if ( pBt.autoVacuum )
5888 #else
5889 if (false)
5890 #endif
5891 {
5892 ptrmapPut( pBt, iPage, PTRMAP_FREEPAGE, 0, ref rc );
5893 if ( rc != 0 )
5894 goto freepage_out;
5895 }
5896  
5897 /* Now manipulate the actual database free-list structure. There are two
5898 ** possibilities. If the free-list is currently empty, or if the first
5899 ** trunk page in the free-list is full, then this page will become a
5900 ** new free-list trunk page. Otherwise, it will become a leaf of the
5901 ** first trunk page in the current free-list. This block tests if it
5902 ** is possible to add the page as a new free-list leaf.
5903 */
5904 if ( nFree != 0 )
5905 {
5906 u32 nLeaf; /* Initial number of leaf cells on trunk page */
5907  
5908 iTrunk = sqlite3Get4byte( pPage1.aData, 32 );
5909 rc = btreeGetPage( pBt, iTrunk, ref pTrunk, 0 );
5910 if ( rc != SQLITE_OK )
5911 {
5912 goto freepage_out;
5913 }
5914  
5915 nLeaf = sqlite3Get4byte( pTrunk.aData, 4 );
5916 Debug.Assert( pBt.usableSize > 32 );
5917 if ( nLeaf > (u32)pBt.usableSize / 4 - 2 )
5918 {
5919 rc = SQLITE_CORRUPT_BKPT();
5920 goto freepage_out;
5921 }
5922 if ( nLeaf < (u32)pBt.usableSize / 4 - 8 )
5923 {
5924 /* In this case there is room on the trunk page to insert the page
5925 ** being freed as a new leaf.
5926 **
5927 ** Note that the trunk page is not really full until it contains
5928 ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
5929 ** coded. But due to a coding error in versions of SQLite prior to
5930 ** 3.6.0, databases with freelist trunk pages holding more than
5931 ** usableSize/4 - 8 entries will be reported as corrupt. In order
5932 ** to maintain backwards compatibility with older versions of SQLite,
5933 ** we will continue to restrict the number of entries to usableSize/4 - 8
5934 ** for now. At some point in the future (once everyone has upgraded
5935 ** to 3.6.0 or later) we should consider fixing the conditional above
5936 ** to read "usableSize/4-2" instead of "usableSize/4-8".
5937 */
5938 rc = sqlite3PagerWrite( pTrunk.pDbPage );
5939 if ( rc == SQLITE_OK )
5940 {
5941 sqlite3Put4byte( pTrunk.aData, (u32)4, nLeaf + 1 );
5942 sqlite3Put4byte( pTrunk.aData, (u32)8 + nLeaf * 4, iPage );
5943 if ( pPage != null && !pBt.secureDelete )
5944 {
5945 sqlite3PagerDontWrite( pPage.pDbPage );
5946 }
5947 rc = btreeSetHasContent( pBt, iPage );
5948 }
5949 TRACE( "FREE-PAGE: %d leaf on trunk page %d\n", iPage, pTrunk.pgno );
5950 goto freepage_out;
5951 }
5952 }
5953  
5954 /* If control flows to this point, then it was not possible to add the
5955 ** the page being freed as a leaf page of the first trunk in the free-list.
5956 ** Possibly because the free-list is empty, or possibly because the
5957 ** first trunk in the free-list is full. Either way, the page being freed
5958 ** will become the new first trunk page in the free-list.
5959 */
5960 if ( pPage == null && SQLITE_OK != ( rc = btreeGetPage( pBt, iPage, ref pPage, 0 ) ) )
5961 {
5962 goto freepage_out;
5963 }
5964 rc = sqlite3PagerWrite( pPage.pDbPage );
5965 if ( rc != SQLITE_OK )
5966 {
5967 goto freepage_out;
5968 }
5969 sqlite3Put4byte( pPage.aData, iTrunk );
5970 sqlite3Put4byte( pPage.aData, 4, 0 );
5971 sqlite3Put4byte( pPage1.aData, (u32)32, iPage );
5972 TRACE( "FREE-PAGE: %d new trunk page replacing %d\n", pPage.pgno, iTrunk );
5973  
5974 freepage_out:
5975 if ( pPage != null )
5976 {
5977 pPage.isInit = 0;
5978 }
5979 releasePage( pPage );
5980 releasePage( pTrunk );
5981 return rc;
5982 }
5983 static void freePage( MemPage pPage, ref int pRC )
5984 {
5985 if ( ( pRC ) == SQLITE_OK )
5986 {
5987 pRC = freePage2( pPage.pBt, pPage, pPage.pgno );
5988 }
5989 }
5990  
5991 /*
5992 ** Free any overflow pages associated with the given Cell.
5993 */
5994 static int clearCell( MemPage pPage, int pCell )
5995 {
5996 BtShared pBt = pPage.pBt;
5997 CellInfo info = new CellInfo();
5998 Pgno ovflPgno;
5999 int rc;
6000 int nOvfl;
6001 u32 ovflPageSize;
6002  
6003 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6004 btreeParseCellPtr( pPage, pCell, ref info );
6005 if ( info.iOverflow == 0 )
6006 {
6007 return SQLITE_OK; /* No overflow pages. Return without doing anything */
6008 }
6009 ovflPgno = sqlite3Get4byte( pPage.aData, pCell, info.iOverflow );
6010 Debug.Assert( pBt.usableSize > 4 );
6011 ovflPageSize = (u16)( pBt.usableSize - 4 );
6012 nOvfl = (int)( ( info.nPayload - info.nLocal + ovflPageSize - 1 ) / ovflPageSize );
6013 Debug.Assert( ovflPgno == 0 || nOvfl > 0 );
6014 while ( nOvfl-- != 0 )
6015 {
6016 Pgno iNext = 0;
6017 MemPage pOvfl = null;
6018 if ( ovflPgno < 2 || ovflPgno > btreePagecount( pBt ) )
6019 {
6020 /* 0 is not a legal page number and page 1 cannot be an
6021 ** overflow page. Therefore if ovflPgno<2 or past the end of the
6022 ** file the database must be corrupt. */
6023 return SQLITE_CORRUPT_BKPT();
6024 }
6025 if ( nOvfl != 0 )
6026 {
6027 rc = getOverflowPage( pBt, ovflPgno, out pOvfl, out iNext );
6028 if ( rc != 0 )
6029 return rc;
6030 }
6031  
6032 if ( ( pOvfl != null || ( ( pOvfl = btreePageLookup( pBt, ovflPgno ) ) != null ) )
6033 && sqlite3PagerPageRefcount( pOvfl.pDbPage ) != 1
6034 )
6035 {
6036 /* There is no reason any cursor should have an outstanding reference
6037 ** to an overflow page belonging to a cell that is being deleted/updated.
6038 ** So if there exists more than one reference to this page, then it
6039 ** must not really be an overflow page and the database must be corrupt.
6040 ** It is helpful to detect this before calling freePage2(), as
6041 ** freePage2() may zero the page contents if secure-delete mode is
6042 ** enabled. If this 'overflow' page happens to be a page that the
6043 ** caller is iterating through or using in some other way, this
6044 ** can be problematic.
6045 */
6046 rc = SQLITE_CORRUPT_BKPT();
6047 }
6048 else
6049 {
6050 rc = freePage2( pBt, pOvfl, ovflPgno );
6051 }
6052 if ( pOvfl != null )
6053 {
6054 sqlite3PagerUnref( pOvfl.pDbPage );
6055 }
6056 if ( rc != 0 )
6057 return rc;
6058 ovflPgno = iNext;
6059 }
6060 return SQLITE_OK;
6061 }
6062  
6063 /*
6064 ** Create the byte sequence used to represent a cell on page pPage
6065 ** and write that byte sequence into pCell[]. Overflow pages are
6066 ** allocated and filled in as necessary. The calling procedure
6067 ** is responsible for making sure sufficient space has been allocated
6068 ** for pCell[].
6069 **
6070 ** Note that pCell does not necessary need to point to the pPage.aData
6071 ** area. pCell might point to some temporary storage. The cell will
6072 ** be constructed in this temporary area then copied into pPage.aData
6073 ** later.
6074 */
6075 static int fillInCell(
6076 MemPage pPage, /* The page that contains the cell */
6077 byte[] pCell, /* Complete text of the cell */
6078 byte[] pKey, i64 nKey, /* The key */
6079 byte[] pData, int nData, /* The data */
6080 int nZero, /* Extra zero bytes to append to pData */
6081 ref int pnSize /* Write cell size here */
6082 )
6083 {
6084 int nPayload;
6085 u8[] pSrc;
6086 int pSrcIndex = 0;
6087 int nSrc, n, rc;
6088 int spaceLeft;
6089 MemPage pOvfl = null;
6090 MemPage pToRelease = null;
6091 byte[] pPrior;
6092 int pPriorIndex = 0;
6093 byte[] pPayload;
6094 int pPayloadIndex = 0;
6095 BtShared pBt = pPage.pBt;
6096 Pgno pgnoOvfl = 0;
6097 int nHeader;
6098 CellInfo info = new CellInfo();
6099  
6100 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6101  
6102 /* pPage is not necessarily writeable since pCell might be auxiliary
6103 ** buffer space that is separate from the pPage buffer area */
6104 // TODO -- Determine if the following Assert is needed under c#
6105 //Debug.Assert( pCell < pPage.aData || pCell >= &pPage.aData[pBt.pageSize]
6106 // || sqlite3PagerIswriteable(pPage.pDbPage) );
6107  
6108 /* Fill in the header. */
6109 nHeader = 0;
6110 if ( 0 == pPage.leaf )
6111 {
6112 nHeader += 4;
6113 }
6114 if ( pPage.hasData != 0 )
6115 {
6116 nHeader += (int)putVarint( pCell, nHeader, (int)( nData + nZero ) ); //putVarint( pCell[nHeader], nData + nZero );
6117 }
6118 else
6119 {
6120 nData = nZero = 0;
6121 }
6122 nHeader += putVarint( pCell, nHeader, (u64)nKey ); //putVarint( pCell[nHeader], *(u64*)&nKey );
6123 btreeParseCellPtr( pPage, pCell, ref info );
6124 Debug.Assert( info.nHeader == nHeader );
6125 Debug.Assert( info.nKey == nKey );
6126 Debug.Assert( info.nData == (u32)( nData + nZero ) );
6127  
6128 /* Fill in the payload */
6129 nPayload = nData + nZero;
6130 if ( pPage.intKey != 0 )
6131 {
6132 pSrc = pData;
6133 nSrc = nData;
6134 nData = 0;
6135 }
6136 else
6137 {
6138 if ( NEVER( nKey > 0x7fffffff || pKey == null ) )
6139 {
6140 return SQLITE_CORRUPT_BKPT();
6141 }
6142 nPayload += (int)nKey;
6143 pSrc = pKey;
6144 nSrc = (int)nKey;
6145 }
6146 pnSize = info.nSize;
6147 spaceLeft = info.nLocal;
6148 // pPayload = &pCell[nHeader];
6149 pPayload = pCell;
6150 pPayloadIndex = nHeader;
6151 // pPrior = &pCell[info.iOverflow];
6152 pPrior = pCell;
6153 pPriorIndex = info.iOverflow;
6154  
6155 while ( nPayload > 0 )
6156 {
6157 if ( spaceLeft == 0 )
6158 {
6159 #if !SQLITE_OMIT_AUTOVACUUM
6160 Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
6161 if ( pBt.autoVacuum )
6162 {
6163 do
6164 {
6165 pgnoOvfl++;
6166 } while (
6167 PTRMAP_ISPAGE( pBt, pgnoOvfl ) || pgnoOvfl == PENDING_BYTE_PAGE( pBt )
6168 );
6169 }
6170 #endif
6171 rc = allocateBtreePage( pBt, ref pOvfl, ref pgnoOvfl, pgnoOvfl, 0 );
6172 #if !SQLITE_OMIT_AUTOVACUUM
6173 /* If the database supports auto-vacuum, and the second or subsequent
6174 ** overflow page is being allocated, add an entry to the pointer-map
6175 ** for that page now.
6176 **
6177 ** If this is the first overflow page, then write a partial entry
6178 ** to the pointer-map. If we write nothing to this pointer-map slot,
6179 ** then the optimistic overflow chain processing in clearCell()
6180 ** may misinterpret the uninitialised values and delete the
6181 ** wrong pages from the database.
6182 */
6183 if ( pBt.autoVacuum && rc == SQLITE_OK )
6184 {
6185 u8 eType = (u8)( pgnoPtrmap != 0 ? PTRMAP_OVERFLOW2 : PTRMAP_OVERFLOW1 );
6186 ptrmapPut( pBt, pgnoOvfl, eType, pgnoPtrmap, ref rc );
6187 if ( rc != 0 )
6188 {
6189 releasePage( pOvfl );
6190 }
6191 }
6192 #endif
6193 if ( rc != 0 )
6194 {
6195 releasePage( pToRelease );
6196 return rc;
6197 }
6198  
6199 /* If pToRelease is not zero than pPrior points into the data area
6200 ** of pToRelease. Make sure pToRelease is still writeable. */
6201 Debug.Assert( pToRelease == null || sqlite3PagerIswriteable( pToRelease.pDbPage ) );
6202  
6203 /* If pPrior is part of the data area of pPage, then make sure pPage
6204 ** is still writeable */
6205 // TODO -- Determine if the following Assert is needed under c#
6206 //Debug.Assert( pPrior < pPage.aData || pPrior >= &pPage.aData[pBt.pageSize]
6207 // || sqlite3PagerIswriteable(pPage.pDbPage) );
6208  
6209 sqlite3Put4byte( pPrior, pPriorIndex, pgnoOvfl );
6210 releasePage( pToRelease );
6211 pToRelease = pOvfl;
6212 pPrior = pOvfl.aData;
6213 pPriorIndex = 0;
6214 sqlite3Put4byte( pPrior, 0 );
6215 pPayload = pOvfl.aData;
6216 pPayloadIndex = 4; //&pOvfl.aData[4];
6217 spaceLeft = (int)pBt.usableSize - 4;
6218 }
6219 n = nPayload;
6220 if ( n > spaceLeft )
6221 n = spaceLeft;
6222  
6223 /* If pToRelease is not zero than pPayload points into the data area
6224 ** of pToRelease. Make sure pToRelease is still writeable. */
6225 Debug.Assert( pToRelease == null || sqlite3PagerIswriteable( pToRelease.pDbPage ) );
6226  
6227 /* If pPayload is part of the data area of pPage, then make sure pPage
6228 ** is still writeable */
6229 // TODO -- Determine if the following Assert is needed under c#
6230 //Debug.Assert( pPayload < pPage.aData || pPayload >= &pPage.aData[pBt.pageSize]
6231 // || sqlite3PagerIswriteable(pPage.pDbPage) );
6232  
6233 if ( nSrc > 0 )
6234 {
6235 if ( n > nSrc )
6236 n = nSrc;
6237 Debug.Assert( pSrc != null );
6238 Buffer.BlockCopy( pSrc, pSrcIndex, pPayload, pPayloadIndex, n );//memcpy(pPayload, pSrc, n);
6239 }
6240 else
6241 {
6242 byte[] pZeroBlob = sqlite3Malloc( n ); // memset(pPayload, 0, n);
6243 Buffer.BlockCopy( pZeroBlob, 0, pPayload, pPayloadIndex, n );
6244 }
6245 nPayload -= n;
6246 pPayloadIndex += n;// pPayload += n;
6247 pSrcIndex += n;// pSrc += n;
6248 nSrc -= n;
6249 spaceLeft -= n;
6250 if ( nSrc == 0 )
6251 {
6252 nSrc = nData;
6253 pSrc = pData;
6254 }
6255 }
6256 releasePage( pToRelease );
6257 return SQLITE_OK;
6258 }
6259  
6260 /*
6261 ** Remove the i-th cell from pPage. This routine effects pPage only.
6262 ** The cell content is not freed or deallocated. It is assumed that
6263 ** the cell content has been copied someplace else. This routine just
6264 ** removes the reference to the cell from pPage.
6265 **
6266 ** "sz" must be the number of bytes in the cell.
6267 */
6268 static void dropCell( MemPage pPage, int idx, int sz, ref int pRC )
6269 {
6270 u32 pc; /* Offset to cell content of cell being deleted */
6271 u8[] data; /* pPage.aData */
6272 int ptr; /* Used to move bytes around within data[] */
6273 int endPtr; /* End of loop */
6274 int rc; /* The return code */
6275 int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
6276  
6277 if ( pRC != 0 )
6278 return;
6279  
6280 Debug.Assert( idx >= 0 && idx < pPage.nCell );
6281 #if SQLITE_DEBUG
6282 Debug.Assert( sz == cellSize( pPage, idx ) );
6283 #endif
6284 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
6285 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6286 data = pPage.aData;
6287 ptr = pPage.cellOffset + 2 * idx; //ptr = &data[pPage.cellOffset + 2 * idx];
6288 pc = (u32)get2byte( data, ptr );
6289 hdr = pPage.hdrOffset;
6290 testcase( pc == get2byte( data, hdr + 5 ) );
6291 testcase( pc + sz == pPage.pBt.usableSize );
6292 if ( pc < (u32)get2byte( data, hdr + 5 ) || pc + sz > pPage.pBt.usableSize )
6293 {
6294 pRC = SQLITE_CORRUPT_BKPT();
6295 return;
6296 }
6297 rc = freeSpace( pPage, pc, sz );
6298 if ( rc != 0 )
6299 {
6300 pRC = rc;
6301 return;
6302 }
6303 //endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2];
6304 //assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
6305 //while( ptr<endPtr ){
6306 // *(u16*)ptr = *(u16*)&ptr[2];
6307 // ptr += 2;
6308 Buffer.BlockCopy( data, ptr + 2, data, ptr, ( pPage.nCell - 1 - idx ) * 2 );
6309 pPage.nCell--;
6310 data[pPage.hdrOffset + 3] = (byte)( pPage.nCell >> 8 );
6311 data[pPage.hdrOffset + 4] = (byte)( pPage.nCell ); //put2byte( data, hdr + 3, pPage.nCell );
6312 pPage.nFree += 2;
6313 }
6314  
6315 /*
6316 ** Insert a new cell on pPage at cell index "i". pCell points to the
6317 ** content of the cell.
6318 **
6319 ** If the cell content will fit on the page, then put it there. If it
6320 ** will not fit, then make a copy of the cell content into pTemp if
6321 ** pTemp is not null. Regardless of pTemp, allocate a new entry
6322 ** in pPage.aOvfl[] and make it point to the cell content (either
6323 ** in pTemp or the original pCell) and also record its index.
6324 ** Allocating a new entry in pPage.aCell[] implies that
6325 ** pPage.nOverflow is incremented.
6326 **
6327 ** If nSkip is non-zero, then do not copy the first nSkip bytes of the
6328 ** cell. The caller will overwrite them after this function returns. If
6329 ** nSkip is non-zero, then pCell may not point to an invalid memory location
6330 ** (but pCell+nSkip is always valid).
6331 */
6332 static void insertCell(
6333 MemPage pPage, /* Page into which we are copying */
6334 int i, /* New cell becomes the i-th cell of the page */
6335 u8[] pCell, /* Content of the new cell */
6336 int sz, /* Bytes of content in pCell */
6337 u8[] pTemp, /* Temp storage space for pCell, if needed */
6338 Pgno iChild, /* If non-zero, replace first 4 bytes with this value */
6339 ref int pRC /* Read and write return code from here */
6340 )
6341 {
6342 int idx = 0; /* Where to write new cell content in data[] */
6343 int j; /* Loop counter */
6344 int end; /* First byte past the last cell pointer in data[] */
6345 int ins; /* Index in data[] where new cell pointer is inserted */
6346 int cellOffset; /* Address of first cell pointer in data[] */
6347 u8[] data; /* The content of the whole page */
6348 u8 ptr; /* Used for moving information around in data[] */
6349 u8 endPtr; /* End of the loop */
6350  
6351 int nSkip = ( iChild != 0 ? 4 : 0 );
6352  
6353 if ( pRC != 0 )
6354 return;
6355  
6356 Debug.Assert( i >= 0 && i <= pPage.nCell + pPage.nOverflow );
6357 Debug.Assert( pPage.nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 10921 );
6358 Debug.Assert( pPage.nOverflow <= ArraySize( pPage.aOvfl ) );
6359 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6360 /* The cell should normally be sized correctly. However, when moving a
6361 ** malformed cell from a leaf page to an interior page, if the cell size
6362 ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
6363 ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
6364 ** the term after the || in the following assert(). */
6365 Debug.Assert( sz == cellSizePtr( pPage, pCell ) || ( sz == 8 && iChild > 0 ) );
6366 if ( pPage.nOverflow != 0 || sz + 2 > pPage.nFree )
6367 {
6368 if ( pTemp != null )
6369 {
6370 Buffer.BlockCopy( pCell, nSkip, pTemp, nSkip, sz - nSkip );//memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
6371 pCell = pTemp;
6372 }
6373 if ( iChild != 0 )
6374 {
6375 sqlite3Put4byte( pCell, iChild );
6376 }
6377 j = pPage.nOverflow++;
6378 Debug.Assert( j < pPage.aOvfl.Length );//(int)(sizeof(pPage.aOvfl)/sizeof(pPage.aOvfl[0])) );
6379 pPage.aOvfl[j].pCell = pCell;
6380 pPage.aOvfl[j].idx = (u16)i;
6381 }
6382 else
6383 {
6384 int rc = sqlite3PagerWrite( pPage.pDbPage );
6385 if ( rc != SQLITE_OK )
6386 {
6387 pRC = rc;
6388 return;
6389 }
6390 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
6391 data = pPage.aData;
6392 cellOffset = pPage.cellOffset;
6393 end = cellOffset + 2 * pPage.nCell;
6394 ins = cellOffset + 2 * i;
6395 rc = allocateSpace( pPage, sz, ref idx );
6396 if ( rc != 0 )
6397 {
6398 pRC = rc;
6399 return;
6400 }
6401 /* The allocateSpace() routine guarantees the following two properties
6402 ** if it returns success */
6403 Debug.Assert( idx >= end + 2 );
6404 Debug.Assert( idx + sz <= (int)pPage.pBt.usableSize );
6405 pPage.nCell++;
6406 pPage.nFree -= (u16)( 2 + sz );
6407 Buffer.BlockCopy( pCell, nSkip, data, idx + nSkip, sz - nSkip ); //memcpy( data[idx + nSkip], pCell + nSkip, sz - nSkip );
6408 if ( iChild != 0 )
6409 {
6410 sqlite3Put4byte( data, idx, iChild );
6411 }
6412 //ptr = &data[end];
6413 //endPtr = &data[ins];
6414 //assert( ( SQLITE_PTR_TO_INT( ptr ) & 1 ) == 0 ); /* ptr is always 2-byte aligned */
6415 //while ( ptr > endPtr )
6416 //{
6417 // *(u16*)ptr = *(u16*)&ptr[-2];
6418 // ptr -= 2;
6419 //}
6420 for ( j = end; j > ins; j -= 2 )
6421 {
6422 data[j + 0] = data[j - 2];
6423 data[j + 1] = data[j - 1];
6424 }
6425 put2byte( data, ins, idx );
6426 put2byte( data, pPage.hdrOffset + 3, pPage.nCell );
6427 #if !SQLITE_OMIT_AUTOVACUUM
6428 if ( pPage.pBt.autoVacuum )
6429 {
6430 /* The cell may contain a pointer to an overflow page. If so, write
6431 ** the entry for the overflow page into the pointer map.
6432 */
6433 ptrmapPutOvflPtr( pPage, pCell, ref pRC );
6434 }
6435 #endif
6436 }
6437 }
6438  
6439 /*
6440 ** Add a list of cells to a page. The page should be initially empty.
6441 ** The cells are guaranteed to fit on the page.
6442 */
6443 static void assemblePage(
6444 MemPage pPage, /* The page to be assemblied */
6445 int nCell, /* The number of cells to add to this page */
6446 u8[] apCell, /* Pointer to a single the cell bodies */
6447 int[] aSize /* Sizes of the cells bodie*/
6448 )
6449 {
6450 int i; /* Loop counter */
6451 int pCellptr; /* Address of next cell pointer */
6452 int cellbody; /* Address of next cell body */
6453 byte[] data = pPage.aData; /* Pointer to data for pPage */
6454 int hdr = pPage.hdrOffset; /* Offset of header on pPage */
6455 int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
6456  
6457 Debug.Assert( pPage.nOverflow == 0 );
6458 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6459 Debug.Assert( nCell >= 0 && nCell <= (int)MX_CELL( pPage.pBt )
6460 && (int)MX_CELL( pPage.pBt ) <= 10921 );
6461  
6462 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
6463  
6464 /* Check that the page has just been zeroed by zeroPage() */
6465 Debug.Assert( pPage.nCell == 0 );
6466 Debug.Assert( get2byteNotZero( data, hdr + 5 ) == nUsable );
6467  
6468 pCellptr = pPage.cellOffset + nCell * 2; //data[pPage.cellOffset + nCell * 2];
6469 cellbody = nUsable;
6470 for ( i = nCell - 1; i >= 0; i-- )
6471 {
6472 u16 sz = (u16)aSize[i];
6473 pCellptr -= 2;
6474 cellbody -= sz;
6475 put2byte( data, pCellptr, cellbody );
6476 Buffer.BlockCopy( apCell, 0, data, cellbody, sz );// memcpy(&data[cellbody], apCell[i], sz);
6477 }
6478 put2byte( data, hdr + 3, nCell );
6479 put2byte( data, hdr + 5, cellbody );
6480 pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
6481 pPage.nCell = (u16)nCell;
6482 }
6483 static void assemblePage(
6484 MemPage pPage, /* The page to be assemblied */
6485 int nCell, /* The number of cells to add to this page */
6486 u8[][] apCell, /* Pointers to cell bodies */
6487 u16[] aSize, /* Sizes of the cells */
6488 int offset /* Offset into the cell bodies, for c# */
6489 )
6490 {
6491 int i; /* Loop counter */
6492 int pCellptr; /* Address of next cell pointer */
6493 int cellbody; /* Address of next cell body */
6494 byte[] data = pPage.aData; /* Pointer to data for pPage */
6495 int hdr = pPage.hdrOffset; /* Offset of header on pPage */
6496 int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
6497  
6498 Debug.Assert( pPage.nOverflow == 0 );
6499 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6500 Debug.Assert( nCell >= 0 && nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 5460 );
6501 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
6502  
6503 /* Check that the page has just been zeroed by zeroPage() */
6504 Debug.Assert( pPage.nCell == 0 );
6505 Debug.Assert( get2byte( data, hdr + 5 ) == nUsable );
6506  
6507 pCellptr = pPage.cellOffset + nCell * 2; //data[pPage.cellOffset + nCell * 2];
6508 cellbody = nUsable;
6509 for ( i = nCell - 1; i >= 0; i-- )
6510 {
6511 pCellptr -= 2;
6512 cellbody -= aSize[i + offset];
6513 put2byte( data, pCellptr, cellbody );
6514 Buffer.BlockCopy( apCell[offset + i], 0, data, cellbody, aSize[i + offset] );// memcpy(&data[cellbody], apCell[i], aSize[i]);
6515 }
6516 put2byte( data, hdr + 3, nCell );
6517 put2byte( data, hdr + 5, cellbody );
6518 pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
6519 pPage.nCell = (u16)nCell;
6520 }
6521  
6522 static void assemblePage(
6523 MemPage pPage, /* The page to be assemblied */
6524 int nCell, /* The number of cells to add to this page */
6525 u8[] apCell, /* Pointers to cell bodies */
6526 u16[] aSize /* Sizes of the cells */
6527 )
6528 {
6529 int i; /* Loop counter */
6530 int pCellptr; /* Address of next cell pointer */
6531 int cellbody; /* Address of next cell body */
6532 u8[] data = pPage.aData; /* Pointer to data for pPage */
6533 int hdr = pPage.hdrOffset; /* Offset of header on pPage */
6534 int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
6535  
6536 Debug.Assert( pPage.nOverflow == 0 );
6537 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6538 Debug.Assert( nCell >= 0 && nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 5460 );
6539 Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
6540  
6541 /* Check that the page has just been zeroed by zeroPage() */
6542 Debug.Assert( pPage.nCell == 0 );
6543 Debug.Assert( get2byte( data, hdr + 5 ) == nUsable );
6544  
6545 pCellptr = pPage.cellOffset + nCell * 2; //&data[pPage.cellOffset + nCell * 2];
6546 cellbody = nUsable;
6547 for ( i = nCell - 1; i >= 0; i-- )
6548 {
6549 pCellptr -= 2;
6550 cellbody -= aSize[i];
6551 put2byte( data, pCellptr, cellbody );
6552 Buffer.BlockCopy( apCell, 0, data, cellbody, aSize[i] );//memcpy( data[cellbody], apCell[i], aSize[i] );
6553 }
6554 put2byte( data, hdr + 3, nCell );
6555 put2byte( data, hdr + 5, cellbody );
6556 pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
6557 pPage.nCell = (u16)nCell;
6558 }
6559  
6560 /*
6561 ** The following parameters determine how many adjacent pages get involved
6562 ** in a balancing operation. NN is the number of neighbors on either side
6563 ** of the page that participate in the balancing operation. NB is the
6564 ** total number of pages that participate, including the target page and
6565 ** NN neighbors on either side.
6566 **
6567 ** The minimum value of NN is 1 (of course). Increasing NN above 1
6568 ** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
6569 ** in exchange for a larger degradation in INSERT and UPDATE performance.
6570 ** The value of NN appears to give the best results overall.
6571 */
6572 static int NN = 1; /* Number of neighbors on either side of pPage */
6573 static int NB = ( NN * 2 + 1 ); /* Total pages involved in the balance */
6574  
6575 #if !SQLITE_OMIT_QUICKBALANCE
6576 /*
6577 ** This version of balance() handles the common special case where
6578 ** a new entry is being inserted on the extreme right-end of the
6579 ** tree, in other words, when the new entry will become the largest
6580 ** entry in the tree.
6581 **
6582 ** Instead of trying to balance the 3 right-most leaf pages, just add
6583 ** a new page to the right-hand side and put the one new entry in
6584 ** that page. This leaves the right side of the tree somewhat
6585 ** unbalanced. But odds are that we will be inserting new entries
6586 ** at the end soon afterwards so the nearly empty page will quickly
6587 ** fill up. On average.
6588 **
6589 ** pPage is the leaf page which is the right-most page in the tree.
6590 ** pParent is its parent. pPage must have a single overflow entry
6591 ** which is also the right-most entry on the page.
6592 **
6593 ** The pSpace buffer is used to store a temporary copy of the divider
6594 ** cell that will be inserted into pParent. Such a cell consists of a 4
6595 ** byte page number followed by a variable length integer. In other
6596 ** words, at most 13 bytes. Hence the pSpace buffer must be at
6597 ** least 13 bytes in size.
6598 */
6599 static int balance_quick( MemPage pParent, MemPage pPage, u8[] pSpace )
6600 {
6601 BtShared pBt = pPage.pBt; /* B-Tree Database */
6602 MemPage pNew = new MemPage();/* Newly allocated page */
6603 int rc; /* Return Code */
6604 Pgno pgnoNew = 0; /* Page number of pNew */
6605  
6606 Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
6607 Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
6608 Debug.Assert( pPage.nOverflow == 1 );
6609  
6610 /* This error condition is now caught prior to reaching this function */
6611 if ( pPage.nCell <= 0 )
6612 return SQLITE_CORRUPT_BKPT();
6613  
6614 /* Allocate a new page. This page will become the right-sibling of
6615 ** pPage. Make the parent page writable, so that the new divider cell
6616 ** may be inserted. If both these operations are successful, proceed.
6617 */
6618 rc = allocateBtreePage( pBt, ref pNew, ref pgnoNew, 0, 0 );
6619  
6620 if ( rc == SQLITE_OK )
6621 {
6622  
6623 int pOut = 4;//u8 pOut = &pSpace[4];
6624 u8[] pCell = pPage.aOvfl[0].pCell;
6625 int[] szCell = new int[1];
6626 szCell[0] = cellSizePtr( pPage, pCell );
6627 int pStop;
6628  
6629 Debug.Assert( sqlite3PagerIswriteable( pNew.pDbPage ) );
6630 Debug.Assert( pPage.aData[0] == ( PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF ) );
6631 zeroPage( pNew, PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF );
6632 assemblePage( pNew, 1, pCell, szCell );
6633  
6634 /* If this is an auto-vacuum database, update the pointer map
6635 ** with entries for the new page, and any pointer from the
6636 ** cell on the page to an overflow page. If either of these
6637 ** operations fails, the return code is set, but the contents
6638 ** of the parent page are still manipulated by thh code below.
6639 ** That is Ok, at this point the parent page is guaranteed to
6640 ** be marked as dirty. Returning an error code will cause a
6641 ** rollback, undoing any changes made to the parent page.
6642 */
6643 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
6644 if ( pBt.autoVacuum )
6645 #else
6646 if (false)
6647 #endif
6648 {
6649 ptrmapPut( pBt, pgnoNew, PTRMAP_BTREE, pParent.pgno, ref rc );
6650 if ( szCell[0] > pNew.minLocal )
6651 {
6652 ptrmapPutOvflPtr( pNew, pCell, ref rc );
6653 }
6654 }
6655  
6656 /* Create a divider cell to insert into pParent. The divider cell
6657 ** consists of a 4-byte page number (the page number of pPage) and
6658 ** a variable length key value (which must be the same value as the
6659 ** largest key on pPage).
6660 **
6661 ** To find the largest key value on pPage, first find the right-most
6662 ** cell on pPage. The first two fields of this cell are the
6663 ** record-length (a variable length integer at most 32-bits in size)
6664 ** and the key value (a variable length integer, may have any value).
6665 ** The first of the while(...) loops below skips over the record-length
6666 ** field. The second while(...) loop copies the key value from the
6667 ** cell on pPage into the pSpace buffer.
6668 */
6669 int iCell = findCell( pPage, pPage.nCell - 1 ); //pCell = findCell( pPage, pPage.nCell - 1 );
6670 pCell = pPage.aData;
6671 int _pCell = iCell;
6672 pStop = _pCell + 9; //pStop = &pCell[9];
6673 while ( ( ( pCell[_pCell++] ) & 0x80 ) != 0 && _pCell < pStop )
6674 ; //while ( ( *( pCell++ ) & 0x80 ) && pCell < pStop ) ;
6675 pStop = _pCell + 9;//pStop = &pCell[9];
6676 while ( ( ( pSpace[pOut++] = pCell[_pCell++] ) & 0x80 ) != 0 && _pCell < pStop )
6677 ; //while ( ( ( *( pOut++ ) = *( pCell++ ) ) & 0x80 ) && pCell < pStop ) ;
6678  
6679 /* Insert the new divider cell into pParent. */
6680 insertCell( pParent, pParent.nCell, pSpace, pOut, //(int)(pOut-pSpace),
6681 null, pPage.pgno, ref rc );
6682  
6683 /* Set the right-child pointer of pParent to point to the new page. */
6684 sqlite3Put4byte( pParent.aData, pParent.hdrOffset + 8, pgnoNew );
6685  
6686 /* Release the reference to the new page. */
6687 releasePage( pNew );
6688 }
6689  
6690 return rc;
6691 }
6692 #endif //* SQLITE_OMIT_QUICKBALANCE */
6693  
6694 #if FALSE
6695 /*
6696 ** This function does not contribute anything to the operation of SQLite.
6697 ** it is sometimes activated temporarily while debugging code responsible
6698 ** for setting pointer-map entries.
6699 */
6700 static int ptrmapCheckPages(MemPage **apPage, int nPage){
6701 int i, j;
6702 for(i=0; i<nPage; i++){
6703 Pgno n;
6704 u8 e;
6705 MemPage pPage = apPage[i];
6706 BtShared pBt = pPage.pBt;
6707 Debug.Assert( pPage.isInit!=0 );
6708  
6709 for(j=0; j<pPage.nCell; j++){
6710 CellInfo info;
6711 u8 *z;
6712  
6713 z = findCell(pPage, j);
6714 btreeParseCellPtr(pPage, z, info);
6715 if( info.iOverflow ){
6716 Pgno ovfl = sqlite3Get4byte(z[info.iOverflow]);
6717 ptrmapGet(pBt, ovfl, ref e, ref n);
6718 Debug.Assert( n==pPage.pgno && e==PTRMAP_OVERFLOW1 );
6719 }
6720 if( 0==pPage.leaf ){
6721 Pgno child = sqlite3Get4byte(z);
6722 ptrmapGet(pBt, child, ref e, ref n);
6723 Debug.Assert( n==pPage.pgno && e==PTRMAP_BTREE );
6724 }
6725 }
6726 if( 0==pPage.leaf ){
6727 Pgno child = sqlite3Get4byte(pPage.aData,pPage.hdrOffset+8]);
6728 ptrmapGet(pBt, child, ref e, ref n);
6729 Debug.Assert( n==pPage.pgno && e==PTRMAP_BTREE );
6730 }
6731 }
6732 return 1;
6733 }
6734 #endif
6735  
6736 /*
6737 ** This function is used to copy the contents of the b-tree node stored
6738 ** on page pFrom to page pTo. If page pFrom was not a leaf page, then
6739 ** the pointer-map entries for each child page are updated so that the
6740 ** parent page stored in the pointer map is page pTo. If pFrom contained
6741 ** any cells with overflow page pointers, then the corresponding pointer
6742 ** map entries are also updated so that the parent page is page pTo.
6743 **
6744 ** If pFrom is currently carrying any overflow cells (entries in the
6745 ** MemPage.aOvfl[] array), they are not copied to pTo.
6746 **
6747 ** Before returning, page pTo is reinitialized using btreeInitPage().
6748 **
6749 ** The performance of this function is not critical. It is only used by
6750 ** the balance_shallower() and balance_deeper() procedures, neither of
6751 ** which are called often under normal circumstances.
6752 */
6753 static void copyNodeContent( MemPage pFrom, MemPage pTo, ref int pRC )
6754 {
6755 if ( ( pRC ) == SQLITE_OK )
6756 {
6757 BtShared pBt = pFrom.pBt;
6758 u8[] aFrom = pFrom.aData;
6759 u8[] aTo = pTo.aData;
6760 int iFromHdr = pFrom.hdrOffset;
6761 int iToHdr = ( ( pTo.pgno == 1 ) ? 100 : 0 );
6762 int rc;
6763 int iData;
6764  
6765  
6766 Debug.Assert( pFrom.isInit != 0 );
6767 Debug.Assert( pFrom.nFree >= iToHdr );
6768 Debug.Assert( get2byte( aFrom, iFromHdr + 5 ) <= (int)pBt.usableSize );
6769  
6770 /* Copy the b-tree node content from page pFrom to page pTo. */
6771 iData = get2byte( aFrom, iFromHdr + 5 );
6772 Buffer.BlockCopy( aFrom, iData, aTo, iData, (int)pBt.usableSize - iData );//memcpy(aTo[iData], ref aFrom[iData], pBt.usableSize-iData);
6773 Buffer.BlockCopy( aFrom, iFromHdr, aTo, iToHdr, pFrom.cellOffset + 2 * pFrom.nCell );//memcpy(aTo[iToHdr], ref aFrom[iFromHdr], pFrom.cellOffset + 2*pFrom.nCell);
6774  
6775 /* Reinitialize page pTo so that the contents of the MemPage structure
6776 ** match the new data. The initialization of pTo can actually fail under
6777 ** fairly obscure circumstances, even though it is a copy of initialized
6778 ** page pFrom.
6779 */
6780 pTo.isInit = 0;
6781 rc = btreeInitPage( pTo );
6782 if ( rc != SQLITE_OK )
6783 {
6784 pRC = rc;
6785 return;
6786 }
6787  
6788 /* If this is an auto-vacuum database, update the pointer-map entries
6789 ** for any b-tree or overflow pages that pTo now contains the pointers to.
6790 */
6791 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
6792 if ( pBt.autoVacuum )
6793 #else
6794 if (false)
6795 #endif
6796 {
6797 pRC = setChildPtrmaps( pTo );
6798 }
6799 }
6800 }
6801  
6802 /*
6803 ** This routine redistributes cells on the iParentIdx'th child of pParent
6804 ** (hereafter "the page") and up to 2 siblings so that all pages have about the
6805 ** same amount of free space. Usually a single sibling on either side of the
6806 ** page are used in the balancing, though both siblings might come from one
6807 ** side if the page is the first or last child of its parent. If the page
6808 ** has fewer than 2 siblings (something which can only happen if the page
6809 ** is a root page or a child of a root page) then all available siblings
6810 ** participate in the balancing.
6811 **
6812 ** The number of siblings of the page might be increased or decreased by
6813 ** one or two in an effort to keep pages nearly full but not over full.
6814 **
6815 ** Note that when this routine is called, some of the cells on the page
6816 ** might not actually be stored in MemPage.aData[]. This can happen
6817 ** if the page is overfull. This routine ensures that all cells allocated
6818 ** to the page and its siblings fit into MemPage.aData[] before returning.
6819 **
6820 ** In the course of balancing the page and its siblings, cells may be
6821 ** inserted into or removed from the parent page (pParent). Doing so
6822 ** may cause the parent page to become overfull or underfull. If this
6823 ** happens, it is the responsibility of the caller to invoke the correct
6824 ** balancing routine to fix this problem (see the balance() routine).
6825 **
6826 ** If this routine fails for any reason, it might leave the database
6827 ** in a corrupted state. So if this routine fails, the database should
6828 ** be rolled back.
6829 **
6830 ** The third argument to this function, aOvflSpace, is a pointer to a
6831 ** buffer big enough to hold one page. If while inserting cells into the parent
6832 ** page (pParent) the parent page becomes overfull, this buffer is
6833 ** used to store the parent's overflow cells. Because this function inserts
6834 ** a maximum of four divider cells into the parent page, and the maximum
6835 ** size of a cell stored within an internal node is always less than 1/4
6836 ** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
6837 ** enough for all overflow cells.
6838 **
6839 ** If aOvflSpace is set to a null pointer, this function returns
6840 ** SQLITE_NOMEM.
6841 */
6842  
6843 // under C#; Try to reuse Memory
6844  
6845 static int balance_nonroot(
6846 MemPage pParent, /* Parent page of siblings being balanced */
6847 int iParentIdx, /* Index of "the page" in pParent */
6848 u8[] aOvflSpace, /* page-size bytes of space for parent ovfl */
6849 int isRoot /* True if pParent is a root-page */
6850 )
6851 {
6852 MemPage[] apOld = new MemPage[NB]; /* pPage and up to two siblings */
6853 MemPage[] apCopy = new MemPage[NB]; /* Private copies of apOld[] pages */
6854 MemPage[] apNew = new MemPage[NB + 2];/* pPage and up to NB siblings after balancing */
6855 int[] apDiv = new int[NB - 1]; /* Divider cells in pParent */
6856 int[] cntNew = new int[NB + 2]; /* Index in aCell[] of cell after i-th page */
6857 int[] szNew = new int[NB + 2]; /* Combined size of cells place on i-th page */
6858 u16[] szCell = new u16[1]; /* Local size of all cells in apCell[] */
6859 BtShared pBt; /* The whole database */
6860 int nCell = 0; /* Number of cells in apCell[] */
6861 int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
6862 int nNew = 0; /* Number of pages in apNew[] */
6863 int nOld; /* Number of pages in apOld[] */
6864 int i, j, k; /* Loop counters */
6865 int nxDiv; /* Next divider slot in pParent.aCell[] */
6866 int rc = SQLITE_OK; /* The return code */
6867 u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */
6868 int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
6869 int usableSpace; /* Bytes in pPage beyond the header */
6870 int pageFlags; /* Value of pPage.aData[0] */
6871 int subtotal; /* Subtotal of bytes in cells on one page */
6872 //int iSpace1 = 0; /* First unused byte of aSpace1[] */
6873 int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
6874 int szScratch; /* Size of scratch memory requested */
6875 int pRight; /* Location in parent of right-sibling pointer */
6876 u8[][] apCell = null; /* All cells begin balanced */
6877 //u16[] szCell; /* Local size of all cells in apCell[] */
6878 //u8[] aSpace1; /* Space for copies of dividers cells */
6879 Pgno pgno; /* Temp var to store a page number in */
6880  
6881 pBt = pParent.pBt;
6882 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
6883 Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
6884  
6885 #if FALSE
6886 TRACE("BALANCE: begin page %d child of %d\n", pPage.pgno, pParent.pgno);
6887 #endif
6888  
6889 /* At this point pParent may have at most one overflow cell. And if
6890 ** this overflow cell is present, it must be the cell with
6891 ** index iParentIdx. This scenario comes about when this function
6892 ** is called (indirectly) from sqlite3BtreeDelete().
6893 */
6894 Debug.Assert( pParent.nOverflow == 0 || pParent.nOverflow == 1 );
6895 Debug.Assert( pParent.nOverflow == 0 || pParent.aOvfl[0].idx == iParentIdx );
6896  
6897 //if( !aOvflSpace ){
6898 // return SQLITE_NOMEM;
6899 //}
6900  
6901 /* Find the sibling pages to balance. Also locate the cells in pParent
6902 ** that divide the siblings. An attempt is made to find NN siblings on
6903 ** either side of pPage. More siblings are taken from one side, however,
6904 ** if there are fewer than NN siblings on the other side. If pParent
6905 ** has NB or fewer children then all children of pParent are taken.
6906 **
6907 ** This loop also drops the divider cells from the parent page. This
6908 ** way, the remainder of the function does not have to deal with any
6909 ** overflow cells in the parent page, since if any existed they will
6910 ** have already been removed.
6911 */
6912 i = pParent.nOverflow + pParent.nCell;
6913 if ( i < 2 )
6914 {
6915 nxDiv = 0;
6916 nOld = i + 1;
6917 }
6918 else
6919 {
6920 nOld = 3;
6921 if ( iParentIdx == 0 )
6922 {
6923 nxDiv = 0;
6924 }
6925 else if ( iParentIdx == i )
6926 {
6927 nxDiv = i - 2;
6928 }
6929 else
6930 {
6931 nxDiv = iParentIdx - 1;
6932 }
6933 i = 2;
6934 }
6935 if ( ( i + nxDiv - pParent.nOverflow ) == pParent.nCell )
6936 {
6937 pRight = pParent.hdrOffset + 8; //&pParent.aData[pParent.hdrOffset + 8];
6938 }
6939 else
6940 {
6941 pRight = findCell( pParent, i + nxDiv - pParent.nOverflow );
6942 }
6943 pgno = sqlite3Get4byte( pParent.aData, pRight );
6944 while ( true )
6945 {
6946 rc = getAndInitPage( pBt, pgno, ref apOld[i] );
6947 if ( rc != 0 )
6948 {
6949 //memset(apOld, 0, (i+1)*sizeof(MemPage*));
6950 goto balance_cleanup;
6951 }
6952 nMaxCells += 1 + apOld[i].nCell + apOld[i].nOverflow;
6953 if ( ( i-- ) == 0 )
6954 break;
6955  
6956 if ( i + nxDiv == pParent.aOvfl[0].idx && pParent.nOverflow != 0 )
6957 {
6958 apDiv[i] = 0;// = pParent.aOvfl[0].pCell;
6959 pgno = sqlite3Get4byte( pParent.aOvfl[0].pCell, apDiv[i] );
6960 szNew[i] = cellSizePtr( pParent, apDiv[i] );
6961 pParent.nOverflow = 0;
6962 }
6963 else
6964 {
6965 apDiv[i] = findCell( pParent, i + nxDiv - pParent.nOverflow );
6966 pgno = sqlite3Get4byte( pParent.aData, apDiv[i] );
6967 szNew[i] = cellSizePtr( pParent, apDiv[i] );
6968  
6969 /* Drop the cell from the parent page. apDiv[i] still points to
6970 ** the cell within the parent, even though it has been dropped.
6971 ** This is safe because dropping a cell only overwrites the first
6972 ** four bytes of it, and this function does not need the first
6973 ** four bytes of the divider cell. So the pointer is safe to use
6974 ** later on.
6975 **
6976 ** Unless SQLite is compiled in secure-delete mode. In this case,
6977 ** the dropCell() routine will overwrite the entire cell with zeroes.
6978 ** In this case, temporarily copy the cell into the aOvflSpace[]
6979 ** buffer. It will be copied out again as soon as the aSpace[] buffer
6980 ** is allocated. */
6981 //if (pBt.secureDelete)
6982 //{
6983 // int iOff = (int)(apDiv[i]) - (int)(pParent.aData); //SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent.aData);
6984 // if( (iOff+szNew[i])>(int)pBt->usableSize )
6985 // {
6986 // rc = SQLITE_CORRUPT_BKPT();
6987 // Array.Clear(apOld[0].aData,0,apOld[0].aData.Length); //memset(apOld, 0, (i + 1) * sizeof(MemPage*));
6988 // goto balance_cleanup;
6989 // }
6990 // else
6991 // {
6992 // memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
6993 // apDiv[i] = &aOvflSpace[apDiv[i] - pParent.aData];
6994 // }
6995 //}
6996 dropCell( pParent, i + nxDiv - pParent.nOverflow, szNew[i], ref rc );
6997 }
6998 }
6999  
7000 /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
7001 ** alignment */
7002 nMaxCells = ( nMaxCells + 3 ) & ~3;
7003  
7004 /*
7005 ** Allocate space for memory structures
7006 */
7007 //k = pBt.pageSize + ROUND8(sizeof(MemPage));
7008 //szScratch =
7009 // nMaxCells*sizeof(u8*) /* apCell */
7010 // + nMaxCells*sizeof(u16) /* szCell */
7011 // + pBt.pageSize /* aSpace1 */
7012 // + k*nOld; /* Page copies (apCopy) */
7013 apCell = sqlite3ScratchMalloc( apCell, nMaxCells );
7014 //if( apCell==null ){
7015 // rc = SQLITE_NOMEM;
7016 // goto balance_cleanup;
7017 //}
7018 if ( szCell.Length < nMaxCells )
7019 Array.Resize( ref szCell, nMaxCells ); //(u16*)&apCell[nMaxCells];
7020 //aSpace1 = new byte[pBt.pageSize * (nMaxCells)];// aSpace1 = (u8*)&szCell[nMaxCells];
7021 //Debug.Assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
7022  
7023 /*
7024 ** Load pointers to all cells on sibling pages and the divider cells
7025 ** into the local apCell[] array. Make copies of the divider cells
7026 ** into space obtained from aSpace1[] and remove the the divider Cells
7027 ** from pParent.
7028 **
7029 ** If the siblings are on leaf pages, then the child pointers of the
7030 ** divider cells are stripped from the cells before they are copied
7031 ** into aSpace1[]. In this way, all cells in apCell[] are without
7032 ** child pointers. If siblings are not leaves, then all cell in
7033 ** apCell[] include child pointers. Either way, all cells in apCell[]
7034 ** are alike.
7035 **
7036 ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
7037 ** leafData: 1 if pPage holds key+data and pParent holds only keys.
7038 */
7039 leafCorrection = (u16)( apOld[0].leaf * 4 );
7040 leafData = apOld[0].hasData;
7041 for ( i = 0; i < nOld; i++ )
7042 {
7043 int limit;
7044  
7045 /* Before doing anything else, take a copy of the i'th original sibling
7046 ** The rest of this function will use data from the copies rather
7047 ** that the original pages since the original pages will be in the
7048 ** process of being overwritten. */
7049 //MemPage pOld = apCopy[i] = (MemPage*)&aSpace1[pBt.pageSize + k*i];
7050 //memcpy(pOld, apOld[i], sizeof(MemPage));
7051 //pOld.aData = (void*)&pOld[1];
7052 //memcpy(pOld.aData, apOld[i].aData, pBt.pageSize);
7053 MemPage pOld = apCopy[i] = apOld[i].Copy();
7054  
7055 limit = pOld.nCell + pOld.nOverflow;
7056 if( pOld.nOverflow>0 || true){
7057 for ( j = 0; j < limit; j++ )
7058 {
7059 Debug.Assert( nCell < nMaxCells );
7060 //apCell[nCell] = findOverflowCell( pOld, j );
7061 //szCell[nCell] = cellSizePtr( pOld, apCell, nCell );
7062 int iFOFC = findOverflowCell( pOld, j );
7063 szCell[nCell] = cellSizePtr( pOld, iFOFC );
7064 // Copy the Data Locally
7065 if ( apCell[nCell] == null )
7066 apCell[nCell] = new u8[szCell[nCell]];
7067 else if ( apCell[nCell].Length < szCell[nCell] )
7068 Array.Resize( ref apCell[nCell], szCell[nCell] );
7069 if ( iFOFC < 0 ) // Overflow Cell
7070 Buffer.BlockCopy( pOld.aOvfl[-( iFOFC + 1 )].pCell, 0, apCell[nCell], 0, szCell[nCell] );
7071 else
7072 Buffer.BlockCopy( pOld.aData, iFOFC, apCell[nCell], 0, szCell[nCell] );
7073 nCell++;
7074 }
7075 }
7076 else
7077 {
7078 u8[] aData = pOld.aData;
7079 u16 maskPage = pOld.maskPage;
7080 u16 cellOffset = pOld.cellOffset;
7081 for ( j = 0; j < limit; j++ )
7082 {
7083 Debugger.Break();
7084 Debug.Assert( nCell < nMaxCells );
7085 apCell[nCell] = findCellv2( aData, maskPage, cellOffset, j );
7086 szCell[nCell] = cellSizePtr( pOld, apCell[nCell] );
7087 nCell++;
7088 }
7089 }
7090 if ( i < nOld - 1 && 0 == leafData )
7091 {
7092 u16 sz = (u16)szNew[i];
7093 byte[] pTemp = sqlite3Malloc( sz + leafCorrection );
7094 Debug.Assert( nCell < nMaxCells );
7095 szCell[nCell] = sz;
7096 //pTemp = &aSpace1[iSpace1];
7097 //iSpace1 += sz;
7098 Debug.Assert( sz <= pBt.maxLocal + 23 );
7099 //Debug.Assert(iSpace1 <= (int)pBt.pageSize);
7100 Buffer.BlockCopy( pParent.aData, apDiv[i], pTemp, 0, sz );//memcpy( pTemp, apDiv[i], sz );
7101 if ( apCell[nCell] == null || apCell[nCell].Length < sz )
7102 Array.Resize( ref apCell[nCell], sz );
7103 Buffer.BlockCopy( pTemp, leafCorrection, apCell[nCell], 0, sz );//apCell[nCell] = pTemp + leafCorrection;
7104 Debug.Assert( leafCorrection == 0 || leafCorrection == 4 );
7105 szCell[nCell] = (u16)( szCell[nCell] - leafCorrection );
7106 if ( 0 == pOld.leaf )
7107 {
7108 Debug.Assert( leafCorrection == 0 );
7109 Debug.Assert( pOld.hdrOffset == 0 );
7110 /* The right pointer of the child page pOld becomes the left
7111 ** pointer of the divider cell */
7112 Buffer.BlockCopy( pOld.aData, 8, apCell[nCell], 0, 4 );//memcpy( apCell[nCell], ref pOld.aData[8], 4 );
7113 }
7114 else
7115 {
7116 Debug.Assert( leafCorrection == 4 );
7117 if ( szCell[nCell] < 4 )
7118 {
7119 /* Do not allow any cells smaller than 4 bytes. */
7120 szCell[nCell] = 4;
7121 }
7122 }
7123 nCell++;
7124 }
7125 }
7126  
7127 /*
7128 ** Figure out the number of pages needed to hold all nCell cells.
7129 ** Store this number in "k". Also compute szNew[] which is the total
7130 ** size of all cells on the i-th page and cntNew[] which is the index
7131 ** in apCell[] of the cell that divides page i from page i+1.
7132 ** cntNew[k] should equal nCell.
7133 **
7134 ** Values computed by this block:
7135 **
7136 ** k: The total number of sibling pages
7137 ** szNew[i]: Spaced used on the i-th sibling page.
7138 ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to
7139 ** the right of the i-th sibling page.
7140 ** usableSpace: Number of bytes of space available on each sibling.
7141 **
7142 */
7143 usableSpace = (int)pBt.usableSize - 12 + leafCorrection;
7144 for ( subtotal = k = i = 0; i < nCell; i++ )
7145 {
7146 Debug.Assert( i < nMaxCells );
7147 subtotal += szCell[i] + 2;
7148 if ( subtotal > usableSpace )
7149 {
7150 szNew[k] = subtotal - szCell[i];
7151 cntNew[k] = i;
7152 if ( leafData != 0 )
7153 {
7154 i--;
7155 }
7156 subtotal = 0;
7157 k++;
7158 if ( k > NB + 1 )
7159 {
7160 rc = SQLITE_CORRUPT_BKPT();
7161 goto balance_cleanup;
7162 }
7163 }
7164 }
7165 szNew[k] = subtotal;
7166 cntNew[k] = nCell;
7167 k++;
7168  
7169 /*
7170 ** The packing computed by the previous block is biased toward the siblings
7171 ** on the left side. The left siblings are always nearly full, while the
7172 ** right-most sibling might be nearly empty. This block of code attempts
7173 ** to adjust the packing of siblings to get a better balance.
7174 **
7175 ** This adjustment is more than an optimization. The packing above might
7176 ** be so out of balance as to be illegal. For example, the right-most
7177 ** sibling might be completely empty. This adjustment is not optional.
7178 */
7179 for ( i = k - 1; i > 0; i-- )
7180 {
7181 int szRight = szNew[i]; /* Size of sibling on the right */
7182 int szLeft = szNew[i - 1]; /* Size of sibling on the left */
7183 int r; /* Index of right-most cell in left sibling */
7184 int d; /* Index of first cell to the left of right sibling */
7185  
7186 r = cntNew[i - 1] - 1;
7187 d = r + 1 - leafData;
7188 Debug.Assert( d < nMaxCells );
7189 Debug.Assert( r < nMaxCells );
7190 while ( szRight == 0 || szRight + szCell[d] + 2 <= szLeft - ( szCell[r] + 2 ) )
7191 {
7192 szRight += szCell[d] + 2;
7193 szLeft -= szCell[r] + 2;
7194 cntNew[i - 1]--;
7195 r = cntNew[i - 1] - 1;
7196 d = r + 1 - leafData;
7197 }
7198 szNew[i] = szRight;
7199 szNew[i - 1] = szLeft;
7200 }
7201  
7202 /* Either we found one or more cells (cntnew[0])>0) or pPage is
7203 ** a virtual root page. A virtual root page is when the real root
7204 ** page is page 1 and we are the only child of that page.
7205 */
7206 Debug.Assert( cntNew[0] > 0 || ( pParent.pgno == 1 && pParent.nCell == 0 ) );
7207  
7208 TRACE( "BALANCE: old: %d %d %d ",
7209 apOld[0].pgno,
7210 nOld >= 2 ? apOld[1].pgno : 0,
7211 nOld >= 3 ? apOld[2].pgno : 0
7212 );
7213  
7214 /*
7215 ** Allocate k new pages. Reuse old pages where possible.
7216 */
7217 if ( apOld[0].pgno <= 1 )
7218 {
7219 rc = SQLITE_CORRUPT_BKPT();
7220 goto balance_cleanup;
7221 }
7222 pageFlags = apOld[0].aData[0];
7223 for ( i = 0; i < k; i++ )
7224 {
7225 MemPage pNew = new MemPage();
7226 if ( i < nOld )
7227 {
7228 pNew = apNew[i] = apOld[i];
7229 apOld[i] = null;
7230 rc = sqlite3PagerWrite( pNew.pDbPage );
7231 nNew++;
7232 if ( rc != 0 )
7233 goto balance_cleanup;
7234 }
7235 else
7236 {
7237 Debug.Assert( i > 0 );
7238 rc = allocateBtreePage( pBt, ref pNew, ref pgno, pgno, 0 );
7239 if ( rc != 0 )
7240 goto balance_cleanup;
7241 apNew[i] = pNew;
7242 nNew++;
7243  
7244 /* Set the pointer-map entry for the new sibling page. */
7245 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
7246 if ( pBt.autoVacuum )
7247 #else
7248 if (false)
7249 #endif
7250 {
7251 ptrmapPut( pBt, pNew.pgno, PTRMAP_BTREE, pParent.pgno, ref rc );
7252 if ( rc != SQLITE_OK )
7253 {
7254 goto balance_cleanup;
7255 }
7256 }
7257 }
7258 }
7259  
7260 /* Free any old pages that were not reused as new pages.
7261 */
7262 while ( i < nOld )
7263 {
7264 freePage( apOld[i], ref rc );
7265 if ( rc != 0 )
7266 goto balance_cleanup;
7267 releasePage( apOld[i] );
7268 apOld[i] = null;
7269 i++;
7270 }
7271  
7272 /*
7273 ** Put the new pages in accending order. This helps to
7274 ** keep entries in the disk file in order so that a scan
7275 ** of the table is a linear scan through the file. That
7276 ** in turn helps the operating system to deliver pages
7277 ** from the disk more rapidly.
7278 **
7279 ** An O(n^2) insertion sort algorithm is used, but since
7280 ** n is never more than NB (a small constant), that should
7281 ** not be a problem.
7282 **
7283 ** When NB==3, this one optimization makes the database
7284 ** about 25% faster for large insertions and deletions.
7285 */
7286 for ( i = 0; i < k - 1; i++ )
7287 {
7288 int minV = (int)apNew[i].pgno;
7289 int minI = i;
7290 for ( j = i + 1; j < k; j++ )
7291 {
7292 if ( apNew[j].pgno < (u32)minV )
7293 {
7294 minI = j;
7295 minV = (int)apNew[j].pgno;
7296 }
7297 }
7298 if ( minI > i )
7299 {
7300 MemPage pT;
7301 pT = apNew[i];
7302 apNew[i] = apNew[minI];
7303 apNew[minI] = pT;
7304 }
7305 }
7306 TRACE( "new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
7307 apNew[0].pgno, szNew[0],
7308 nNew >= 2 ? apNew[1].pgno : 0, nNew >= 2 ? szNew[1] : 0,
7309 nNew >= 3 ? apNew[2].pgno : 0, nNew >= 3 ? szNew[2] : 0,
7310 nNew >= 4 ? apNew[3].pgno : 0, nNew >= 4 ? szNew[3] : 0,
7311 nNew >= 5 ? apNew[4].pgno : 0, nNew >= 5 ? szNew[4] : 0 );
7312  
7313 Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
7314 sqlite3Put4byte( pParent.aData, pRight, apNew[nNew - 1].pgno );
7315  
7316 /*
7317 ** Evenly distribute the data in apCell[] across the new pages.
7318 ** Insert divider cells into pParent as necessary.
7319 */
7320 j = 0;
7321 for ( i = 0; i < nNew; i++ )
7322 {
7323 /* Assemble the new sibling page. */
7324 MemPage pNew = apNew[i];
7325 Debug.Assert( j < nMaxCells );
7326 zeroPage( pNew, pageFlags );
7327 assemblePage( pNew, cntNew[i] - j, apCell, szCell, j );
7328 Debug.Assert( pNew.nCell > 0 || ( nNew == 1 && cntNew[0] == 0 ) );
7329 Debug.Assert( pNew.nOverflow == 0 );
7330  
7331 j = cntNew[i];
7332  
7333 /* If the sibling page assembled above was not the right-most sibling,
7334 ** insert a divider cell into the parent page.
7335 */
7336 Debug.Assert( i < nNew - 1 || j == nCell );
7337 if ( j < nCell )
7338 {
7339 u8[] pCell;
7340 u8[] pTemp;
7341 int sz;
7342  
7343 Debug.Assert( j < nMaxCells );
7344 pCell = apCell[j];
7345 sz = szCell[j] + leafCorrection;
7346 pTemp = sqlite3Malloc( sz );//&aOvflSpace[iOvflSpace];
7347 if ( 0 == pNew.leaf )
7348 {
7349 Buffer.BlockCopy( pCell, 0, pNew.aData, 8, 4 );//memcpy( pNew.aData[8], pCell, 4 );
7350 }
7351 else if ( leafData != 0 )
7352 {
7353 /* If the tree is a leaf-data tree, and the siblings are leaves,
7354 ** then there is no divider cell in apCell[]. Instead, the divider
7355 ** cell consists of the integer key for the right-most cell of
7356 ** the sibling-page assembled above only.
7357 */
7358 CellInfo info = new CellInfo();
7359 j--;
7360 btreeParseCellPtr( pNew, apCell[j], ref info );
7361 pCell = pTemp;
7362 sz = 4 + putVarint( pCell, 4, (u64)info.nKey );
7363 pTemp = null;
7364 }
7365 else
7366 {
7367 //------------ pCell -= 4;
7368 byte[] _pCell_4 = sqlite3Malloc( pCell.Length + 4 );
7369 Buffer.BlockCopy( pCell, 0, _pCell_4, 4, pCell.Length );
7370 pCell = _pCell_4;
7371 //
7372 /* Obscure case for non-leaf-data trees: If the cell at pCell was
7373 ** previously stored on a leaf node, and its reported size was 4
7374 ** bytes, then it may actually be smaller than this
7375 ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
7376 ** any cell). But it is important to pass the correct size to
7377 ** insertCell(), so reparse the cell now.
7378 **
7379 ** Note that this can never happen in an SQLite data file, as all
7380 ** cells are at least 4 bytes. It only happens in b-trees used
7381 ** to evaluate "IN (SELECT ...)" and similar clauses.
7382 */
7383 if ( szCell[j] == 4 )
7384 {
7385 Debug.Assert( leafCorrection == 4 );
7386 sz = cellSizePtr( pParent, pCell );
7387 }
7388 }
7389 iOvflSpace += sz;
7390 Debug.Assert( sz <= pBt.maxLocal + 23 );
7391 Debug.Assert( iOvflSpace <= (int)pBt.pageSize );
7392 insertCell( pParent, nxDiv, pCell, sz, pTemp, pNew.pgno, ref rc );
7393 if ( rc != SQLITE_OK )
7394 goto balance_cleanup;
7395 Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
7396  
7397 j++;
7398 nxDiv++;
7399 }
7400 }
7401 Debug.Assert( j == nCell );
7402 Debug.Assert( nOld > 0 );
7403 Debug.Assert( nNew > 0 );
7404 if ( ( pageFlags & PTF_LEAF ) == 0 )
7405 {
7406 Buffer.BlockCopy( apCopy[nOld - 1].aData, 8, apNew[nNew - 1].aData, 8, 4 ); //u8* zChild = &apCopy[nOld - 1].aData[8];
7407 //memcpy( apNew[nNew - 1].aData[8], zChild, 4 );
7408 }
7409  
7410 if ( isRoot != 0 && pParent.nCell == 0 && pParent.hdrOffset <= apNew[0].nFree )
7411 {
7412 /* The root page of the b-tree now contains no cells. The only sibling
7413 ** page is the right-child of the parent. Copy the contents of the
7414 ** child page into the parent, decreasing the overall height of the
7415 ** b-tree structure by one. This is described as the "balance-shallower"
7416 ** sub-algorithm in some documentation.
7417 **
7418 ** If this is an auto-vacuum database, the call to copyNodeContent()
7419 ** sets all pointer-map entries corresponding to database image pages
7420 ** for which the pointer is stored within the content being copied.
7421 **
7422 ** The second Debug.Assert below verifies that the child page is defragmented
7423 ** (it must be, as it was just reconstructed using assemblePage()). This
7424 ** is important if the parent page happens to be page 1 of the database
7425 ** image. */
7426 Debug.Assert( nNew == 1 );
7427 Debug.Assert( apNew[0].nFree ==
7428 ( get2byte( apNew[0].aData, 5 ) - apNew[0].cellOffset - apNew[0].nCell * 2 )
7429 );
7430 copyNodeContent( apNew[0], pParent, ref rc );
7431 freePage( apNew[0], ref rc );
7432 }
7433 else
7434 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
7435 if ( pBt.autoVacuum )
7436 #else
7437 if (false)
7438 #endif
7439 {
7440 /* Fix the pointer-map entries for all the cells that were shifted around.
7441 ** There are several different types of pointer-map entries that need to
7442 ** be dealt with by this routine. Some of these have been set already, but
7443 ** many have not. The following is a summary:
7444 **
7445 ** 1) The entries associated with new sibling pages that were not
7446 ** siblings when this function was called. These have already
7447 ** been set. We don't need to worry about old siblings that were
7448 ** moved to the free-list - the freePage() code has taken care
7449 ** of those.
7450 **
7451 ** 2) The pointer-map entries associated with the first overflow
7452 ** page in any overflow chains used by new divider cells. These
7453 ** have also already been taken care of by the insertCell() code.
7454 **
7455 ** 3) If the sibling pages are not leaves, then the child pages of
7456 ** cells stored on the sibling pages may need to be updated.
7457 **
7458 ** 4) If the sibling pages are not internal intkey nodes, then any
7459 ** overflow pages used by these cells may need to be updated
7460 ** (internal intkey nodes never contain pointers to overflow pages).
7461 **
7462 ** 5) If the sibling pages are not leaves, then the pointer-map
7463 ** entries for the right-child pages of each sibling may need
7464 ** to be updated.
7465 **
7466 ** Cases 1 and 2 are dealt with above by other code. The next
7467 ** block deals with cases 3 and 4 and the one after that, case 5. Since
7468 ** setting a pointer map entry is a relatively expensive operation, this
7469 ** code only sets pointer map entries for child or overflow pages that have
7470 ** actually moved between pages. */
7471 MemPage pNew = apNew[0];
7472 MemPage pOld = apCopy[0];
7473 int nOverflow = pOld.nOverflow;
7474 int iNextOld = pOld.nCell + nOverflow;
7475 int iOverflow = ( nOverflow != 0 ? pOld.aOvfl[0].idx : -1 );
7476 j = 0; /* Current 'old' sibling page */
7477 k = 0; /* Current 'new' sibling page */
7478 for ( i = 0; i < nCell; i++ )
7479 {
7480 int isDivider = 0;
7481 while ( i == iNextOld )
7482 {
7483 /* Cell i is the cell immediately following the last cell on old
7484 ** sibling page j. If the siblings are not leaf pages of an
7485 ** intkey b-tree, then cell i was a divider cell. */
7486 pOld = apCopy[++j];
7487 iNextOld = i + ( 0 == leafData ? 1 : 0 ) + pOld.nCell + pOld.nOverflow;
7488 if ( pOld.nOverflow != 0 )
7489 {
7490 nOverflow = pOld.nOverflow;
7491 iOverflow = i + ( 0 == leafData ? 1 : 0 ) + pOld.aOvfl[0].idx;
7492 }
7493 isDivider = 0 == leafData ? 1 : 0;
7494 }
7495  
7496 Debug.Assert( nOverflow > 0 || iOverflow < i );
7497 Debug.Assert( nOverflow < 2 || pOld.aOvfl[0].idx == pOld.aOvfl[1].idx - 1 );
7498 Debug.Assert( nOverflow < 3 || pOld.aOvfl[1].idx == pOld.aOvfl[2].idx - 1 );
7499 if ( i == iOverflow )
7500 {
7501 isDivider = 1;
7502 if ( ( --nOverflow ) > 0 )
7503 {
7504 iOverflow++;
7505 }
7506 }
7507  
7508 if ( i == cntNew[k] )
7509 {
7510 /* Cell i is the cell immediately following the last cell on new
7511 ** sibling page k. If the siblings are not leaf pages of an
7512 ** intkey b-tree, then cell i is a divider cell. */
7513 pNew = apNew[++k];
7514 if ( 0 == leafData )
7515 continue;
7516 }
7517 Debug.Assert( j < nOld );
7518 Debug.Assert( k < nNew );
7519  
7520 /* If the cell was originally divider cell (and is not now) or
7521 ** an overflow cell, or if the cell was located on a different sibling
7522 ** page before the balancing, then the pointer map entries associated
7523 ** with any child or overflow pages need to be updated. */
7524 if ( isDivider != 0 || pOld.pgno != pNew.pgno )
7525 {
7526 if ( 0 == leafCorrection )
7527 {
7528 ptrmapPut( pBt, sqlite3Get4byte( apCell[i] ), PTRMAP_BTREE, pNew.pgno, ref rc );
7529 }
7530 if ( szCell[i] > pNew.minLocal )
7531 {
7532 ptrmapPutOvflPtr( pNew, apCell[i], ref rc );
7533 }
7534 }
7535 }
7536  
7537 if ( 0 == leafCorrection )
7538 {
7539 for ( i = 0; i < nNew; i++ )
7540 {
7541 u32 key = sqlite3Get4byte( apNew[i].aData, 8 );
7542 ptrmapPut( pBt, key, PTRMAP_BTREE, apNew[i].pgno, ref rc );
7543 }
7544 }
7545  
7546 #if FALSE
7547 /* The ptrmapCheckPages() contains Debug.Assert() statements that verify that
7548 ** all pointer map pages are set correctly. This is helpful while
7549 ** debugging. This is usually disabled because a corrupt database may
7550 ** cause an Debug.Assert() statement to fail. */
7551 ptrmapCheckPages(apNew, nNew);
7552 ptrmapCheckPages(pParent, 1);
7553 #endif
7554 }
7555  
7556 Debug.Assert( pParent.isInit != 0 );
7557 TRACE( "BALANCE: finished: old=%d new=%d cells=%d\n",
7558 nOld, nNew, nCell );
7559  
7560 /*
7561 ** Cleanup before returning.
7562 */
7563 balance_cleanup:
7564 sqlite3ScratchFree( apCell );
7565 for ( i = 0; i < nOld; i++ )
7566 {
7567 releasePage( apOld[i] );
7568 }
7569 for ( i = 0; i < nNew; i++ )
7570 {
7571 releasePage( apNew[i] );
7572 }
7573  
7574 return rc;
7575 }
7576  
7577  
7578 /*
7579 ** This function is called when the root page of a b-tree structure is
7580 ** overfull (has one or more overflow pages).
7581 **
7582 ** A new child page is allocated and the contents of the current root
7583 ** page, including overflow cells, are copied into the child. The root
7584 ** page is then overwritten to make it an empty page with the right-child
7585 ** pointer pointing to the new page.
7586 **
7587 ** Before returning, all pointer-map entries corresponding to pages
7588 ** that the new child-page now contains pointers to are updated. The
7589 ** entry corresponding to the new right-child pointer of the root
7590 ** page is also updated.
7591 **
7592 ** If successful, ppChild is set to contain a reference to the child
7593 ** page and SQLITE_OK is returned. In this case the caller is required
7594 ** to call releasePage() on ppChild exactly once. If an error occurs,
7595 ** an error code is returned and ppChild is set to 0.
7596 */
7597 static int balance_deeper( MemPage pRoot, ref MemPage ppChild )
7598 {
7599 int rc; /* Return value from subprocedures */
7600 MemPage pChild = null; /* Pointer to a new child page */
7601 Pgno pgnoChild = 0; /* Page number of the new child page */
7602 BtShared pBt = pRoot.pBt; /* The BTree */
7603  
7604 Debug.Assert( pRoot.nOverflow > 0 );
7605 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
7606  
7607 /* Make pRoot, the root page of the b-tree, writable. Allocate a new
7608 ** page that will become the new right-child of pPage. Copy the contents
7609 ** of the node stored on pRoot into the new child page.
7610 */
7611 rc = sqlite3PagerWrite( pRoot.pDbPage );
7612 if ( rc == SQLITE_OK )
7613 {
7614 rc = allocateBtreePage( pBt, ref pChild, ref pgnoChild, pRoot.pgno, 0 );
7615 copyNodeContent( pRoot, pChild, ref rc );
7616 #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
7617 if ( pBt.autoVacuum )
7618 #else
7619 if (false)
7620 #endif
7621 {
7622 ptrmapPut( pBt, pgnoChild, PTRMAP_BTREE, pRoot.pgno, ref rc );
7623 }
7624 }
7625 if ( rc != 0 )
7626 {
7627 ppChild = null;
7628 releasePage( pChild );
7629 return rc;
7630 }
7631 Debug.Assert( sqlite3PagerIswriteable( pChild.pDbPage ) );
7632 Debug.Assert( sqlite3PagerIswriteable( pRoot.pDbPage ) );
7633 Debug.Assert( pChild.nCell == pRoot.nCell );
7634  
7635 TRACE( "BALANCE: copy root %d into %d\n", pRoot.pgno, pChild.pgno );
7636  
7637 /* Copy the overflow cells from pRoot to pChild */
7638 Array.Copy( pRoot.aOvfl, pChild.aOvfl, pRoot.nOverflow );//memcpy(pChild.aOvfl, pRoot.aOvfl, pRoot.nOverflow*sizeof(pRoot.aOvfl[0]));
7639 pChild.nOverflow = pRoot.nOverflow;
7640  
7641 /* Zero the contents of pRoot. Then install pChild as the right-child. */
7642 zeroPage( pRoot, pChild.aData[0] & ~PTF_LEAF );
7643 sqlite3Put4byte( pRoot.aData, pRoot.hdrOffset + 8, pgnoChild );
7644  
7645 ppChild = pChild;
7646 return SQLITE_OK;
7647 }
7648  
7649 /*
7650 ** The page that pCur currently points to has just been modified in
7651 ** some way. This function figures out if this modification means the
7652 ** tree needs to be balanced, and if so calls the appropriate balancing
7653 ** routine. Balancing routines are:
7654 **
7655 ** balance_quick()
7656 ** balance_deeper()
7657 ** balance_nonroot()
7658 */
7659 static u8[] aBalanceQuickSpace = new u8[13];
7660 static int balance( BtCursor pCur )
7661 {
7662 int rc = SQLITE_OK;
7663 int nMin = (int)pCur.pBt.usableSize * 2 / 3;
7664  
7665 //u8[] pFree = null;
7666  
7667 #if !NDEBUG || SQLITE_COVERAGE_TEST || DEBUG
7668 int balance_quick_called = 0;//TESTONLY( int balance_quick_called = 0 );
7669 int balance_deeper_called = 0;//TESTONLY( int balance_deeper_called = 0 );
7670 #else
7671 int balance_quick_called = 0;
7672 int balance_deeper_called = 0;
7673 #endif
7674  
7675 do
7676 {
7677 int iPage = pCur.iPage;
7678 MemPage pPage = pCur.apPage[iPage];
7679  
7680 if ( iPage == 0 )
7681 {
7682 if ( pPage.nOverflow != 0 )
7683 {
7684 /* The root page of the b-tree is overfull. In this case call the
7685 ** balance_deeper() function to create a new child for the root-page
7686 ** and copy the current contents of the root-page to it. The
7687 ** next iteration of the do-loop will balance the child page.
7688 */
7689 Debug.Assert( ( balance_deeper_called++ ) == 0 );
7690 rc = balance_deeper( pPage, ref pCur.apPage[1] );
7691 if ( rc == SQLITE_OK )
7692 {
7693 pCur.iPage = 1;
7694 pCur.aiIdx[0] = 0;
7695 pCur.aiIdx[1] = 0;
7696 Debug.Assert( pCur.apPage[1].nOverflow != 0 );
7697 }
7698 }
7699 else
7700 {
7701 break;
7702 }
7703 }
7704 else if ( pPage.nOverflow == 0 && pPage.nFree <= nMin )
7705 {
7706 break;
7707 }
7708 else
7709 {
7710 MemPage pParent = pCur.apPage[iPage - 1];
7711 int iIdx = pCur.aiIdx[iPage - 1];
7712  
7713 rc = sqlite3PagerWrite( pParent.pDbPage );
7714 if ( rc == SQLITE_OK )
7715 {
7716 #if !SQLITE_OMIT_QUICKBALANCE
7717 if ( pPage.hasData != 0
7718 && pPage.nOverflow == 1
7719 && pPage.aOvfl[0].idx == pPage.nCell
7720 && pParent.pgno != 1
7721 && pParent.nCell == iIdx
7722 )
7723 {
7724 /* Call balance_quick() to create a new sibling of pPage on which
7725 ** to store the overflow cell. balance_quick() inserts a new cell
7726 ** into pParent, which may cause pParent overflow. If this
7727 ** happens, the next interation of the do-loop will balance pParent
7728 ** use either balance_nonroot() or balance_deeper(). Until this
7729 ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
7730 ** buffer.
7731 **
7732 ** The purpose of the following Debug.Assert() is to check that only a
7733 ** single call to balance_quick() is made for each call to this
7734 ** function. If this were not verified, a subtle bug involving reuse
7735 ** of the aBalanceQuickSpace[] might sneak in.
7736 */
7737 Debug.Assert( ( balance_quick_called++ ) == 0 );
7738 rc = balance_quick( pParent, pPage, aBalanceQuickSpace );
7739 }
7740 else
7741 #endif
7742 {
7743 /* In this case, call balance_nonroot() to redistribute cells
7744 ** between pPage and up to 2 of its sibling pages. This involves
7745 ** modifying the contents of pParent, which may cause pParent to
7746 ** become overfull or underfull. The next iteration of the do-loop
7747 ** will balance the parent page to correct this.
7748 **
7749 ** If the parent page becomes overfull, the overflow cell or cells
7750 ** are stored in the pSpace buffer allocated immediately below.
7751 ** A subsequent iteration of the do-loop will deal with this by
7752 ** calling balance_nonroot() (balance_deeper() may be called first,
7753 ** but it doesn't deal with overflow cells - just moves them to a
7754 ** different page). Once this subsequent call to balance_nonroot()
7755 ** has completed, it is safe to release the pSpace buffer used by
7756 ** the previous call, as the overflow cell data will have been
7757 ** copied either into the body of a database page or into the new
7758 ** pSpace buffer passed to the latter call to balance_nonroot().
7759 */
7760 ////u8[] pSpace = new u8[pCur.pBt.pageSize];// u8 pSpace = sqlite3PageMalloc( pCur.pBt.pageSize );
7761 rc = balance_nonroot( pParent, iIdx, null, iPage == 1 ? 1 : 0 );
7762 //if (pFree != null)
7763 //{
7764 // /* If pFree is not NULL, it points to the pSpace buffer used
7765 // ** by a previous call to balance_nonroot(). Its contents are
7766 // ** now stored either on real database pages or within the
7767 // ** new pSpace buffer, so it may be safely freed here. */
7768 // sqlite3PageFree(ref pFree);
7769 //}
7770  
7771 /* The pSpace buffer will be freed after the next call to
7772 ** balance_nonroot(), or just before this function returns, whichever
7773 ** comes first. */
7774 //pFree = pSpace;
7775 }
7776 }
7777  
7778 pPage.nOverflow = 0;
7779  
7780 /* The next iteration of the do-loop balances the parent page. */
7781 releasePage( pPage );
7782 pCur.iPage--;
7783 }
7784 } while ( rc == SQLITE_OK );
7785  
7786 //if (pFree != null)
7787 //{
7788 // sqlite3PageFree(ref pFree);
7789 //}
7790 return rc;
7791 }
7792  
7793  
7794 /*
7795 ** Insert a new record into the BTree. The key is given by (pKey,nKey)
7796 ** and the data is given by (pData,nData). The cursor is used only to
7797 ** define what table the record should be inserted into. The cursor
7798 ** is left pointing at a random location.
7799 **
7800 ** For an INTKEY table, only the nKey value of the key is used. pKey is
7801 ** ignored. For a ZERODATA table, the pData and nData are both ignored.
7802 **
7803 ** If the seekResult parameter is non-zero, then a successful call to
7804 ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
7805 ** been performed. seekResult is the search result returned (a negative
7806 ** number if pCur points at an entry that is smaller than (pKey, nKey), or
7807 ** a positive value if pCur points at an etry that is larger than
7808 ** (pKey, nKey)).
7809 **
7810 ** If the seekResult parameter is non-zero, then the caller guarantees that
7811 ** cursor pCur is pointing at the existing copy of a row that is to be
7812 ** overwritten. If the seekResult parameter is 0, then cursor pCur may
7813 ** point to any entry or to no entry at all and so this function has to seek
7814 ** the cursor before the new key can be inserted.
7815 */
7816 static int sqlite3BtreeInsert(
7817 BtCursor pCur, /* Insert data into the table of this cursor */
7818 byte[] pKey, i64 nKey, /* The key of the new record */
7819 byte[] pData, int nData, /* The data of the new record */
7820 int nZero, /* Number of extra 0 bytes to append to data */
7821 int appendBias, /* True if this is likely an append */
7822 int seekResult /* Result of prior MovetoUnpacked() call */
7823 )
7824 {
7825 int rc;
7826 int loc = seekResult; /* -1: before desired location +1: after */
7827 int szNew = 0;
7828 int idx;
7829 MemPage pPage;
7830 Btree p = pCur.pBtree;
7831 BtShared pBt = p.pBt;
7832 int oldCell;
7833 byte[] newCell = null;
7834  
7835 if ( pCur.eState == CURSOR_FAULT )
7836 {
7837 Debug.Assert( pCur.skipNext != SQLITE_OK );
7838 return pCur.skipNext;
7839 }
7840  
7841 Debug.Assert( cursorHoldsMutex( pCur ) );
7842 Debug.Assert( pCur.wrFlag != 0 && pBt.inTransaction == TRANS_WRITE && !pBt.readOnly );
7843 Debug.Assert( hasSharedCacheTableLock( p, pCur.pgnoRoot, pCur.pKeyInfo != null ? 1 : 0, 2 ) );
7844  
7845 /* Assert that the caller has been consistent. If this cursor was opened
7846 ** expecting an index b-tree, then the caller should be inserting blob
7847 ** keys with no associated data. If the cursor was opened expecting an
7848 ** intkey table, the caller should be inserting integer keys with a
7849 ** blob of associated data. */
7850 Debug.Assert( ( pKey == null ) == ( pCur.pKeyInfo == null ) );
7851  
7852 /* If this is an insert into a table b-tree, invalidate any incrblob
7853 ** cursors open on the row being replaced (assuming this is a replace
7854 ** operation - if it is not, the following is a no-op). */
7855 if ( pCur.pKeyInfo == null )
7856 {
7857 invalidateIncrblobCursors( p, nKey, 0 );
7858 }
7859  
7860 /* Save the positions of any other cursors open on this table.
7861 **
7862 ** In some cases, the call to btreeMoveto() below is a no-op. For
7863 ** example, when inserting data into a table with auto-generated integer
7864 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
7865 ** integer key to use. It then calls this function to actually insert the
7866 ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
7867 ** that the cursor is already where it needs to be and returns without
7868 ** doing any work. To avoid thwarting these optimizations, it is important
7869 ** not to clear the cursor here.
7870 */
7871 rc = saveAllCursors( pBt, pCur.pgnoRoot, pCur );
7872 if ( rc != 0 )
7873 return rc;
7874 if ( 0 == loc )
7875 {
7876 rc = btreeMoveto( pCur, pKey, nKey, appendBias, ref loc );
7877 if ( rc != 0 )
7878 return rc;
7879 }
7880 Debug.Assert( pCur.eState == CURSOR_VALID || ( pCur.eState == CURSOR_INVALID && loc != 0 ) );
7881  
7882 pPage = pCur.apPage[pCur.iPage];
7883 Debug.Assert( pPage.intKey != 0 || nKey >= 0 );
7884 Debug.Assert( pPage.leaf != 0 || 0 == pPage.intKey );
7885  
7886 TRACE( "INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
7887 pCur.pgnoRoot, nKey, nData, pPage.pgno,
7888 loc == 0 ? "overwrite" : "new entry" );
7889 Debug.Assert( pPage.isInit != 0 );
7890 allocateTempSpace( pBt );
7891 newCell = pBt.pTmpSpace;
7892 //if (newCell == null) return SQLITE_NOMEM;
7893 rc = fillInCell( pPage, newCell, pKey, nKey, pData, nData, nZero, ref szNew );
7894 if ( rc != 0 )
7895 goto end_insert;
7896 Debug.Assert( szNew == cellSizePtr( pPage, newCell ) );
7897 Debug.Assert( szNew <= MX_CELL_SIZE( pBt ) );
7898 idx = pCur.aiIdx[pCur.iPage];
7899 if ( loc == 0 )
7900 {
7901 u16 szOld;
7902 Debug.Assert( idx < pPage.nCell );
7903 rc = sqlite3PagerWrite( pPage.pDbPage );
7904 if ( rc != 0 )
7905 {
7906 goto end_insert;
7907 }
7908 oldCell = findCell( pPage, idx );
7909 if ( 0 == pPage.leaf )
7910 {
7911 //memcpy(newCell, oldCell, 4);
7912 newCell[0] = pPage.aData[oldCell + 0];
7913 newCell[1] = pPage.aData[oldCell + 1];
7914 newCell[2] = pPage.aData[oldCell + 2];
7915 newCell[3] = pPage.aData[oldCell + 3];
7916 }
7917 szOld = cellSizePtr( pPage, oldCell );
7918 rc = clearCell( pPage, oldCell );
7919 dropCell( pPage, idx, szOld, ref rc );
7920 if ( rc != 0 )
7921 goto end_insert;
7922 }
7923 else if ( loc < 0 && pPage.nCell > 0 )
7924 {
7925 Debug.Assert( pPage.leaf != 0 );
7926 idx = ++pCur.aiIdx[pCur.iPage];
7927 }
7928 else
7929 {
7930 Debug.Assert( pPage.leaf != 0 );
7931 }
7932 insertCell( pPage, idx, newCell, szNew, null, 0, ref rc );
7933 Debug.Assert( rc != SQLITE_OK || pPage.nCell > 0 || pPage.nOverflow > 0 );
7934  
7935 /* If no error has occured and pPage has an overflow cell, call balance()
7936 ** to redistribute the cells within the tree. Since balance() may move
7937 ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
7938 ** variables.
7939 **
7940 ** Previous versions of SQLite called moveToRoot() to move the cursor
7941 ** back to the root page as balance() used to invalidate the contents
7942 ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
7943 ** set the cursor state to "invalid". This makes common insert operations
7944 ** slightly faster.
7945 **
7946 ** There is a subtle but important optimization here too. When inserting
7947 ** multiple records into an intkey b-tree using a single cursor (as can
7948 ** happen while processing an "INSERT INTO ... SELECT" statement), it
7949 ** is advantageous to leave the cursor pointing to the last entry in
7950 ** the b-tree if possible. If the cursor is left pointing to the last
7951 ** entry in the table, and the next row inserted has an integer key
7952 ** larger than the largest existing key, it is possible to insert the
7953 ** row without seeking the cursor. This can be a big performance boost.
7954 */
7955 pCur.info.nSize = 0;
7956 pCur.validNKey = false;
7957 if ( rc == SQLITE_OK && pPage.nOverflow != 0 )
7958 {
7959 rc = balance( pCur );
7960  
7961 /* Must make sure nOverflow is reset to zero even if the balance()
7962 ** fails. Internal data structure corruption will result otherwise.
7963 ** Also, set the cursor state to invalid. This stops saveCursorPosition()
7964 ** from trying to save the current position of the cursor. */
7965 pCur.apPage[pCur.iPage].nOverflow = 0;
7966 pCur.eState = CURSOR_INVALID;
7967 }
7968 Debug.Assert( pCur.apPage[pCur.iPage].nOverflow == 0 );
7969  
7970 end_insert:
7971 return rc;
7972 }
7973  
7974 /*
7975 ** Delete the entry that the cursor is pointing to. The cursor
7976 ** is left pointing at a arbitrary location.
7977 */
7978 static int sqlite3BtreeDelete( BtCursor pCur )
7979 {
7980 Btree p = pCur.pBtree;
7981 BtShared pBt = p.pBt;
7982 int rc; /* Return code */
7983 MemPage pPage; /* Page to delete cell from */
7984 int pCell; /* Pointer to cell to delete */
7985 int iCellIdx; /* Index of cell to delete */
7986 int iCellDepth; /* Depth of node containing pCell */
7987  
7988 Debug.Assert( cursorHoldsMutex( pCur ) );
7989 Debug.Assert( pBt.inTransaction == TRANS_WRITE );
7990 Debug.Assert( !pBt.readOnly );
7991 Debug.Assert( pCur.wrFlag != 0 );
7992 Debug.Assert( hasSharedCacheTableLock( p, pCur.pgnoRoot, pCur.pKeyInfo != null ? 1 : 0, 2 ) );
7993 Debug.Assert( !hasReadConflicts( p, pCur.pgnoRoot ) );
7994  
7995 if ( NEVER( pCur.aiIdx[pCur.iPage] >= pCur.apPage[pCur.iPage].nCell )
7996 || NEVER( pCur.eState != CURSOR_VALID )
7997 )
7998 {
7999 return SQLITE_ERROR; /* Something has gone awry. */
8000 }
8001  
8002 /* If this is a delete operation to remove a row from a table b-tree,
8003 ** invalidate any incrblob cursors open on the row being deleted. */
8004 if ( pCur.pKeyInfo == null )
8005 {
8006 invalidateIncrblobCursors( p, pCur.info.nKey, 0 );
8007 }
8008  
8009 iCellDepth = pCur.iPage;
8010 iCellIdx = pCur.aiIdx[iCellDepth];
8011 pPage = pCur.apPage[iCellDepth];
8012 pCell = findCell( pPage, iCellIdx );
8013  
8014 /* If the page containing the entry to delete is not a leaf page, move
8015 ** the cursor to the largest entry in the tree that is smaller than
8016 ** the entry being deleted. This cell will replace the cell being deleted
8017 ** from the internal node. The 'previous' entry is used for this instead
8018 ** of the 'next' entry, as the previous entry is always a part of the
8019 ** sub-tree headed by the child page of the cell being deleted. This makes
8020 ** balancing the tree following the delete operation easier. */
8021 if ( 0 == pPage.leaf )
8022 {
8023 int notUsed = 0;
8024 rc = sqlite3BtreePrevious( pCur, ref notUsed );
8025 if ( rc != 0 )
8026 return rc;
8027 }
8028  
8029 /* Save the positions of any other cursors open on this table before
8030 ** making any modifications. Make the page containing the entry to be
8031 ** deleted writable. Then free any overflow pages associated with the
8032 ** entry and finally remove the cell itself from within the page.
8033 */
8034 rc = saveAllCursors( pBt, pCur.pgnoRoot, pCur );
8035 if ( rc != 0 )
8036 return rc;
8037 rc = sqlite3PagerWrite( pPage.pDbPage );
8038 if ( rc != 0 )
8039 return rc;
8040 rc = clearCell( pPage, pCell );
8041 dropCell( pPage, iCellIdx, cellSizePtr( pPage, pCell ), ref rc );
8042 if ( rc != 0 )
8043 return rc;
8044  
8045 /* If the cell deleted was not located on a leaf page, then the cursor
8046 ** is currently pointing to the largest entry in the sub-tree headed
8047 ** by the child-page of the cell that was just deleted from an internal
8048 ** node. The cell from the leaf node needs to be moved to the internal
8049 ** node to replace the deleted cell. */
8050 if ( 0 == pPage.leaf )
8051 {
8052 MemPage pLeaf = pCur.apPage[pCur.iPage];
8053 int nCell;
8054 Pgno n = pCur.apPage[iCellDepth + 1].pgno;
8055 //byte[] pTmp;
8056  
8057 pCell = findCell( pLeaf, pLeaf.nCell - 1 );
8058 nCell = cellSizePtr( pLeaf, pCell );
8059 Debug.Assert( MX_CELL_SIZE( pBt ) >= nCell );
8060  
8061 //allocateTempSpace(pBt);
8062 //pTmp = pBt.pTmpSpace;
8063  
8064 rc = sqlite3PagerWrite( pLeaf.pDbPage );
8065 byte[] pNext_4 = sqlite3Malloc( nCell + 4 );
8066 Buffer.BlockCopy( pLeaf.aData, pCell - 4, pNext_4, 0, nCell + 4 );
8067 insertCell( pPage, iCellIdx, pNext_4, nCell + 4, null, n, ref rc ); //insertCell( pPage, iCellIdx, pCell - 4, nCell + 4, pTmp, n, ref rc );
8068 dropCell( pLeaf, pLeaf.nCell - 1, nCell, ref rc );
8069 if ( rc != 0 )
8070 return rc;
8071 }
8072  
8073 /* Balance the tree. If the entry deleted was located on a leaf page,
8074 ** then the cursor still points to that page. In this case the first
8075 ** call to balance() repairs the tree, and the if(...) condition is
8076 ** never true.
8077 **
8078 ** Otherwise, if the entry deleted was on an internal node page, then
8079 ** pCur is pointing to the leaf page from which a cell was removed to
8080 ** replace the cell deleted from the internal node. This is slightly
8081 ** tricky as the leaf node may be underfull, and the internal node may
8082 ** be either under or overfull. In this case run the balancing algorithm
8083 ** on the leaf node first. If the balance proceeds far enough up the
8084 ** tree that we can be sure that any problem in the internal node has
8085 ** been corrected, so be it. Otherwise, after balancing the leaf node,
8086 ** walk the cursor up the tree to the internal node and balance it as
8087 ** well. */
8088 rc = balance( pCur );
8089 if ( rc == SQLITE_OK && pCur.iPage > iCellDepth )
8090 {
8091 while ( pCur.iPage > iCellDepth )
8092 {
8093 releasePage( pCur.apPage[pCur.iPage--] );
8094 }
8095 rc = balance( pCur );
8096 }
8097  
8098 if ( rc == SQLITE_OK )
8099 {
8100 moveToRoot( pCur );
8101 }
8102 return rc;
8103 }
8104  
8105 /*
8106 ** Create a new BTree table. Write into piTable the page
8107 ** number for the root page of the new table.
8108 **
8109 ** The type of type is determined by the flags parameter. Only the
8110 ** following values of flags are currently in use. Other values for
8111 ** flags might not work:
8112 **
8113 ** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys
8114 ** BTREE_ZERODATA Used for SQL indices
8115 */
8116 static int btreeCreateTable( Btree p, ref int piTable, int createTabFlags )
8117 {
8118 BtShared pBt = p.pBt;
8119 MemPage pRoot = new MemPage();
8120 Pgno pgnoRoot = 0;
8121 int rc;
8122 int ptfFlags; /* Page-type flage for the root page of new table */
8123  
8124 Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
8125 Debug.Assert( pBt.inTransaction == TRANS_WRITE );
8126 Debug.Assert( !pBt.readOnly );
8127  
8128 #if SQLITE_OMIT_AUTOVACUUM
8129 rc = allocateBtreePage(pBt, ref pRoot, ref pgnoRoot, 1, 0);
8130 if( rc !=0){
8131 return rc;
8132 }
8133 #else
8134 if ( pBt.autoVacuum )
8135 {
8136 Pgno pgnoMove = 0; /* Move a page here to make room for the root-page */
8137 MemPage pPageMove = new MemPage(); /* The page to move to. */
8138  
8139 /* Creating a new table may probably require moving an existing database
8140 ** to make room for the new tables root page. In case this page turns
8141 ** out to be an overflow page, delete all overflow page-map caches
8142 ** held by open cursors.
8143 */
8144 invalidateAllOverflowCache( pBt );
8145  
8146 /* Read the value of meta[3] from the database to determine where the
8147 ** root page of the new table should go. meta[3] is the largest root-page
8148 ** created so far, so the new root-page is (meta[3]+1).
8149 */
8150 sqlite3BtreeGetMeta( p, BTREE_LARGEST_ROOT_PAGE, ref pgnoRoot );
8151 pgnoRoot++;
8152  
8153 /* The new root-page may not be allocated on a pointer-map page, or the
8154 ** PENDING_BYTE page.
8155 */
8156 while ( pgnoRoot == PTRMAP_PAGENO( pBt, pgnoRoot ) ||
8157 pgnoRoot == PENDING_BYTE_PAGE( pBt ) )
8158 {
8159 pgnoRoot++;
8160 }
8161 Debug.Assert( pgnoRoot >= 3 );
8162  
8163 /* Allocate a page. The page that currently resides at pgnoRoot will
8164 ** be moved to the allocated page (unless the allocated page happens
8165 ** to reside at pgnoRoot).
8166 */
8167 rc = allocateBtreePage( pBt, ref pPageMove, ref pgnoMove, pgnoRoot, 1 );
8168 if ( rc != SQLITE_OK )
8169 {
8170 return rc;
8171 }
8172  
8173 if ( pgnoMove != pgnoRoot )
8174 {
8175 /* pgnoRoot is the page that will be used for the root-page of
8176 ** the new table (assuming an error did not occur). But we were
8177 ** allocated pgnoMove. If required (i.e. if it was not allocated
8178 ** by extending the file), the current page at position pgnoMove
8179 ** is already journaled.
8180 */
8181 u8 eType = 0;
8182 Pgno iPtrPage = 0;
8183  
8184 releasePage( pPageMove );
8185  
8186 /* Move the page currently at pgnoRoot to pgnoMove. */
8187 rc = btreeGetPage( pBt, pgnoRoot, ref pRoot, 0 );
8188 if ( rc != SQLITE_OK )
8189 {
8190 return rc;
8191 }
8192 rc = ptrmapGet( pBt, pgnoRoot, ref eType, ref iPtrPage );
8193 if ( eType == PTRMAP_ROOTPAGE || eType == PTRMAP_FREEPAGE )
8194 {
8195 rc = SQLITE_CORRUPT_BKPT();
8196 }
8197 if ( rc != SQLITE_OK )
8198 {
8199 releasePage( pRoot );
8200 return rc;
8201 }
8202 Debug.Assert( eType != PTRMAP_ROOTPAGE );
8203 Debug.Assert( eType != PTRMAP_FREEPAGE );
8204 rc = relocatePage( pBt, pRoot, eType, iPtrPage, pgnoMove, 0 );
8205 releasePage( pRoot );
8206  
8207 /* Obtain the page at pgnoRoot */
8208 if ( rc != SQLITE_OK )
8209 {
8210 return rc;
8211 }
8212 rc = btreeGetPage( pBt, pgnoRoot, ref pRoot, 0 );
8213 if ( rc != SQLITE_OK )
8214 {
8215 return rc;
8216 }
8217 rc = sqlite3PagerWrite( pRoot.pDbPage );
8218 if ( rc != SQLITE_OK )
8219 {
8220 releasePage( pRoot );
8221 return rc;
8222 }
8223 }
8224 else
8225 {
8226 pRoot = pPageMove;
8227 }
8228  
8229 /* Update the pointer-map and meta-data with the new root-page number. */
8230 ptrmapPut( pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, ref rc );
8231 if ( rc != 0 )
8232 {
8233 releasePage( pRoot );
8234 return rc;
8235 }
8236  
8237 /* When the new root page was allocated, page 1 was made writable in
8238 ** order either to increase the database filesize, or to decrement the
8239 ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail.
8240 */
8241 Debug.Assert( sqlite3PagerIswriteable( pBt.pPage1.pDbPage ) );
8242 rc = sqlite3BtreeUpdateMeta( p, 4, pgnoRoot );
8243 if ( NEVER( rc != 0 ) )
8244 {
8245 releasePage( pRoot );
8246 return rc;
8247 }
8248  
8249 }
8250 else
8251 {
8252 rc = allocateBtreePage( pBt, ref pRoot, ref pgnoRoot, 1, 0 );
8253 if ( rc != 0 )
8254 return rc;
8255 }
8256 #endif
8257 Debug.Assert( sqlite3PagerIswriteable( pRoot.pDbPage ) );
8258 if ( ( createTabFlags & BTREE_INTKEY ) != 0 )
8259 {
8260 ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF;
8261 }
8262 else
8263 {
8264 ptfFlags = PTF_ZERODATA | PTF_LEAF;
8265 }
8266 zeroPage( pRoot, ptfFlags );
8267 sqlite3PagerUnref( pRoot.pDbPage );
8268 Debug.Assert( ( pBt.openFlags & BTREE_SINGLE ) == 0 || pgnoRoot == 2 );
8269 piTable = (int)pgnoRoot;
8270 return SQLITE_OK;
8271 }
8272 static int sqlite3BtreeCreateTable( Btree p, ref int piTable, int flags )
8273 {
8274 int rc;
8275 sqlite3BtreeEnter( p );
8276 rc = btreeCreateTable( p, ref piTable, flags );
8277 sqlite3BtreeLeave( p );
8278 return rc;
8279 }
8280  
8281 /*
8282 ** Erase the given database page and all its children. Return
8283 ** the page to the freelist.
8284 */
8285 static int clearDatabasePage(
8286 BtShared pBt, /* The BTree that contains the table */
8287 Pgno pgno, /* Page number to clear */
8288 int freePageFlag, /* Deallocate page if true */
8289 ref int pnChange /* Add number of Cells freed to this counter */
8290 )
8291 {
8292 MemPage pPage = new MemPage();
8293 int rc;
8294 byte[] pCell;
8295 int i;
8296  
8297 Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
8298 if ( pgno > btreePagecount( pBt ) )
8299 {
8300 return SQLITE_CORRUPT_BKPT();
8301 }
8302  
8303 rc = getAndInitPage( pBt, pgno, ref pPage );
8304 if ( rc != 0 )
8305 return rc;
8306 for ( i = 0; i < pPage.nCell; i++ )
8307 {
8308 int iCell = findCell( pPage, i );
8309 pCell = pPage.aData; // pCell = findCell( pPage, i );
8310 if ( 0 == pPage.leaf )
8311 {
8312 rc = clearDatabasePage( pBt, sqlite3Get4byte( pCell, iCell ), 1, ref pnChange );
8313 if ( rc != 0 )
8314 goto cleardatabasepage_out;
8315 }
8316 rc = clearCell( pPage, iCell );
8317 if ( rc != 0 )
8318 goto cleardatabasepage_out;
8319 }
8320 if ( 0 == pPage.leaf )
8321 {
8322 rc = clearDatabasePage( pBt, sqlite3Get4byte( pPage.aData, 8 ), 1, ref pnChange );
8323 if ( rc != 0 )
8324 goto cleardatabasepage_out;
8325 }
8326 else //if (pnChange != 0)
8327 {
8328 //Debug.Assert(pPage.intKey != 0);
8329 pnChange += pPage.nCell;
8330 }
8331 if ( freePageFlag != 0 )
8332 {
8333 freePage( pPage, ref rc );
8334 }
8335 else if ( ( rc = sqlite3PagerWrite( pPage.pDbPage ) ) == 0 )
8336 {
8337 zeroPage( pPage, pPage.aData[0] | PTF_LEAF );
8338 }
8339  
8340 cleardatabasepage_out:
8341 releasePage( pPage );
8342 return rc;
8343 }
8344  
8345 /*
8346 ** Delete all information from a single table in the database. iTable is
8347 ** the page number of the root of the table. After this routine returns,
8348 ** the root page is empty, but still exists.
8349 **
8350 ** This routine will fail with SQLITE_LOCKED if there are any open
8351 ** read cursors on the table. Open write cursors are moved to the
8352 ** root of the table.
8353 **
8354 ** If pnChange is not NULL, then table iTable must be an intkey table. The
8355 ** integer value pointed to by pnChange is incremented by the number of
8356 ** entries in the table.
8357 */
8358 static int sqlite3BtreeClearTable( Btree p, int iTable, ref int pnChange )
8359 {
8360 int rc;
8361 BtShared pBt = p.pBt;
8362 sqlite3BtreeEnter( p );
8363 Debug.Assert( p.inTrans == TRANS_WRITE );
8364  
8365 /* Invalidate all incrblob cursors open on table iTable (assuming iTable
8366 ** is the root of a table b-tree - if it is not, the following call is
8367 ** a no-op). */
8368 invalidateIncrblobCursors( p, 0, 1 );
8369  
8370 rc = saveAllCursors( pBt, (Pgno)iTable, null );
8371 if ( SQLITE_OK == rc )
8372 {
8373 rc = clearDatabasePage( pBt, (Pgno)iTable, 0, ref pnChange );
8374 }
8375 sqlite3BtreeLeave( p );
8376 return rc;
8377 }
8378  
8379 /*
8380 ** Erase all information in a table and add the root of the table to
8381 ** the freelist. Except, the root of the principle table (the one on
8382 ** page 1) is never added to the freelist.
8383 **
8384 ** This routine will fail with SQLITE_LOCKED if there are any open
8385 ** cursors on the table.
8386 **
8387 ** If AUTOVACUUM is enabled and the page at iTable is not the last
8388 ** root page in the database file, then the last root page
8389 ** in the database file is moved into the slot formerly occupied by
8390 ** iTable and that last slot formerly occupied by the last root page
8391 ** is added to the freelist instead of iTable. In this say, all
8392 ** root pages are kept at the beginning of the database file, which
8393 ** is necessary for AUTOVACUUM to work right. piMoved is set to the
8394 ** page number that used to be the last root page in the file before
8395 ** the move. If no page gets moved, piMoved is set to 0.
8396 ** The last root page is recorded in meta[3] and the value of
8397 ** meta[3] is updated by this procedure.
8398 */
8399 static int btreeDropTable( Btree p, Pgno iTable, ref int piMoved )
8400 {
8401 int rc;
8402 MemPage pPage = null;
8403 BtShared pBt = p.pBt;
8404  
8405 Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
8406 Debug.Assert( p.inTrans == TRANS_WRITE );
8407  
8408 /* It is illegal to drop a table if any cursors are open on the
8409 ** database. This is because in auto-vacuum mode the backend may
8410 ** need to move another root-page to fill a gap left by the deleted
8411 ** root page. If an open cursor was using this page a problem would
8412 ** occur.
8413 **
8414 ** This error is caught long before control reaches this point.
8415 */
8416 if ( NEVER( pBt.pCursor ) )
8417 {
8418 sqlite3ConnectionBlocked( p.db, pBt.pCursor.pBtree.db );
8419 return SQLITE_LOCKED_SHAREDCACHE;
8420 }
8421  
8422 rc = btreeGetPage( pBt, (Pgno)iTable, ref pPage, 0 );
8423 if ( rc != 0 )
8424 return rc;
8425 int Dummy0 = 0;
8426 rc = sqlite3BtreeClearTable( p, (int)iTable, ref Dummy0 );
8427 if ( rc != 0 )
8428 {
8429 releasePage( pPage );
8430 return rc;
8431 }
8432  
8433 piMoved = 0;
8434  
8435 if ( iTable > 1 )
8436 {
8437 #if SQLITE_OMIT_AUTOVACUUM
8438 freePage(pPage, ref rc);
8439 releasePage(pPage);
8440 #else
8441 if ( pBt.autoVacuum )
8442 {
8443 Pgno maxRootPgno = 0;
8444 sqlite3BtreeGetMeta( p, BTREE_LARGEST_ROOT_PAGE, ref maxRootPgno );
8445  
8446 if ( iTable == maxRootPgno )
8447 {
8448 /* If the table being dropped is the table with the largest root-page
8449 ** number in the database, put the root page on the free list.
8450 */
8451 freePage( pPage, ref rc );
8452 releasePage( pPage );
8453 if ( rc != SQLITE_OK )
8454 {
8455 return rc;
8456 }
8457 }
8458 else
8459 {
8460 /* The table being dropped does not have the largest root-page
8461 ** number in the database. So move the page that does into the
8462 ** gap left by the deleted root-page.
8463 */
8464 MemPage pMove = new MemPage();
8465 releasePage( pPage );
8466 rc = btreeGetPage( pBt, maxRootPgno, ref pMove, 0 );
8467 if ( rc != SQLITE_OK )
8468 {
8469 return rc;
8470 }
8471 rc = relocatePage( pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0 );
8472 releasePage( pMove );
8473 if ( rc != SQLITE_OK )
8474 {
8475 return rc;
8476 }
8477 pMove = null;
8478 rc = btreeGetPage( pBt, maxRootPgno, ref pMove, 0 );
8479 freePage( pMove, ref rc );
8480 releasePage( pMove );
8481 if ( rc != SQLITE_OK )
8482 {
8483 return rc;
8484 }
8485 piMoved = (int)maxRootPgno;
8486 }
8487  
8488 /* Set the new 'max-root-page' value in the database header. This
8489 ** is the old value less one, less one more if that happens to
8490 ** be a root-page number, less one again if that is the
8491 ** PENDING_BYTE_PAGE.
8492 */
8493 maxRootPgno--;
8494 while ( maxRootPgno == PENDING_BYTE_PAGE( pBt )
8495 || PTRMAP_ISPAGE( pBt, maxRootPgno ) )
8496 {
8497 maxRootPgno--;
8498 }
8499 Debug.Assert( maxRootPgno != PENDING_BYTE_PAGE( pBt ) );
8500  
8501 rc = sqlite3BtreeUpdateMeta( p, 4, maxRootPgno );
8502 }
8503 else
8504 {
8505 freePage( pPage, ref rc );
8506 releasePage( pPage );
8507 }
8508 #endif
8509 }
8510 else
8511 {
8512 /* If sqlite3BtreeDropTable was called on page 1.
8513 ** This really never should happen except in a corrupt
8514 ** database.
8515 */
8516 zeroPage( pPage, PTF_INTKEY | PTF_LEAF );
8517 releasePage( pPage );
8518 }
8519 return rc;
8520 }
8521 static int sqlite3BtreeDropTable( Btree p, int iTable, ref int piMoved )
8522 {
8523 int rc;
8524 sqlite3BtreeEnter( p );
8525 rc = btreeDropTable( p, (u32)iTable, ref piMoved );
8526 sqlite3BtreeLeave( p );
8527 return rc;
8528 }
8529  
8530  
8531 /*
8532 ** This function may only be called if the b-tree connection already
8533 ** has a read or write transaction open on the database.
8534 **
8535 ** Read the meta-information out of a database file. Meta[0]
8536 ** is the number of free pages currently in the database. Meta[1]
8537 ** through meta[15] are available for use by higher layers. Meta[0]
8538 ** is read-only, the others are read/write.
8539 **
8540 ** The schema layer numbers meta values differently. At the schema
8541 ** layer (and the SetCookie and ReadCookie opcodes) the number of
8542 ** free pages is not visible. So Cookie[0] is the same as Meta[1].
8543 */
8544 static void sqlite3BtreeGetMeta( Btree p, int idx, ref u32 pMeta )
8545 {
8546 BtShared pBt = p.pBt;
8547  
8548 sqlite3BtreeEnter( p );
8549 Debug.Assert( p.inTrans > TRANS_NONE );
8550 Debug.Assert( SQLITE_OK == querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK ) );
8551 Debug.Assert( pBt.pPage1 != null );
8552 Debug.Assert( idx >= 0 && idx <= 15 );
8553  
8554 pMeta = sqlite3Get4byte( pBt.pPage1.aData, 36 + idx * 4 );
8555  
8556 /* If auto-vacuum is disabled in this build and this is an auto-vacuum
8557 ** database, mark the database as read-only. */
8558 #if SQLITE_OMIT_AUTOVACUUM
8559 if( idx==BTREE_LARGEST_ROOT_PAGE && pMeta>0 ) pBt.readOnly = 1;
8560 #endif
8561  
8562 sqlite3BtreeLeave( p );
8563 }
8564  
8565 /*
8566 ** Write meta-information back into the database. Meta[0] is
8567 ** read-only and may not be written.
8568 */
8569 static int sqlite3BtreeUpdateMeta( Btree p, int idx, u32 iMeta )
8570 {
8571 BtShared pBt = p.pBt;
8572 byte[] pP1;
8573 int rc;
8574 Debug.Assert( idx >= 1 && idx <= 15 );
8575 sqlite3BtreeEnter( p );
8576 Debug.Assert( p.inTrans == TRANS_WRITE );
8577 Debug.Assert( pBt.pPage1 != null );
8578 pP1 = pBt.pPage1.aData;
8579 rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
8580 if ( rc == SQLITE_OK )
8581 {
8582 sqlite3Put4byte( pP1, 36 + idx * 4, iMeta );
8583 #if !SQLITE_OMIT_AUTOVACUUM
8584 if ( idx == BTREE_INCR_VACUUM )
8585 {
8586 Debug.Assert( pBt.autoVacuum || iMeta == 0 );
8587 Debug.Assert( iMeta == 0 || iMeta == 1 );
8588 pBt.incrVacuum = iMeta != 0;
8589 }
8590 #endif
8591 }
8592 sqlite3BtreeLeave( p );
8593 return rc;
8594 }
8595  
8596 #if !SQLITE_OMIT_BTREECOUNT
8597 /*
8598 ** The first argument, pCur, is a cursor opened on some b-tree. Count the
8599 ** number of entries in the b-tree and write the result to pnEntry.
8600 **
8601 ** SQLITE_OK is returned if the operation is successfully executed.
8602 ** Otherwise, if an error is encountered (i.e. an IO error or database
8603 ** corruption) an SQLite error code is returned.
8604 */
8605 static int sqlite3BtreeCount( BtCursor pCur, ref i64 pnEntry )
8606 {
8607 i64 nEntry = 0; /* Value to return in pnEntry */
8608 int rc; /* Return code */
8609 rc = moveToRoot( pCur );
8610  
8611 /* Unless an error occurs, the following loop runs one iteration for each
8612 ** page in the B-Tree structure (not including overflow pages).
8613 */
8614 while ( rc == SQLITE_OK )
8615 {
8616 int iIdx; /* Index of child node in parent */
8617 MemPage pPage; /* Current page of the b-tree */
8618  
8619 /* If this is a leaf page or the tree is not an int-key tree, then
8620 ** this page contains countable entries. Increment the entry counter
8621 ** accordingly.
8622 */
8623 pPage = pCur.apPage[pCur.iPage];
8624 if ( pPage.leaf != 0 || 0 == pPage.intKey )
8625 {
8626 nEntry += pPage.nCell;
8627 }
8628  
8629 /* pPage is a leaf node. This loop navigates the cursor so that it
8630 ** points to the first interior cell that it points to the parent of
8631 ** the next page in the tree that has not yet been visited. The
8632 ** pCur.aiIdx[pCur.iPage] value is set to the index of the parent cell
8633 ** of the page, or to the number of cells in the page if the next page
8634 ** to visit is the right-child of its parent.
8635 **
8636 ** If all pages in the tree have been visited, return SQLITE_OK to the
8637 ** caller.
8638 */
8639 if ( pPage.leaf != 0 )
8640 {
8641 do
8642 {
8643 if ( pCur.iPage == 0 )
8644 {
8645 /* All pages of the b-tree have been visited. Return successfully. */
8646 pnEntry = nEntry;
8647 return SQLITE_OK;
8648 }
8649 moveToParent( pCur );
8650 } while ( pCur.aiIdx[pCur.iPage] >= pCur.apPage[pCur.iPage].nCell );
8651  
8652 pCur.aiIdx[pCur.iPage]++;
8653 pPage = pCur.apPage[pCur.iPage];
8654 }
8655  
8656 /* Descend to the child node of the cell that the cursor currently
8657 ** points at. This is the right-child if (iIdx==pPage.nCell).
8658 */
8659 iIdx = pCur.aiIdx[pCur.iPage];
8660 if ( iIdx == pPage.nCell )
8661 {
8662 rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) );
8663 }
8664 else
8665 {
8666 rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, findCell( pPage, iIdx ) ) );
8667 }
8668 }
8669  
8670 /* An error has occurred. Return an error code. */
8671 return rc;
8672 }
8673 #endif
8674  
8675 /*
8676 ** Return the pager associated with a BTree. This routine is used for
8677 ** testing and debugging only.
8678 */
8679 static Pager sqlite3BtreePager( Btree p )
8680 {
8681 return p.pBt.pPager;
8682 }
8683  
8684 #if !SQLITE_OMIT_INTEGRITY_CHECK
8685 /*
8686 ** Append a message to the error message string.
8687 */
8688 static void checkAppendMsg(
8689 IntegrityCk pCheck,
8690 string zMsg1,
8691 string zFormat,
8692 params object[] ap
8693 )
8694 {
8695 if ( 0 == pCheck.mxErr )
8696 return;
8697 //va_list ap;
8698 lock ( lock_va_list )
8699 {
8700 pCheck.mxErr--;
8701 pCheck.nErr++;
8702 va_start( ap, zFormat );
8703 if ( pCheck.errMsg.zText.Length != 0 )
8704 {
8705 sqlite3StrAccumAppend( pCheck.errMsg, "\n", 1 );
8706 }
8707 if ( zMsg1.Length > 0 )
8708 {
8709 sqlite3StrAccumAppend( pCheck.errMsg, zMsg1.ToString(), -1 );
8710 }
8711 sqlite3VXPrintf( pCheck.errMsg, 1, zFormat, ap );
8712 va_end( ref ap );
8713 }
8714 }
8715  
8716 static void checkAppendMsg(
8717 IntegrityCk pCheck,
8718 StringBuilder zMsg1,
8719 string zFormat,
8720 params object[] ap
8721 )
8722 {
8723 if ( 0 == pCheck.mxErr )
8724 return;
8725 //va_list ap;
8726 lock ( lock_va_list )
8727 {
8728 pCheck.mxErr--;
8729 pCheck.nErr++;
8730 va_start( ap, zFormat );
8731 if ( pCheck.errMsg.zText.Length != 0 )
8732 {
8733 sqlite3StrAccumAppend( pCheck.errMsg, "\n", 1 );
8734 }
8735 if ( zMsg1.Length > 0 )
8736 {
8737 sqlite3StrAccumAppend( pCheck.errMsg, zMsg1.ToString(), -1 );
8738 }
8739 sqlite3VXPrintf( pCheck.errMsg, 1, zFormat, ap );
8740 va_end( ref ap );
8741 }
8742 //if( pCheck.errMsg.mallocFailed ){
8743 // pCheck.mallocFailed = 1;
8744 //}
8745 }
8746 #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
8747  
8748 #if !SQLITE_OMIT_INTEGRITY_CHECK
8749 /*
8750 ** Add 1 to the reference count for page iPage. If this is the second
8751 ** reference to the page, add an error message to pCheck.zErrMsg.
8752 ** Return 1 if there are 2 ore more references to the page and 0 if
8753 ** if this is the first reference to the page.
8754 **
8755 ** Also check that the page number is in bounds.
8756 */
8757 static int checkRef( IntegrityCk pCheck, Pgno iPage, string zContext )
8758 {
8759 if ( iPage == 0 )
8760 return 1;
8761 if ( iPage > pCheck.nPage )
8762 {
8763 checkAppendMsg( pCheck, zContext, "invalid page number %d", iPage );
8764 return 1;
8765 }
8766 if ( pCheck.anRef[iPage] == 1 )
8767 {
8768 checkAppendMsg( pCheck, zContext, "2nd reference to page %d", iPage );
8769 return 1;
8770 }
8771 return ( ( pCheck.anRef[iPage]++ ) > 1 ) ? 1 : 0;
8772 }
8773  
8774 #if !SQLITE_OMIT_AUTOVACUUM
8775 /*
8776 ** Check that the entry in the pointer-map for page iChild maps to
8777 ** page iParent, pointer type ptrType. If not, append an error message
8778 ** to pCheck.
8779 */
8780 static void checkPtrmap(
8781 IntegrityCk pCheck, /* Integrity check context */
8782 Pgno iChild, /* Child page number */
8783 u8 eType, /* Expected pointer map type */
8784 Pgno iParent, /* Expected pointer map parent page number */
8785 string zContext /* Context description (used for error msg) */
8786 )
8787 {
8788 int rc;
8789 u8 ePtrmapType = 0;
8790 Pgno iPtrmapParent = 0;
8791  
8792 rc = ptrmapGet( pCheck.pBt, iChild, ref ePtrmapType, ref iPtrmapParent );
8793 if ( rc != SQLITE_OK )
8794 {
8795 //if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck.mallocFailed = 1;
8796 checkAppendMsg( pCheck, zContext, "Failed to read ptrmap key=%d", iChild );
8797 return;
8798 }
8799  
8800 if ( ePtrmapType != eType || iPtrmapParent != iParent )
8801 {
8802 checkAppendMsg( pCheck, zContext,
8803 "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
8804 iChild, eType, iParent, ePtrmapType, iPtrmapParent );
8805 }
8806 }
8807 #endif
8808  
8809 /*
8810 ** Check the integrity of the freelist or of an overflow page list.
8811 ** Verify that the number of pages on the list is N.
8812 */
8813 static void checkList(
8814 IntegrityCk pCheck, /* Integrity checking context */
8815 int isFreeList, /* True for a freelist. False for overflow page list */
8816 int iPage, /* Page number for first page in the list */
8817 int N, /* Expected number of pages in the list */
8818 string zContext /* Context for error messages */
8819 )
8820 {
8821 int i;
8822 int expected = N;
8823 int iFirst = iPage;
8824 while ( N-- > 0 && pCheck.mxErr != 0 )
8825 {
8826 PgHdr pOvflPage = new PgHdr();
8827 byte[] pOvflData;
8828 if ( iPage < 1 )
8829 {
8830 checkAppendMsg( pCheck, zContext,
8831 "%d of %d pages missing from overflow list starting at %d",
8832 N + 1, expected, iFirst );
8833 break;
8834 }
8835 if ( checkRef( pCheck, (u32)iPage, zContext ) != 0 )
8836 break;
8837 if ( sqlite3PagerGet( pCheck.pPager, (Pgno)iPage, ref pOvflPage ) != 0 )
8838 {
8839 checkAppendMsg( pCheck, zContext, "failed to get page %d", iPage );
8840 break;
8841 }
8842 pOvflData = sqlite3PagerGetData( pOvflPage );
8843 if ( isFreeList != 0 )
8844 {
8845 int n = (int)sqlite3Get4byte( pOvflData, 4 );
8846 #if !SQLITE_OMIT_AUTOVACUUM
8847 if ( pCheck.pBt.autoVacuum )
8848 {
8849 checkPtrmap( pCheck, (u32)iPage, PTRMAP_FREEPAGE, 0, zContext );
8850 }
8851 #endif
8852 if ( n > (int)pCheck.pBt.usableSize / 4 - 2 )
8853 {
8854 checkAppendMsg( pCheck, zContext,
8855 "freelist leaf count too big on page %d", iPage );
8856 N--;
8857 }
8858 else
8859 {
8860 for ( i = 0; i < n; i++ )
8861 {
8862 Pgno iFreePage = sqlite3Get4byte( pOvflData, 8 + i * 4 );
8863 #if !SQLITE_OMIT_AUTOVACUUM
8864 if ( pCheck.pBt.autoVacuum )
8865 {
8866 checkPtrmap( pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext );
8867 }
8868 #endif
8869 checkRef( pCheck, iFreePage, zContext );
8870 }
8871 N -= n;
8872 }
8873 }
8874 #if !SQLITE_OMIT_AUTOVACUUM
8875 else
8876 {
8877 /* If this database supports auto-vacuum and iPage is not the last
8878 ** page in this overflow list, check that the pointer-map entry for
8879 ** the following page matches iPage.
8880 */
8881 if ( pCheck.pBt.autoVacuum && N > 0 )
8882 {
8883 i = (int)sqlite3Get4byte( pOvflData );
8884 checkPtrmap( pCheck, (u32)i, PTRMAP_OVERFLOW2, (u32)iPage, zContext );
8885 }
8886 }
8887 #endif
8888 iPage = (int)sqlite3Get4byte( pOvflData );
8889 sqlite3PagerUnref( pOvflPage );
8890 }
8891 }
8892 #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
8893  
8894 #if !SQLITE_OMIT_INTEGRITY_CHECK
8895 /*
8896 ** Do various sanity checks on a single page of a tree. Return
8897 ** the tree depth. Root pages return 0. Parents of root pages
8898 ** return 1, and so forth.
8899 **
8900 ** These checks are done:
8901 **
8902 ** 1. Make sure that cells and freeblocks do not overlap
8903 ** but combine to completely cover the page.
8904 ** NO 2. Make sure cell keys are in order.
8905 ** NO 3. Make sure no key is less than or equal to zLowerBound.
8906 ** NO 4. Make sure no key is greater than or equal to zUpperBound.
8907 ** 5. Check the integrity of overflow pages.
8908 ** 6. Recursively call checkTreePage on all children.
8909 ** 7. Verify that the depth of all children is the same.
8910 ** 8. Make sure this page is at least 33% full or else it is
8911 ** the root of the tree.
8912 */
8913  
8914 static i64 refNULL = 0; //Dummy for C# ref NULL
8915  
8916 static int checkTreePage(
8917 IntegrityCk pCheck, /* Context for the sanity check */
8918 int iPage, /* Page number of the page to check */
8919 string zParentContext, /* Parent context */
8920 ref i64 pnParentMinKey,
8921 ref i64 pnParentMaxKey,
8922 object _pnParentMinKey, /* C# Needed to determine if content passed*/
8923 object _pnParentMaxKey /* C# Needed to determine if content passed*/
8924 )
8925 {
8926 MemPage pPage = new MemPage();
8927 int i, rc, depth, d2, pgno, cnt;
8928 int hdr, cellStart;
8929 int nCell;
8930 u8[] data;
8931 BtShared pBt;
8932 int usableSize;
8933 StringBuilder zContext = new StringBuilder( 100 );
8934 byte[] hit = null;
8935 i64 nMinKey = 0;
8936 i64 nMaxKey = 0;
8937  
8938  
8939 sqlite3_snprintf( 200, zContext, "Page %d: ", iPage );
8940  
8941 /* Check that the page exists
8942 */
8943 pBt = pCheck.pBt;
8944 usableSize = (int)pBt.usableSize;
8945 if ( iPage == 0 )
8946 return 0;
8947 if ( checkRef( pCheck, (u32)iPage, zParentContext ) != 0 )
8948 return 0;
8949 if ( ( rc = btreeGetPage( pBt, (Pgno)iPage, ref pPage, 0 ) ) != 0 )
8950 {
8951 checkAppendMsg( pCheck, zContext.ToString(),
8952 "unable to get the page. error code=%d", rc );
8953 return 0;
8954 }
8955  
8956 /* Clear MemPage.isInit to make sure the corruption detection code in
8957 ** btreeInitPage() is executed. */
8958 pPage.isInit = 0;
8959 if ( ( rc = btreeInitPage( pPage ) ) != 0 )
8960 {
8961 Debug.Assert( rc == SQLITE_CORRUPT ); /* The only possible error from InitPage */
8962 checkAppendMsg( pCheck, zContext.ToString(),
8963 "btreeInitPage() returns error code %d", rc );
8964 releasePage( pPage );
8965 return 0;
8966 }
8967  
8968 /* Check out all the cells.
8969 */
8970 depth = 0;
8971 for ( i = 0; i < pPage.nCell && pCheck.mxErr != 0; i++ )
8972 {
8973 u8[] pCell;
8974 u32 sz;
8975 CellInfo info = new CellInfo();
8976  
8977 /* Check payload overflow pages
8978 */
8979 sqlite3_snprintf( 200, zContext,
8980 "On tree page %d cell %d: ", iPage, i );
8981 int iCell = findCell( pPage, i ); //pCell = findCell( pPage, i );
8982 pCell = pPage.aData;
8983 btreeParseCellPtr( pPage, iCell, ref info ); //btreeParseCellPtr( pPage, pCell, info );
8984 sz = info.nData;
8985 if ( 0 == pPage.intKey )
8986 sz += (u32)info.nKey;
8987 /* For intKey pages, check that the keys are in order.
8988 */
8989 else if ( i == 0 )
8990 nMinKey = nMaxKey = info.nKey;
8991 else
8992 {
8993 if ( info.nKey <= nMaxKey )
8994 {
8995 checkAppendMsg( pCheck, zContext.ToString(),
8996 "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey );
8997 }
8998 nMaxKey = info.nKey;
8999 }
9000 Debug.Assert( sz == info.nPayload );
9001 if ( ( sz > info.nLocal )
9002 //&& (pCell[info.iOverflow]<=&pPage.aData[pBt.usableSize])
9003 )
9004 {
9005 int nPage = (int)( sz - info.nLocal + usableSize - 5 ) / ( usableSize - 4 );
9006 Pgno pgnoOvfl = sqlite3Get4byte( pCell, iCell, info.iOverflow );
9007 #if !SQLITE_OMIT_AUTOVACUUM
9008 if ( pBt.autoVacuum )
9009 {
9010 checkPtrmap( pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, (u32)iPage, zContext.ToString() );
9011 }
9012 #endif
9013 checkList( pCheck, 0, (int)pgnoOvfl, nPage, zContext.ToString() );
9014 }
9015  
9016 /* Check sanity of left child page.
9017 */
9018 if ( 0 == pPage.leaf )
9019 {
9020 pgno = (int)sqlite3Get4byte( pCell, iCell ); //sqlite3Get4byte( pCell );
9021 #if !SQLITE_OMIT_AUTOVACUUM
9022 if ( pBt.autoVacuum )
9023 {
9024 checkPtrmap( pCheck, (u32)pgno, PTRMAP_BTREE, (u32)iPage, zContext.ToString() );
9025 }
9026 #endif
9027 if ( i == 0 )
9028 d2 = checkTreePage( pCheck, pgno, zContext.ToString(), ref nMinKey, ref refNULL, pCheck, null );
9029 else
9030 d2 = checkTreePage( pCheck, pgno, zContext.ToString(), ref nMinKey, ref nMaxKey, pCheck, pCheck );
9031  
9032 if ( i > 0 && d2 != depth )
9033 {
9034 checkAppendMsg( pCheck, zContext, "Child page depth differs" );
9035 }
9036 depth = d2;
9037 }
9038 }
9039 if ( 0 == pPage.leaf )
9040 {
9041 pgno = (int)sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
9042 sqlite3_snprintf( 200, zContext,
9043 "On page %d at right child: ", iPage );
9044 #if !SQLITE_OMIT_AUTOVACUUM
9045 if ( pBt.autoVacuum )
9046 {
9047 checkPtrmap( pCheck, (u32)pgno, PTRMAP_BTREE, (u32)iPage, zContext.ToString() );
9048 }
9049 #endif
9050 // checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
9051 if ( 0 == pPage.nCell )
9052 checkTreePage( pCheck, pgno, zContext.ToString(), ref refNULL, ref refNULL, null, null );
9053 else
9054 checkTreePage( pCheck, pgno, zContext.ToString(), ref refNULL, ref nMaxKey, null, pCheck );
9055 }
9056  
9057 /* For intKey leaf pages, check that the min/max keys are in order
9058 ** with any left/parent/right pages.
9059 */
9060 if ( pPage.leaf != 0 && pPage.intKey != 0 )
9061 {
9062 /* if we are a left child page */
9063 if ( _pnParentMinKey != null )
9064 {
9065 /* if we are the left most child page */
9066 if ( _pnParentMaxKey == null )
9067 {
9068 if ( nMaxKey > pnParentMinKey )
9069 {
9070 checkAppendMsg( pCheck, zContext,
9071 "Rowid %lld out of order (max larger than parent min of %lld)",
9072 nMaxKey, pnParentMinKey );
9073 }
9074 }
9075 else
9076 {
9077 if ( nMinKey <= pnParentMinKey )
9078 {
9079 checkAppendMsg( pCheck, zContext,
9080 "Rowid %lld out of order (min less than parent min of %lld)",
9081 nMinKey, pnParentMinKey );
9082 }
9083 if ( nMaxKey > pnParentMaxKey )
9084 {
9085 checkAppendMsg( pCheck, zContext,
9086 "Rowid %lld out of order (max larger than parent max of %lld)",
9087 nMaxKey, pnParentMaxKey );
9088 }
9089 pnParentMinKey = nMaxKey;
9090 }
9091 /* else if we're a right child page */
9092 }
9093 else if ( _pnParentMaxKey != null )
9094 {
9095 if ( nMinKey <= pnParentMaxKey )
9096 {
9097 checkAppendMsg( pCheck, zContext,
9098 "Rowid %lld out of order (min less than parent max of %lld)",
9099 nMinKey, pnParentMaxKey );
9100 }
9101 }
9102 }
9103  
9104 /* Check for complete coverage of the page
9105 */
9106 data = pPage.aData;
9107 hdr = pPage.hdrOffset;
9108 hit = sqlite3Malloc( pBt.pageSize );
9109 //if( hit==null ){
9110 // pCheck.mallocFailed = 1;
9111 //}else
9112 {
9113 int contentOffset = get2byteNotZero( data, hdr + 5 );
9114 Debug.Assert( contentOffset <= usableSize ); /* Enforced by btreeInitPage() */
9115 Array.Clear( hit, contentOffset, usableSize - contentOffset );//memset(hit+contentOffset, 0, usableSize-contentOffset);
9116 for ( int iLoop = contentOffset - 1; iLoop >= 0; iLoop-- )
9117 hit[iLoop] = 1;//memset(hit, 1, contentOffset);
9118 nCell = get2byte( data, hdr + 3 );
9119 cellStart = hdr + 12 - 4 * pPage.leaf;
9120 for ( i = 0; i < nCell; i++ )
9121 {
9122 int pc = get2byte( data, cellStart + i * 2 );
9123 u32 size = 65536;
9124 int j;
9125 if ( pc <= usableSize - 4 )
9126 {
9127 size = cellSizePtr( pPage, data, pc );
9128 }
9129 if ( (int)( pc + size - 1 ) >= usableSize )
9130 {
9131 checkAppendMsg( pCheck, string.Empty,
9132 "Corruption detected in cell %d on page %d", i, iPage );
9133 }
9134 else
9135 {
9136 for ( j = (int)( pc + size - 1 ); j >= pc; j-- )
9137 hit[j]++;
9138 }
9139 }
9140 i = get2byte( data, hdr + 1 );
9141 while ( i > 0 )
9142 {
9143 int size, j;
9144 Debug.Assert( i <= usableSize - 4 ); /* Enforced by btreeInitPage() */
9145 size = get2byte( data, i + 2 );
9146 Debug.Assert( i + size <= usableSize ); /* Enforced by btreeInitPage() */
9147 for ( j = i + size - 1; j >= i; j-- )
9148 hit[j]++;
9149 j = get2byte( data, i );
9150 Debug.Assert( j == 0 || j > i + size ); /* Enforced by btreeInitPage() */
9151 Debug.Assert( j <= usableSize - 4 ); /* Enforced by btreeInitPage() */
9152 i = j;
9153 }
9154 for ( i = cnt = 0; i < usableSize; i++ )
9155 {
9156 if ( hit[i] == 0 )
9157 {
9158 cnt++;
9159 }
9160 else if ( hit[i] > 1 )
9161 {
9162 checkAppendMsg( pCheck, string.Empty,
9163 "Multiple uses for byte %d of page %d", i, iPage );
9164 break;
9165 }
9166 }
9167 if ( cnt != data[hdr + 7] )
9168 {
9169 checkAppendMsg( pCheck, string.Empty,
9170 "Fragmentation of %d bytes reported as %d on page %d",
9171 cnt, data[hdr + 7], iPage );
9172 }
9173 }
9174 sqlite3PageFree( ref hit );
9175 releasePage( pPage );
9176 return depth + 1;
9177 }
9178 #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
9179  
9180 #if !SQLITE_OMIT_INTEGRITY_CHECK
9181 /*
9182 ** This routine does a complete check of the given BTree file. aRoot[] is
9183 ** an array of pages numbers were each page number is the root page of
9184 ** a table. nRoot is the number of entries in aRoot.
9185 **
9186 ** A read-only or read-write transaction must be opened before calling
9187 ** this function.
9188 **
9189 ** Write the number of error seen in pnErr. Except for some memory
9190 ** allocation errors, an error message held in memory obtained from
9191 ** malloc is returned if pnErr is non-zero. If pnErr==null then NULL is
9192 ** returned. If a memory allocation error occurs, NULL is returned.
9193 */
9194 static string sqlite3BtreeIntegrityCheck(
9195 Btree p, /* The btree to be checked */
9196 int[] aRoot, /* An array of root pages numbers for individual trees */
9197 int nRoot, /* Number of entries in aRoot[] */
9198 int mxErr, /* Stop reporting errors after this many */
9199 ref int pnErr /* Write number of errors seen to this variable */
9200 )
9201 {
9202 Pgno i;
9203 int nRef;
9204 IntegrityCk sCheck = new IntegrityCk();
9205 BtShared pBt = p.pBt;
9206  
9207 sqlite3BtreeEnter( p );
9208 Debug.Assert( p.inTrans > TRANS_NONE && pBt.inTransaction > TRANS_NONE );
9209 nRef = sqlite3PagerRefcount( pBt.pPager );
9210 sCheck.pBt = pBt;
9211 sCheck.pPager = pBt.pPager;
9212 sCheck.nPage = btreePagecount( sCheck.pBt );
9213 sCheck.mxErr = mxErr;
9214 sCheck.nErr = 0;
9215 //sCheck.mallocFailed = 0;
9216 pnErr = 0;
9217 if ( sCheck.nPage == 0 )
9218 {
9219 sqlite3BtreeLeave( p );
9220 return string.Empty;
9221 }
9222 sCheck.anRef = sqlite3Malloc( sCheck.anRef, (int)sCheck.nPage + 1 );
9223 //if( !sCheck.anRef ){
9224 // pnErr = 1;
9225 // sqlite3BtreeLeave(p);
9226 // return 0;
9227 //}
9228 // for (i = 0; i <= sCheck.nPage; i++) { sCheck.anRef[i] = 0; }
9229 i = PENDING_BYTE_PAGE( pBt );
9230 if ( i <= sCheck.nPage )
9231 {
9232 sCheck.anRef[i] = 1;
9233 }
9234 sqlite3StrAccumInit( sCheck.errMsg, null, 1000, 20000 );
9235 //sCheck.errMsg.useMalloc = 2;
9236  
9237 /* Check the integrity of the freelist
9238 */
9239 checkList( sCheck, 1, (int)sqlite3Get4byte( pBt.pPage1.aData, 32 ),
9240 (int)sqlite3Get4byte( pBt.pPage1.aData, 36 ), "Main freelist: " );
9241  
9242 /* Check all the tables.
9243 */
9244 for ( i = 0; (int)i < nRoot && sCheck.mxErr != 0; i++ )
9245 {
9246 if ( aRoot[i] == 0 )
9247 continue;
9248 #if !SQLITE_OMIT_AUTOVACUUM
9249 if ( pBt.autoVacuum && aRoot[i] > 1 )
9250 {
9251 checkPtrmap( sCheck, (u32)aRoot[i], PTRMAP_ROOTPAGE, 0, string.Empty );
9252 }
9253 #endif
9254 checkTreePage( sCheck, aRoot[i], "List of tree roots: ", ref refNULL, ref refNULL, null, null );
9255 }
9256  
9257 /* Make sure every page in the file is referenced
9258 */
9259 for ( i = 1; i <= sCheck.nPage && sCheck.mxErr != 0; i++ )
9260 {
9261 #if SQLITE_OMIT_AUTOVACUUM
9262 if( sCheck.anRef[i]==null ){
9263 checkAppendMsg(sCheck, 0, "Page %d is never used", i);
9264 }
9265 #else
9266 /* If the database supports auto-vacuum, make sure no tables contain
9267 ** references to pointer-map pages.
9268 */
9269 if ( sCheck.anRef[i] == 0 &&
9270 ( PTRMAP_PAGENO( pBt, i ) != i || !pBt.autoVacuum ) )
9271 {
9272 checkAppendMsg( sCheck, string.Empty, "Page %d is never used", i );
9273 }
9274 if ( sCheck.anRef[i] != 0 &&
9275 ( PTRMAP_PAGENO( pBt, i ) == i && pBt.autoVacuum ) )
9276 {
9277 checkAppendMsg( sCheck, string.Empty, "Pointer map page %d is referenced", i );
9278 }
9279 #endif
9280 }
9281  
9282 /* Make sure this analysis did not leave any unref() pages.
9283 ** This is an internal consistency check; an integrity check
9284 ** of the integrity check.
9285 */
9286 if ( NEVER( nRef != sqlite3PagerRefcount( pBt.pPager ) ) )
9287 {
9288 checkAppendMsg( sCheck, string.Empty,
9289 "Outstanding page count goes from %d to %d during this analysis",
9290 nRef, sqlite3PagerRefcount( pBt.pPager )
9291 );
9292 }
9293  
9294 /* Clean up and report errors.
9295 */
9296 sqlite3BtreeLeave( p );
9297 sCheck.anRef = null;// sqlite3_free( ref sCheck.anRef );
9298 //if( sCheck.mallocFailed ){
9299 // sqlite3StrAccumReset(sCheck.errMsg);
9300 // pnErr = sCheck.nErr+1;
9301 // return 0;
9302 //}
9303 pnErr = sCheck.nErr;
9304 if ( sCheck.nErr == 0 )
9305 sqlite3StrAccumReset( sCheck.errMsg );
9306 return sqlite3StrAccumFinish( sCheck.errMsg );
9307 }
9308 #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
9309  
9310 /*
9311 ** Return the full pathname of the underlying database file.
9312 **
9313 ** The pager filename is invariant as long as the pager is
9314 ** open so it is safe to access without the BtShared mutex.
9315 */
9316 static string sqlite3BtreeGetFilename( Btree p )
9317 {
9318 Debug.Assert( p.pBt.pPager != null );
9319 return sqlite3PagerFilename( p.pBt.pPager );
9320 }
9321  
9322 /*
9323 ** Return the pathname of the journal file for this database. The return
9324 ** value of this routine is the same regardless of whether the journal file
9325 ** has been created or not.
9326 **
9327 ** The pager journal filename is invariant as long as the pager is
9328 ** open so it is safe to access without the BtShared mutex.
9329 */
9330 static string sqlite3BtreeGetJournalname( Btree p )
9331 {
9332 Debug.Assert( p.pBt.pPager != null );
9333 return sqlite3PagerJournalname( p.pBt.pPager );
9334 }
9335  
9336 /*
9337 ** Return non-zero if a transaction is active.
9338 */
9339 static bool sqlite3BtreeIsInTrans( Btree p )
9340 {
9341 Debug.Assert( p == null || sqlite3_mutex_held( p.db.mutex ) );
9342 return ( p != null && ( p.inTrans == TRANS_WRITE ) );
9343 }
9344  
9345 #if !SQLITE_OMIT_WAL
9346 /*
9347 ** Run a checkpoint on the Btree passed as the first argument.
9348 **
9349 ** Return SQLITE_LOCKED if this or any other connection has an open
9350 ** transaction on the shared-cache the argument Btree is connected to.
9351 **
9352 ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
9353 */
9354 static int sqlite3BtreeCheckpointBtree *p, int eMode, int *pnLog, int *pnCkpt){
9355 int rc = SQLITE_OK;
9356 if( p != null){
9357 BtShared pBt = p.pBt;
9358 sqlite3BtreeEnter(p);
9359 if( pBt.inTransaction!=TRANS_NONE ){
9360 rc = SQLITE_LOCKED;
9361 }else{
9362 rc = sqlite3PagerCheckpoint(pBt.pPager, eMode, pnLog, pnCkpt);
9363 }
9364 sqlite3BtreeLeave(p);
9365 }
9366 return rc;
9367 }
9368 #endif
9369  
9370 /*
9371 ** Return non-zero if a read (or write) transaction is active.
9372 */
9373 static bool sqlite3BtreeIsInReadTrans( Btree p )
9374 {
9375 Debug.Assert( p != null );
9376 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
9377 return p.inTrans != TRANS_NONE;
9378 }
9379  
9380 static bool sqlite3BtreeIsInBackup( Btree p )
9381 {
9382 Debug.Assert( p != null );
9383 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
9384 return p.nBackup != 0;
9385 }
9386  
9387 /*
9388 ** This function returns a pointer to a blob of memory associated with
9389 ** a single shared-btree. The memory is used by client code for its own
9390 ** purposes (for example, to store a high-level schema associated with
9391 ** the shared-btree). The btree layer manages reference counting issues.
9392 **
9393 ** The first time this is called on a shared-btree, nBytes bytes of memory
9394 ** are allocated, zeroed, and returned to the caller. For each subsequent
9395 ** call the nBytes parameter is ignored and a pointer to the same blob
9396 ** of memory returned.
9397 **
9398 ** If the nBytes parameter is 0 and the blob of memory has not yet been
9399 ** allocated, a null pointer is returned. If the blob has already been
9400 ** allocated, it is returned as normal.
9401 **
9402 ** Just before the shared-btree is closed, the function passed as the
9403 ** xFree argument when the memory allocation was made is invoked on the
9404 ** blob of allocated memory. The xFree function should not call sqlite3_free()
9405 ** on the memory, the btree layer does that.
9406 */
9407 static Schema sqlite3BtreeSchema( Btree p, int nBytes, dxFreeSchema xFree )
9408 {
9409 BtShared pBt = p.pBt;
9410 sqlite3BtreeEnter( p );
9411 if ( null == pBt.pSchema && nBytes != 0 )
9412 {
9413 pBt.pSchema = new Schema();//sqlite3DbMallocZero(0, nBytes);
9414 pBt.xFreeSchema = xFree;
9415 }
9416 sqlite3BtreeLeave( p );
9417 return pBt.pSchema;
9418 }
9419  
9420 /*
9421 ** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
9422 ** btree as the argument handle holds an exclusive lock on the
9423 ** sqlite_master table. Otherwise SQLITE_OK.
9424 */
9425 static int sqlite3BtreeSchemaLocked( Btree p )
9426 {
9427 int rc;
9428 Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
9429 sqlite3BtreeEnter( p );
9430 rc = querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK );
9431 Debug.Assert( rc == SQLITE_OK || rc == SQLITE_LOCKED_SHAREDCACHE );
9432 sqlite3BtreeLeave( p );
9433 return rc;
9434 }
9435  
9436  
9437 #if !SQLITE_OMIT_SHARED_CACHE
9438 /*
9439 ** Obtain a lock on the table whose root page is iTab. The
9440 ** lock is a write lock if isWritelock is true or a read lock
9441 ** if it is false.
9442 */
9443 int sqlite3BtreeLockTable(Btree p, int iTab, u8 isWriteLock){
9444 int rc = SQLITE_OK;
9445 Debug.Assert( p.inTrans!=TRANS_NONE );
9446 if( p.sharable ){
9447 u8 lockType = READ_LOCK + isWriteLock;
9448 Debug.Assert( READ_LOCK+1==WRITE_LOCK );
9449 Debug.Assert( isWriteLock==null || isWriteLock==1 );
9450  
9451 sqlite3BtreeEnter(p);
9452 rc = querySharedCacheTableLock(p, iTab, lockType);
9453 if( rc==SQLITE_OK ){
9454 rc = setSharedCacheTableLock(p, iTab, lockType);
9455 }
9456 sqlite3BtreeLeave(p);
9457 }
9458 return rc;
9459 }
9460 #endif
9461  
9462 #if !SQLITE_OMIT_INCRBLOB
9463 /*
9464 ** Argument pCsr must be a cursor opened for writing on an
9465 ** INTKEY table currently pointing at a valid table entry.
9466 ** This function modifies the data stored as part of that entry.
9467 **
9468 ** Only the data content may only be modified, it is not possible to
9469 ** change the length of the data stored. If this function is called with
9470 ** parameters that attempt to write past the end of the existing data,
9471 ** no modifications are made and SQLITE_CORRUPT is returned.
9472 */
9473 int sqlite3BtreePutData(BtCursor pCsr, u32 offset, u32 amt, void *z){
9474 int rc;
9475 Debug.Assert( cursorHoldsMutex(pCsr) );
9476 Debug.Assert( sqlite3_mutex_held(pCsr.pBtree.db.mutex) );
9477 Debug.Assert( pCsr.isIncrblobHandle );
9478  
9479 rc = restoreCursorPosition(pCsr);
9480 if( rc!=SQLITE_OK ){
9481 return rc;
9482 }
9483 Debug.Assert( pCsr.eState!=CURSOR_REQUIRESEEK );
9484 if( pCsr.eState!=CURSOR_VALID ){
9485 return SQLITE_ABORT;
9486 }
9487  
9488 /* Check some assumptions:
9489 ** (a) the cursor is open for writing,
9490 ** (b) there is a read/write transaction open,
9491 ** (c) the connection holds a write-lock on the table (if required),
9492 ** (d) there are no conflicting read-locks, and
9493 ** (e) the cursor points at a valid row of an intKey table.
9494 */
9495 if( !pCsr.wrFlag ){
9496 return SQLITE_READONLY;
9497 }
9498 Debug.Assert( !pCsr.pBt.readOnly && pCsr.pBt.inTransaction==TRANS_WRITE );
9499 Debug.Assert( hasSharedCacheTableLock(pCsr.pBtree, pCsr.pgnoRoot, 0, 2) );
9500 Debug.Assert( !hasReadConflicts(pCsr.pBtree, pCsr.pgnoRoot) );
9501 Debug.Assert( pCsr.apPage[pCsr.iPage].intKey );
9502  
9503 return accessPayload(pCsr, offset, amt, (byte[] *)z, 1);
9504 }
9505  
9506 /*
9507 ** Set a flag on this cursor to cache the locations of pages from the
9508 ** overflow list for the current row. This is used by cursors opened
9509 ** for incremental blob IO only.
9510 **
9511 ** This function sets a flag only. The actual page location cache
9512 ** (stored in BtCursor.aOverflow[]) is allocated and used by function
9513 ** accessPayload() (the worker function for sqlite3BtreeData() and
9514 ** sqlite3BtreePutData()).
9515 */
9516 static void sqlite3BtreeCacheOverflow(BtCursor pCur){
9517 Debug.Assert( cursorHoldsMutex(pCur) );
9518 Debug.Assert( sqlite3_mutex_held(pCur.pBtree.db.mutex) );
9519 invalidateOverflowCache(pCur)
9520 pCur.isIncrblobHandle = 1;
9521 }
9522 #endif
9523  
9524 /*
9525 ** Set both the "read version" (single byte at byte offset 18) and
9526 ** "write version" (single byte at byte offset 19) fields in the database
9527 ** header to iVersion.
9528 */
9529 static int sqlite3BtreeSetVersion( Btree pBtree, int iVersion )
9530 {
9531 BtShared pBt = pBtree.pBt;
9532 int rc; /* Return code */
9533  
9534 Debug.Assert( pBtree.inTrans == TRANS_NONE );
9535 Debug.Assert( iVersion == 1 || iVersion == 2 );
9536  
9537 /* If setting the version fields to 1, do not automatically open the
9538 ** WAL connection, even if the version fields are currently set to 2.
9539 */
9540 pBt.doNotUseWAL = iVersion == 1;
9541  
9542 rc = sqlite3BtreeBeginTrans( pBtree, 0 );
9543 if ( rc == SQLITE_OK )
9544 {
9545 u8[] aData = pBt.pPage1.aData;
9546 if ( aData[18] != (u8)iVersion || aData[19] != (u8)iVersion )
9547 {
9548 rc = sqlite3BtreeBeginTrans( pBtree, 2 );
9549 if ( rc == SQLITE_OK )
9550 {
9551 rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
9552 if ( rc == SQLITE_OK )
9553 {
9554 aData[18] = (u8)iVersion;
9555 aData[19] = (u8)iVersion;
9556 }
9557 }
9558 }
9559 }
9560  
9561 pBt.doNotUseWAL = false;
9562 return rc;
9563 }
9564 }
9565 }