wasCSharpSQLite – Blame information for rev 4

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System.Diagnostics;
2 using System.Text;
3  
4 namespace Community.CsharpSqlite
5 {
6 using sqlite3_int64 = System.Int64;
7 using i64 = System.Int64;
8 using sqlite3_uint64 = System.UInt64;
9 using u32 = System.UInt32;
10 using System;
11  
12 public partial class Sqlite3
13 {
14 /*
15 ** 2001 September 15
16 **
17 ** The author disclaims copyright to this source code. In place of
18 ** a legal notice, here is a blessing:
19 **
20 ** May you do good and not evil.
21 ** May you find forgiveness for yourself and forgive others.
22 ** May you share freely, never taking more than you give.
23 **
24 *************************************************************************
25 **
26 ** Memory allocation functions used throughout sqlite.
27 *************************************************************************
28 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
29 ** C#-SQLite is an independent reimplementation of the SQLite software library
30 **
31 ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
32 **
33 *************************************************************************
34 */
35 //#include "sqliteInt.h"
36 //#include <stdarg.h>
37  
38 /*
39 ** Attempt to release up to n bytes of non-essential memory currently
40 ** held by SQLite. An example of non-essential memory is memory used to
41 ** cache database pages that are not currently in use.
42 */
43 static int sqlite3_release_memory( int n )
44 {
45 #if SQLITE_ENABLE_MEMORY_MANAGEMENT
46 int nRet = 0;
47 nRet += sqlite3PcacheReleaseMemory(n-nRet);
48 return nRet;
49 #else
50 UNUSED_PARAMETER( n );
51 return SQLITE_OK;
52 #endif
53 }
54  
55 /*
56 ** State information local to the memory allocation subsystem.
57 */
58 //static SQLITE_WSD struct Mem0Global {
59 public class Mem0Global
60 {/* Number of free pages for scratch and page-cache memory */
61 public int nScratchFree;
62 public int nPageFree;
63  
64 public sqlite3_mutex mutex; /* Mutex to serialize access */
65  
66 /*
67 ** The alarm callback and its arguments. The mem0.mutex lock will
68 ** be held while the callback is running. Recursive calls into
69 ** the memory subsystem are allowed, but no new callbacks will be
70 ** issued.
71 */
72 public sqlite3_int64 alarmThreshold;
73 public dxalarmCallback alarmCallback; // (*alarmCallback)(void*, sqlite3_int64,int);
74 public object alarmArg;
75  
76 /*
77 ** Pointers to the end of sqlite3GlobalConfig.pScratch and
78 ** sqlite3GlobalConfig.pPage to a block of memory that records
79 ** which pages are available.
80 */
81 //u32 *aScratchFree;
82 /*
83 ** True if heap is nearly "full" where "full" is defined by the
84 ** sqlite3_soft_heap_limit() setting.
85 */
86 public bool nearlyFull;
87  
88 public byte[][][] aByte;
89 public int[] aByteSize;
90 public int[] aByte_used;
91 public int[][] aInt;
92 public Mem[] aMem;
93 public BtCursor[] aBtCursor;
94  
95 public struct memstat
96 {
97 public int alloc; // # of allocation requests
98 public int dealloc; // # of deallocations
99 public int cached; // # of cache hits
100 public int next; // # Next slot to use
101 public int max; // # Max slot used
102 }
103  
104 public memstat msByte;
105 public memstat msInt;
106 public memstat msMem;
107 public memstat msBtCursor;
108  
109 public Mem0Global()
110 {
111 }
112  
113 public Mem0Global( int nScratchFree, int nPageFree, sqlite3_mutex mutex, sqlite3_int64 alarmThreshold, dxalarmCallback alarmCallback, object alarmArg, int Byte_Allocation, int Int_Allocation, int Mem_Allocation, int BtCursor_Allocation )
114 {
115 this.nScratchFree = nScratchFree;
116 this.nPageFree = nPageFree;
117 this.mutex = mutex;
118 this.alarmThreshold = alarmThreshold;
119 this.alarmCallback = alarmCallback;
120 this.alarmArg = alarmArg;
121 this.msByte.next = -1;
122 this.msInt.next = -1;
123 this.msMem.next = -1;
124 this.aByteSize = new int[] { 32, 256, 1024, 8192, 0 };
125 this.aByte_used = new int[] { -1, -1, -1, -1, -1 };
126 this.aByte = new byte[this.aByteSize.Length][][];
127 for ( int i = 0; i < this.aByteSize.Length; i++ )
128 this.aByte[i] = new byte[Byte_Allocation][];
129 this.aInt = new int[Int_Allocation][];
130 this.aMem = new Mem[Mem_Allocation <= 4 ? 4 : Mem_Allocation];
131 this.aBtCursor = new BtCursor[BtCursor_Allocation <= 4 ? 4 : BtCursor_Allocation];
132 this.nearlyFull = false;
133 }
134 }
135 //mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
136  
137 //#define mem0 GLOBAL(struct Mem0Global, mem0)
138 static Mem0Global mem0 = new Mem0Global();
139  
140 /*
141 ** This routine runs when the memory allocator sees that the
142 ** total memory allocation is about to exceed the soft heap
143 ** limit.
144 */
145 static void softHeapLimitEnforcer(
146 object NotUsed,
147 sqlite3_int64 NotUsed2,
148 int allocSize
149 )
150 {
151 UNUSED_PARAMETER2( NotUsed, NotUsed2 );
152 sqlite3_release_memory( allocSize );
153 }
154  
155 #if !SQLITE_OMIT_DEPRECATED
156 /*
157 ** Deprecated external interface. Internal/core SQLite code
158 ** should call sqlite3MemoryAlarm.
159 */
160 int sqlite3_memory_alarm(
161 void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
162 void *pArg,
163 sqlite3_int64 iThreshold
164 ){
165 return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
166 }
167 #endif
168  
169 /*
170 ** Set the soft heap-size limit for the library. Passing a zero or
171 ** negative value indicates no limit.
172 */
173 static sqlite3_int64 sqlite3_soft_heap_limit64( sqlite3_int64 n )
174 {
175 sqlite3_int64 priorLimit;
176 sqlite3_int64 excess;
177 #if !SQLITE_OMIT_AUTOINIT
178 sqlite3_initialize();
179 #endif
180 sqlite3_mutex_enter( mem0.mutex );
181 priorLimit = mem0.alarmThreshold;
182 sqlite3_mutex_leave( mem0.mutex );
183 if ( n < 0 )
184 return priorLimit;
185 if ( n > 0 )
186 {
187 sqlite3MemoryAlarm( softHeapLimitEnforcer, 0, n );
188 }
189 else
190 {
191 sqlite3MemoryAlarm( null, 0, 0 );
192 }
193 excess = sqlite3_memory_used() - n;
194 if ( excess > 0 )
195 sqlite3_release_memory( (int)( excess & 0x7fffffff ) );
196 return priorLimit;
197 }
198 void sqlite3_soft_heap_limit( int n )
199 {
200 if ( n < 0 )
201 n = 0;
202 sqlite3_soft_heap_limit64( n );
203 }
204  
205 /*
206 ** Initialize the memory allocation subsystem.
207 */
208 static int sqlite3MallocInit()
209 {
210 if ( sqlite3GlobalConfig.m.xMalloc == null )
211 {
212 sqlite3MemSetDefault();
213 }
214 mem0 = new Mem0Global( 0, 0, null, 0, null, null, 1, 1, 8, 8 ); //memset(&mem0, 0, sizeof(mem0));
215 if ( sqlite3GlobalConfig.bCoreMutex )
216 {
217 mem0.mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MEM );
218 }
219 if ( sqlite3GlobalConfig.pScratch != null && sqlite3GlobalConfig.szScratch >= 100
220 && sqlite3GlobalConfig.nScratch >= 0 )
221 {
222 int i;
223 sqlite3GlobalConfig.szScratch = ROUNDDOWN8( sqlite3GlobalConfig.szScratch - 4 );
224 //mem0.aScratchFree = (u32)&((char)sqlite3GlobalConfig.pScratch)
225 // [sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch];
226 //for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; }
227 //mem0.nScratchFree = sqlite3GlobalConfig.nScratch;
228 }
229 else
230 {
231 sqlite3GlobalConfig.pScratch = null;
232 sqlite3GlobalConfig.szScratch = 0;
233 }
234 if ( sqlite3GlobalConfig.pPage == null || sqlite3GlobalConfig.szPage < 512
235 || sqlite3GlobalConfig.nPage < 1 )
236 {
237 sqlite3GlobalConfig.pPage = null;
238 sqlite3GlobalConfig.szPage = 0;
239 sqlite3GlobalConfig.nPage = 0;
240 }
241 return sqlite3GlobalConfig.m.xInit( sqlite3GlobalConfig.m.pAppData );
242 }
243  
244 /*
245 ** Return true if the heap is currently under memory pressure - in other
246 ** words if the amount of heap used is close to the limit set by
247 ** sqlite3_soft_heap_limit().
248 */
249 static bool sqlite3HeapNearlyFull()
250 {
251 return mem0.nearlyFull;
252 }
253  
254 /*
255 ** Deinitialize the memory allocation subsystem.
256 */
257 static void sqlite3MallocEnd()
258 {
259 if ( sqlite3GlobalConfig.m.xShutdown != null )
260 {
261 sqlite3GlobalConfig.m.xShutdown( sqlite3GlobalConfig.m.pAppData );
262 }
263 mem0 = new Mem0Global();//memset(&mem0, 0, sizeof(mem0));
264 }
265  
266 /*
267 ** Return the amount of memory currently checked out.
268 */
269 static sqlite3_int64 sqlite3_memory_used()
270 {
271 int n = 0, mx = 0;
272 sqlite3_int64 res;
273 sqlite3_status( SQLITE_STATUS_MEMORY_USED, ref n, ref mx, 0 );
274 res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
275 return res;
276 }
277  
278 /*
279 ** Return the maximum amount of memory that has ever been
280 ** checked out since either the beginning of this process
281 ** or since the most recent reset.
282 */
283 static sqlite3_int64 sqlite3_memory_highwater( int resetFlag )
284 {
285 int n = 0, mx = 0;
286 sqlite3_int64 res;
287 sqlite3_status( SQLITE_STATUS_MEMORY_USED, ref n, ref mx, resetFlag );
288 res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
289 return res;
290 }
291  
292 /*
293 ** Change the alarm callback
294 */
295 static int sqlite3MemoryAlarm(
296 dxalarmCallback xCallback, //void(*xCallback)(object pArg, sqlite3_int64 used,int N),
297 object pArg,
298 sqlite3_int64 iThreshold
299 )
300 {
301 int nUsed;
302 sqlite3_mutex_enter( mem0.mutex );
303 mem0.alarmCallback = xCallback;
304 mem0.alarmArg = pArg;
305 mem0.alarmThreshold = iThreshold;
306 nUsed = sqlite3StatusValue( SQLITE_STATUS_MEMORY_USED );
307 mem0.nearlyFull = ( iThreshold > 0 && iThreshold <= nUsed );
308 sqlite3_mutex_leave( mem0.mutex );
309 return SQLITE_OK;
310 }
311  
312 /*
313 ** Trigger the alarm
314 */
315 static void sqlite3MallocAlarm( int nByte )
316 {
317 dxalarmCallback xCallback;//void (*xCallback)(void*,sqlite3_int64,int);
318 sqlite3_int64 nowUsed;
319 object pArg;// void* pArg;
320 if ( mem0.alarmCallback == null )
321 return;
322 xCallback = mem0.alarmCallback;
323 nowUsed = sqlite3StatusValue( SQLITE_STATUS_MEMORY_USED );
324 pArg = mem0.alarmArg;
325 mem0.alarmCallback = null;
326 sqlite3_mutex_leave( mem0.mutex );
327 xCallback( pArg, nowUsed, nByte );
328 sqlite3_mutex_enter( mem0.mutex );
329 mem0.alarmCallback = xCallback;
330 mem0.alarmArg = pArg;
331 }
332  
333 /*
334 ** Do a memory allocation with statistics and alarms. Assume the
335 ** lock is already held.
336 */
337 static int mallocWithAlarm( int n, ref int[] pp )
338 {
339 int nFull;
340 int[] p;
341 Debug.Assert( sqlite3_mutex_held( mem0.mutex ) );
342 nFull = sqlite3GlobalConfig.m.xRoundup( n );
343 sqlite3StatusSet( SQLITE_STATUS_MALLOC_SIZE, n );
344 if ( mem0.alarmCallback != null )
345 {
346 int nUsed = sqlite3StatusValue( SQLITE_STATUS_MEMORY_USED );
347 if ( nUsed >= mem0.alarmThreshold - nFull )
348 {
349 mem0.nearlyFull = true;
350 sqlite3MallocAlarm( nFull );
351 }
352 else
353 {
354 mem0.nearlyFull = false;
355 }
356 }
357 p = sqlite3GlobalConfig.m.xMallocInt( nFull );
358 #if SQLITE_ENABLE_MEMORY_MANAGEMENT
359 if( p==null && mem0.alarmCallback!=null ){
360 sqlite3MallocAlarm(nFull);
361 p = sqlite3GlobalConfig.m.xMalloc(nFull);
362 }
363 #endif
364 if ( p != null )
365 {
366 nFull = sqlite3MallocSize( p );
367 sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, nFull );
368 }
369 pp = p;
370 return nFull;
371 }
372 static int mallocWithAlarm( int n, ref byte[] pp )
373 {
374 int nFull;
375 byte[] p;
376 Debug.Assert( sqlite3_mutex_held( mem0.mutex ) );
377 nFull = sqlite3GlobalConfig.m.xRoundup( n );
378 sqlite3StatusSet( SQLITE_STATUS_MALLOC_SIZE, n );
379 if ( mem0.alarmCallback != null )
380 {
381 int nUsed = sqlite3StatusValue( SQLITE_STATUS_MEMORY_USED );
382 if ( nUsed + nFull >= mem0.alarmThreshold )
383 {
384 sqlite3MallocAlarm( nFull );
385 }
386 }
387 p = sqlite3GlobalConfig.m.xMalloc( nFull );
388 if ( p == null && mem0.alarmCallback != null )
389 {
390 sqlite3MallocAlarm( nFull );
391 p = sqlite3GlobalConfig.m.xMalloc( nFull );
392 }
393 if ( p != null )
394 {
395 nFull = sqlite3MallocSize( p );
396 sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, nFull );
397 sqlite3StatusAdd( SQLITE_STATUS_MALLOC_COUNT, 1 );
398 }
399 pp = p;
400 return nFull;
401 }
402  
403 /*
404 ** Allocate memory. This routine is like sqlite3_malloc() except that it
405 ** assumes the memory subsystem has already been initialized.
406 */
407 static Mem sqlite3Malloc( Mem pMem )
408 {
409 return sqlite3GlobalConfig.m.xMallocMem( pMem );
410 }
411 static int[] sqlite3Malloc( int[] pInt, u32 n )
412 {
413 return sqlite3Malloc( pInt, (int)n );
414 }
415  
416 static int[] sqlite3Malloc( int[] pInt, int n )
417 {
418 int[] p = null;
419 if ( n < 0 || n >= 0x7fffff00 )
420 {
421 /* A memory allocation of a number of bytes which is near the maximum
422 ** signed integer value might cause an integer overflow inside of the
423 ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
424 ** 255 bytes of overhead. SQLite itself will never use anything near
425 ** this amount. The only way to reach the limit is with sqlite3_malloc() */
426 p = null;
427 }
428 else if ( sqlite3GlobalConfig.bMemstat )
429 {
430 sqlite3_mutex_enter( mem0.mutex );
431 mallocWithAlarm( n, ref p );
432 sqlite3_mutex_leave( mem0.mutex );
433 }
434 else
435 {
436 p = sqlite3GlobalConfig.m.xMallocInt( n );
437 }
438 return p;
439 }
440  
441 static byte[] sqlite3Malloc( u32 n )
442 {
443 return sqlite3Malloc( (int)n );
444 }
445 static byte[] sqlite3Malloc( int n )
446 {
447 byte[] p = null;
448 if ( n < 0 || n >= 0x7fffff00 )
449 {
450 /* A memory allocation of a number of bytes which is near the maximum
451 ** signed integer value might cause an integer overflow inside of the
452 ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
453 ** 255 bytes of overhead. SQLite itself will never use anything near
454 ** this amount. The only way to reach the limit is with sqlite3_malloc() */
455 p = null;
456 }
457 else if ( sqlite3GlobalConfig.bMemstat )
458 {
459 sqlite3_mutex_enter( mem0.mutex );
460 mallocWithAlarm( n, ref p );
461 sqlite3_mutex_leave( mem0.mutex );
462 }
463 else
464 {
465 p = sqlite3GlobalConfig.m.xMalloc( n );
466 }
467 return p;
468 }
469  
470 /*
471 ** This version of the memory allocation is for use by the application.
472 ** First make sure the memory subsystem is initialized, then do the
473 ** allocation.
474 */
475 static byte[] sqlite3_malloc( int n )
476 {
477 #if !SQLITE_OMIT_AUTOINIT
478 if ( sqlite3_initialize() != 0 )
479 return null;
480 #endif
481 return sqlite3Malloc( n );
482 }
483  
484 /*
485 ** Each thread may only have a single outstanding allocation from
486 ** xScratchMalloc(). We verify this constraint in the single-threaded
487 ** case by setting scratchAllocOut to 1 when an allocation
488 ** is outstanding clearing it when the allocation is freed.
489 */
490 #if SQLITE_THREADSAFE && !(NDEBUG)
491 static int scratchAllocOut = 0;
492 #endif
493  
494  
495 /*
496 ** Allocate memory that is to be used and released right away.
497 ** This routine is similar to alloca() in that it is not intended
498 ** for situations where the memory might be held long-term. This
499 ** routine is intended to get memory to old large transient data
500 ** structures that would not normally fit on the stack of an
501 ** embedded processor.
502 */
503 static byte[][] sqlite3ScratchMalloc( byte[][] apCell, int n )
504 {
505 apCell = sqlite3GlobalConfig.pScratch2;
506 if ( apCell == null )
507 apCell = new byte[n < 200 ? 200 : n][];
508 else if ( apCell.Length < n )
509 Array.Resize( ref apCell, n );
510 sqlite3GlobalConfig.pScratch2 = null;
511 return apCell;
512 }
513  
514 static byte[] sqlite3ScratchMalloc( int n )
515 {
516 byte[] p = null;
517 Debug.Assert( n > 0 );
518  
519 #if SQLITE_THREADSAFE && !(NDEBUG)
520 /* Verify that no more than two scratch allocation per thread
521 ** is outstanding at one time. (This is only checked in the
522 ** single-threaded case since checking in the multi-threaded case
523 ** would be much more complicated.) */
524 Debug.Assert( scratchAllocOut <= 1 );
525 #endif
526  
527 if ( sqlite3GlobalConfig.szScratch < n )
528 {
529 goto scratch_overflow;
530 }
531 else
532 {
533 sqlite3_mutex_enter( mem0.mutex );
534 if ( mem0.nScratchFree == 0 )
535 {
536 sqlite3_mutex_leave( mem0.mutex );
537 goto scratch_overflow;
538 }
539 else
540 {
541 int i;
542 //i = mem0.aScratchFree[--mem0.nScratchFree];
543 //i *= sqlite3GlobalConfig.szScratch;
544 for ( i = 0; i < sqlite3GlobalConfig.pScratch.Length; i++ )
545 {
546 if ( sqlite3GlobalConfig.pScratch[i] == null || sqlite3GlobalConfig.pScratch[i].Length < n )
547 continue;
548 p = sqlite3GlobalConfig.pScratch[i];// (void)&((char)sqlite3GlobalConfig.pScratch)[i];
549 sqlite3GlobalConfig.pScratch[i] = null;
550 break;
551 }
552 sqlite3_mutex_leave( mem0.mutex );
553 if ( p == null )
554 goto scratch_overflow;
555 sqlite3StatusAdd( SQLITE_STATUS_SCRATCH_USED, 1 );
556 sqlite3StatusSet( SQLITE_STATUS_SCRATCH_SIZE, n );
557 //Debug.Assert( (((u8)p - (u8)0) & 7)==0 );
558 }
559 }
560 #if SQLITE_THREADSAFE && !(NDEBUG)
561 scratchAllocOut = ( p != null ? 1 : 0 );
562 #endif
563  
564 return p;
565  
566 scratch_overflow:
567 if ( sqlite3GlobalConfig.bMemstat )
568 {
569 sqlite3_mutex_enter( mem0.mutex );
570 sqlite3StatusSet( SQLITE_STATUS_SCRATCH_SIZE, n );
571 n = mallocWithAlarm( n, ref p );
572 if ( p != null )
573 sqlite3StatusAdd( SQLITE_STATUS_SCRATCH_OVERFLOW, n );
574 sqlite3_mutex_leave( mem0.mutex );
575 }
576 else
577 {
578 p = sqlite3GlobalConfig.m.xMalloc( n );
579 }
580 sqlite3MemdebugSetType( p, MEMTYPE_SCRATCH );
581 #if SQLITE_THREADSAFE && !(NDEBUG)
582 scratchAllocOut = ( p != null ) ? 1 : 0;
583 #endif
584 return p;
585 }
586 static void sqlite3ScratchFree( byte[][] p )
587 {
588 if ( p != null )
589 {
590  
591 if ( sqlite3GlobalConfig.pScratch2 == null || sqlite3GlobalConfig.pScratch2.Length < p.Length )
592 {
593 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_SCRATCH ) );
594 Debug.Assert( sqlite3MemdebugNoType( p, ~MEMTYPE_SCRATCH ) );
595 sqlite3MemdebugSetType( p, MEMTYPE_HEAP );
596 if ( sqlite3GlobalConfig.bMemstat )
597 {
598 int iSize = sqlite3MallocSize( p );
599 sqlite3_mutex_enter( mem0.mutex );
600 sqlite3StatusAdd( SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize );
601 sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, -iSize );
602 sqlite3StatusAdd( SQLITE_STATUS_MALLOC_COUNT, -1 );
603 sqlite3GlobalConfig.pScratch2 = p;// sqlite3GlobalConfig.m.xFree(ref p);
604 sqlite3_mutex_leave( mem0.mutex );
605 }
606 else
607 {
608 sqlite3GlobalConfig.pScratch2 = p;//sqlite3GlobalConfig.m.xFree(ref p);
609 }
610 }
611 else // larger Scratch 2 already in use, let the C# GC handle
612 {
613 //int i;
614 //i = (int)((u8)p - (u8)sqlite3GlobalConfig.pScratch);
615 //i /= sqlite3GlobalConfig.szScratch;
616 //Debug.Assert(i >= 0 && i < sqlite3GlobalConfig.nScratch);
617 //sqlite3_mutex_enter(mem0.mutex);
618 //Debug.Assert(mem0.nScratchFree < (u32)sqlite3GlobalConfig.nScratch);
619 //mem0.aScratchFree[mem0.nScratchFree++] = i;
620 //sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
621 //sqlite3_mutex_leave(mem0.mutex);
622 #if SQLITE_THREADSAFE && !(NDEBUG)
623 /* Verify that no more than two scratch allocation per thread
624 ** is outstanding at one time. (This is only checked in the
625 ** single-threaded case since checking in the multi-threaded case
626 ** would be much more complicated.) */
627 Debug.Assert( scratchAllocOut >= 1 && scratchAllocOut <= 2 );
628 scratchAllocOut = 0;
629 #endif
630 }
631 //if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
632 // /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
633 // ScratchFreeslot *pSlot;
634 // pSlot = (ScratchFreeslot)p;
635 // sqlite3_mutex_enter(mem0.mutex);
636 // pSlot->pNext = mem0.pScratchFree;
637 // mem0.pScratchFree = pSlot;
638 // mem0.nScratchFree++;
639 // Debug.Assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
640 // sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
641 // sqlite3_mutex_leave(mem0.mutex);
642 //}else{
643 // /* Release memory back to the heap */
644 // Debug.Assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
645 // Debug.Assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
646 // sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
647 // if( sqlite3GlobalConfig.bMemstat ){
648 // int iSize = sqlite3MallocSize(p);
649 // sqlite3_mutex_enter(mem0.mutex);
650 // sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
651 // sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
652 // sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
653 // sqlite3GlobalConfig.m.xFree(p);
654 // sqlite3_mutex_leave(mem0.mutex);
655 // }else{
656 // sqlite3GlobalConfig.m.xFree(p);
657 // }
658 p = null;
659 }
660 }
661  
662 /*
663 ** TRUE if p is a lookaside memory allocation from db
664 */
665 #if !SQLITE_OMIT_LOOKASIDE
666 static int isLookaside(sqlite3 db, object *p){
667 return p && p>=db.lookaside.pStart && p<db.lookaside.pEnd;
668 }
669 #else
670 //#define isLookaside(A,B) 0
671 static bool isLookaside( sqlite3 db, object p )
672 {
673 return false;
674 }
675 #endif
676  
677 /*
678 ** Return the size of a memory allocation previously obtained from
679 ** sqlite3Malloc() or sqlite3_malloc().
680 */
681 //int sqlite3MallocSize(void* p)
682 //{
683 // Debug.Assert(sqlite3MemdebugHasType(p, MEMTYPE_HEAP));
684 // Debug.Assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
685 // return sqlite3GlobalConfig.m.xSize(p);
686 //}
687 static int sqlite3MallocSize( byte[][] p )
688 {
689 return p.Length * p[0].Length;
690 }
691  
692 static int sqlite3MallocSize( int[] p )
693 {
694 return p.Length;
695 }
696  
697 static int sqlite3MallocSize( byte[] p )
698 {
699 return sqlite3GlobalConfig.m.xSize( p );
700 }
701  
702 static int sqlite3DbMallocSize( sqlite3 db, byte[] p )
703 {
704 Debug.Assert( db == null || sqlite3_mutex_held( db.mutex ) );
705 if ( db != null && isLookaside( db, p ) )
706 {
707 return db.lookaside.sz;
708 }
709 else
710 {
711 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_DB ) );
712 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_LOOKASIDE | MEMTYPE_HEAP ) );
713 Debug.Assert( db != null || sqlite3MemdebugNoType( p, MEMTYPE_LOOKASIDE ) );
714 return sqlite3GlobalConfig.m.xSize( p );
715 }
716 }
717  
718 /*
719 ** Free memory previously obtained from sqlite3Malloc().
720 */
721 static void sqlite3_free( ref byte[] p )
722 {
723 if ( p == null )
724 return;
725 Debug.Assert( sqlite3MemdebugNoType( p, MEMTYPE_DB ) );
726 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_HEAP ) );
727 if ( sqlite3GlobalConfig.bMemstat )
728 {
729 sqlite3_mutex_enter( mem0.mutex );
730 sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize( p ) );
731 sqlite3StatusAdd( SQLITE_STATUS_MALLOC_COUNT, -1 );
732 sqlite3GlobalConfig.m.xFree( ref p );
733 sqlite3_mutex_leave( mem0.mutex );
734 }
735 else
736 {
737 sqlite3GlobalConfig.m.xFree( ref p );
738 }
739 p = null;
740 }
741 static void sqlite3_free( ref Mem p )
742 {
743 if ( p == null )
744 return;
745 if ( sqlite3GlobalConfig.bMemstat )
746 {
747 sqlite3_mutex_enter( mem0.mutex );
748 //sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize( p ) );
749 sqlite3GlobalConfig.m.xFreeMem( ref p );
750 sqlite3_mutex_leave( mem0.mutex );
751 }
752 else
753 {
754 sqlite3GlobalConfig.m.xFreeMem( ref p );
755 }
756 p = null;
757 }
758  
759 /*
760 ** Free memory that might be associated with a particular database
761 ** connection.
762 */
763 static void sqlite3DbFree( sqlite3 db, ref byte[] p )
764 {
765 Debug.Assert( db == null || sqlite3_mutex_held( db.mutex ) );
766 if ( db != null )
767 {
768 //if ( db.pnBytesFreed != 0 )
769 //{
770 #if SQLITE_OMIT_LOOKASIDE
771 //db.pnBytesFreed += 1;
772 #else
773 db.pnBytesFreed += sqlite3DbMallocSize( db, p );
774 #endif
775 return;
776 //}
777 #if !SQLITE_OMIT_LOOKASIDE
778 if( isLookaside(db, p) ){
779 LookasideSlot *pBuf = (LookasideSlot)p;
780 pBuf.pNext = db.lookaside.pFree;
781 db.lookaside.pFree = pBuf;
782 db.lookaside.nOut--;
783 }else
784 #endif
785 //{
786 // Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_DB ) );
787 // Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_LOOKASIDE | MEMTYPE_HEAP ) );
788 // Debug.Assert( db != null || sqlite3MemdebugNoType( p, MEMTYPE_LOOKASIDE ) );
789 // sqlite3MemdebugSetType( p, MEMTYPE_HEAP );
790 // sqlite3_free( ref p );
791 //}
792 }
793 }
794  
795 /*
796 ** Change the size of an existing memory allocation
797 */
798 static byte[] sqlite3Realloc( byte[] pOld, int nBytes )
799 {
800 int nOld, nNew, nDiff;
801 byte[] pNew;
802 if ( pOld == null )
803 {
804 pOld = sqlite3Malloc( nBytes );
805 return pOld;
806 }
807 if ( nBytes < 0 )
808 {
809 sqlite3_free( ref pOld );
810 return null;
811 }
812 if ( nBytes >= 0x7fffff00 )
813 {
814 /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
815 return null;
816 }
817 nOld = sqlite3MallocSize( pOld );
818 nNew = sqlite3GlobalConfig.m.xRoundup( nBytes );
819 if ( nOld == nNew )
820 {
821 pNew = pOld;
822 }
823 else if ( sqlite3GlobalConfig.bMemstat )
824 {
825 sqlite3_mutex_enter( mem0.mutex );
826 sqlite3StatusSet( SQLITE_STATUS_MALLOC_SIZE, nBytes );
827 nDiff = nNew - nOld;
828 if ( sqlite3StatusValue( SQLITE_STATUS_MEMORY_USED ) >=
829 mem0.alarmThreshold - nDiff )
830 {
831 sqlite3MallocAlarm( nDiff );
832 }
833 Debug.Assert( sqlite3MemdebugHasType( pOld, MEMTYPE_HEAP ) );
834 Debug.Assert( sqlite3MemdebugNoType( pOld, ~MEMTYPE_HEAP ) );
835 pNew = sqlite3GlobalConfig.m.xRealloc( pOld, nNew );
836 if ( pNew == null && mem0.alarmCallback != null )
837 {
838 sqlite3MallocAlarm( nBytes );
839 pNew = sqlite3GlobalConfig.m.xRealloc( pOld, nNew );
840 }
841 if ( pNew != null )
842 {
843 nNew = sqlite3MallocSize( pNew );
844 sqlite3StatusAdd( SQLITE_STATUS_MEMORY_USED, nNew - nOld );
845 }
846 sqlite3_mutex_leave( mem0.mutex );
847 }
848 else
849 {
850 pNew = sqlite3GlobalConfig.m.xRealloc( pOld, nNew );
851 }
852 return pNew;
853 }
854  
855 /*
856 ** The public interface to sqlite3Realloc. Make sure that the memory
857 ** subsystem is initialized prior to invoking sqliteRealloc.
858 */
859 static byte[] sqlite3_realloc( byte[] pOld, int n )
860 {
861 #if !SQLITE_OMIT_AUTOINIT
862 if ( sqlite3_initialize() != 0 )
863 return null;
864 #endif
865 return sqlite3Realloc( pOld, n );
866 }
867  
868  
869 /*
870 ** Allocate and zero memory.
871 */
872 static byte[] sqlite3MallocZero( int n )
873 {
874 byte[] p = sqlite3Malloc( n );
875 if ( p != null )
876 {
877 Array.Clear( p, 0, n );// memset(p, 0, n);
878 }
879 return p;
880 }
881  
882 /*
883 ** Allocate and zero memory. If the allocation fails, make
884 ** the mallocFailed flag in the connection pointer.
885 */
886 static Mem sqlite3DbMallocZero( sqlite3 db, Mem m )
887 {
888 return new Mem();
889 }
890  
891 static byte[] sqlite3DbMallocZero( sqlite3 db, int n )
892 {
893 byte[] p = sqlite3DbMallocRaw( db, n );
894 if ( p != null )
895 {
896 Array.Clear( p, 0, n );// memset(p, 0, n);
897 }
898 return p;
899 }
900  
901 /*
902 ** Allocate and zero memory. If the allocation fails, make
903 ** the mallocFailed flag in the connection pointer.
904 **
905 ** If db!=0 and db->mallocFailed is true (indicating a prior malloc
906 ** failure on the same database connection) then always return 0.
907 ** Hence for a particular database connection, once malloc starts
908 ** failing, it fails consistently until mallocFailed is reset.
909 ** This is an important assumption. There are many places in the
910 ** code that do things like this:
911 **
912 ** int *a = (int)sqlite3DbMallocRaw(db, 100);
913 ** int *b = (int)sqlite3DbMallocRaw(db, 200);
914 ** if( b ) a[10] = 9;
915 **
916 ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
917 ** that all prior mallocs (ex: "a") worked too.
918 */
919 static byte[] sqlite3DbMallocRaw( sqlite3 db, int n )
920 {
921 byte[] p;
922 Debug.Assert( db == null || sqlite3_mutex_held( db.mutex ) );
923 Debug.Assert( db == null || db.pnBytesFreed == 0 );
924 #if !SQLITE_OMIT_LOOKASIDE
925 if( db ){
926 LookasideSlot *pBuf;
927 if( db->mallocFailed ){
928 return 0;
929 }
930 if( db->lookaside.bEnabled ){
931 if( n>db->lookaside.sz ){
932 db->lookaside.anStat[1]++;
933 }else if( (pBuf = db->lookaside.pFree)==0 ){
934 db->lookaside.anStat[2]++;
935 }else{
936 db->lookaside.pFree = pBuf->pNext;
937 db->lookaside.nOut++;
938 db->lookaside.anStat[0]++;
939 if( db->lookaside.nOut>db->lookaside.mxOut ){
940 db->lookaside.mxOut = db->lookaside.nOut;
941 }
942 return (void)pBuf;
943 }
944 }
945 }
946 #else
947 //if( db && db->mallocFailed ){
948 // return 0;
949 //}
950 #endif
951 p = sqlite3Malloc( n );
952 //if( null==p && db ){
953 // db->mallocFailed = 1;
954 //}
955 #if !SQLITE_OMIT_LOOKASIDE
956 sqlite3MemdebugSetType(p, MEMTYPE_DB |
957 ((db !=null && db.lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
958 #endif
959 return p;
960 }
961  
962 /*
963 ** Resize the block of memory pointed to by p to n bytes. If the
964 ** resize fails, set the mallocFailed flag in the connection object.
965 */
966 static byte[] sqlite3DbRealloc( sqlite3 db, byte[] p, int n )
967 {
968 byte[] pNew = null;
969 Debug.Assert( db != null );
970 Debug.Assert( sqlite3_mutex_held( db.mutex ) );
971 //if( db->mallocFailed==0 ){
972 if ( p == null )
973 {
974 return sqlite3DbMallocRaw( db, n );
975 }
976 #if !SQLITE_OMIT_LOOKASIDE
977 if( isLookaside(db, p) ){
978 if( n<=db->lookaside.sz ){
979 return p;
980 }
981 pNew = sqlite3DbMallocRaw(db, n);
982 if( pNew ){
983 memcpy(pNew, p, db->lookaside.sz);
984 sqlite3DbFree(db, ref p);
985 }
986 }else
987 #else
988 {
989 {
990 #endif
991 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_DB ) );
992 Debug.Assert( sqlite3MemdebugHasType( p, MEMTYPE_LOOKASIDE | MEMTYPE_HEAP ) );
993 sqlite3MemdebugSetType( p, MEMTYPE_HEAP );
994 pNew = sqlite3_realloc( p, n );
995 //if( null==pNew ){
996 //sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
997 // db->mallocFailed = 1;
998 //}
999 #if !SQLITE_OMIT_LOOKASIDE
1000 sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
1001 (db.lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
1002 #endif
1003 }
1004 }
1005 return pNew;
1006 }
1007  
1008 /*
1009 ** Attempt to reallocate p. If the reallocation fails, then free p
1010 ** and set the mallocFailed flag in the database connection.
1011 */
1012 static byte[] sqlite3DbReallocOrFree( sqlite3 db, byte[] p, int n )
1013 {
1014 byte[] pNew;
1015 pNew = sqlite3DbRealloc( db, p, n );
1016 if ( null == pNew )
1017 {
1018 sqlite3DbFree( db, ref p );
1019 }
1020 return pNew;
1021 }
1022  
1023 /*
1024 ** Make a copy of a string in memory obtained from sqliteMalloc(). These
1025 ** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
1026 ** is because when memory debugging is turned on, these two functions are
1027 ** called via macros that record the current file and line number in the
1028 ** ThreadData structure.
1029 */
1030 //char *sqlite3DbStrDup(sqlite3 db, string z){
1031 // string zNew;
1032 // size_t n;
1033 // if( z==0 ){
1034 // return 0;
1035 // }
1036 // n = sqlite3Strlen30(z) + 1;
1037 // Debug.Assert( (n&0x7fffffff)==n );
1038 // zNew = sqlite3DbMallocRaw(db, (int)n);
1039 // if( zNew ){
1040 // memcpy(zNew, z, n);
1041 // }
1042 // return zNew;
1043 //}
1044 //char *sqlite3DbStrNDup(sqlite3 db, string z, int n){
1045 // string zNew;
1046 // if( z==0 ){
1047 // return 0;
1048 // }
1049 // Debug.Assert( (n&0x7fffffff)==n );
1050 // zNew = sqlite3DbMallocRaw(db, n+1);
1051 // if( zNew ){
1052 // memcpy(zNew, z, n);
1053 // zNew[n] = 0;
1054 // }
1055 // return zNew;
1056 //}
1057  
1058  
1059  
1060 /*
1061 ** Create a string from the zFromat argument and the va_list that follows.
1062 ** Store the string in memory obtained from sqliteMalloc() and make pz
1063 ** point to that string.
1064 */
1065 static void sqlite3SetString( ref string pz, sqlite3 db, string zFormat, params string[] ap )
1066 {
1067 //va_list ap;
1068 lock ( lock_va_list )
1069 {
1070 string z;
1071  
1072 va_start( ap, zFormat );
1073 z = sqlite3VMPrintf( db, zFormat, ap );
1074 va_end( ref ap );
1075 sqlite3DbFree( db, ref pz );
1076 pz = z;
1077 }
1078 }
1079  
1080 /*
1081 ** This function must be called before exiting any API function (i.e.
1082 ** returning control to the user) that has called sqlite3_malloc or
1083 ** sqlite3_realloc.
1084 **
1085 ** The returned value is normally a copy of the second argument to this
1086 ** function. However, if a malloc() failure has occurred since the previous
1087 ** invocation SQLITE_NOMEM is returned instead.
1088 **
1089 ** If the first argument, db, is not NULL and a malloc() error has occurred,
1090 ** then the connection error-code (the value returned by sqlite3_errcode())
1091 ** is set to SQLITE_NOMEM.
1092 */
1093 static int sqlite3ApiExit( int zero, int rc )
1094 {
1095 sqlite3 db = null;
1096 return sqlite3ApiExit( db, rc );
1097 }
1098  
1099 static int sqlite3ApiExit( sqlite3 db, int rc )
1100 {
1101 /* If the db handle is not NULL, then we must hold the connection handle
1102 ** mutex here. Otherwise the read (and possible write) of db.mallocFailed
1103 ** is unsafe, as is the call to sqlite3Error().
1104 */
1105 Debug.Assert( db == null || sqlite3_mutex_held( db.mutex ) );
1106 if ( /*db != null && db.mallocFailed != 0 || */ rc == SQLITE_IOERR_NOMEM )
1107 {
1108 sqlite3Error( db, SQLITE_NOMEM, string.Empty );
1109 //db.mallocFailed = 0;
1110 rc = SQLITE_NOMEM;
1111 }
1112 return rc & ( db != null ? db.errMask : 0xff );
1113 }
1114 }
1115 }