using System; namespace Community.CsharpSqlite { public partial class Sqlite3 { /* ************************************************************************* ** ** This file contains low-level memory & pool allocation drivers ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** ************************************************************************* */ /* ** Like malloc(), but remember the size of the allocation ** so that we can find it later using sqlite3MemSize(). ** ** For this low-level routine, we are guaranteed that nByte>0 because ** cases of nByte<=0 will be intercepted and dealt with by higher level ** routines. */ #if SQLITE_POOL_MEM #if TRUE static byte[] sqlite3MemMalloc( u32 nByte ) { return new byte[nByte]; } static byte[] sqlite3MemMalloc( int nByte ) { return new byte[nByte]; } static int[] sqlite3MemMallocInt( int nInt ) { return new int[nInt]; } #else static byte[] sqlite3MemMalloc(int nByte) { byte[] pByte = null; int savej = -1; int BestSize = int.MaxValue; if (nByte > mem0.aByteSize[0]) { int i; for (i = 0; i < mem0.aByteSize.Length - 1; i++) if (nByte <= mem0.aByteSize[i]) break; mem0.mr_Byte++; for (int j = 0; j <= mem0.aByte_used[i]; j++) if (mem0.aByte[i][j] != null) { if (mem0.aByte[i][j].Length == nByte) { pByte = mem0.aByte[i][j]; mem0.aByte[i][j] = null; mem0.cf_Byte++; if (j == mem0.aByte_used[i]) mem0.aByte_used[i]--; break; } if (mem0.aByte[i][j].Length > nByte) { if (mem0.aByte[i][j].Length < BestSize) { BestSize = mem0.aByte[i][j].Length; savej = j; } } } if (pByte == null && savej >= 0) { pByte = mem0.aByte[i][savej]; mem0.aByte[i][savej] = null; mem0.cf_Byte++; Array.Resize(ref pByte, nByte); } if (mem0.aByte_used[i] >=0 && mem0.aByte[i][mem0.aByte_used[i]] == null) mem0.aByte_used[i]--; } if (pByte == null) pByte = new byte[nByte]; return pByte; } static int[] sqlite3MemMallocInt(int nInt) { int[] pInt = null; int savei = -1; int BestSize = int.MaxValue; if (nInt >=10) { mem0.mr_Int++; int i; for (i = 0; i < mem0.hw_Int; i++) if (mem0.aInt[i] != null) { if (mem0.aInt[i].Length == nInt) { pInt = mem0.aInt[i]; mem0.aInt[i] = null; mem0.cf_Int++; break; } if (mem0.aInt[i].Length > nInt) { if (mem0.aInt[i].Length < BestSize) { BestSize = mem0.aInt[i].Length; savei = i; } } } if (pInt == null && savei >= 0) { pInt = mem0.aInt[savei]; mem0.aInt[savei] = null; mem0.cf_Int++; } } if (pInt == null) pInt = new int[nInt]; return pInt; } #endif static Mem sqlite3MemMallocMem( Mem dummy ) { Mem pMem; mem0.msMem.alloc++; if ( mem0.msMem.next > 0 && mem0.aMem[mem0.msMem.next] != null ) { pMem = mem0.aMem[mem0.msMem.next]; mem0.aMem[mem0.msMem.next] = null; mem0.msMem.cached++; mem0.msMem.next--; } else pMem = new Mem(); return pMem; } static BtCursor sqlite3MemMallocBtCursor( BtCursor dummy ) { BtCursor pBtCursor; mem0.msBtCursor.alloc++; if ( mem0.msBtCursor.next > 0 && mem0.aBtCursor[mem0.msBtCursor.next] != null ) { pBtCursor = mem0.aBtCursor[mem0.msBtCursor.next]; Debug.Assert( pBtCursor.pNext == null && pBtCursor.pPrev == null && pBtCursor.wrFlag == 0 ); mem0.aBtCursor[mem0.msBtCursor.next] = null; mem0.msBtCursor.cached++; mem0.msBtCursor.next--; } else pBtCursor = new BtCursor(); return pBtCursor; } #endif /* ** Free memory. */ // -- overloads --------------------------------------- private static void sqlite3MemFree(ref T x) where T : class { x = null; } private static void sqlite3MemFree(ref string x) { x = null; } // /* ** Like free() but works for allocations obtained from sqlite3MemMalloc() ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since ** cases where pPrior==0 will have been intecepted and dealt with ** by higher-level routines. */ #if SQLITE_POOL_MEM #if TRUE static void sqlite3MemFreeInt( ref int[] pPrior ) { pPrior = null; } #else static void sqlite3MemFree(ref byte[] pPrior) { if (pPrior == null) return; if (pPrior.Length > mem0.aByteSize[0]) { int savej = -1; int Smallest = int.MaxValue; int i; for (i = 0; i < mem0.aByteSize.Length - 1; i++) if (pPrior.Length <= mem0.aByteSize[i]) break; #if DEBUG for (int j = 0; j < mem0.aByte[i].Length; j++) if (mem0.aByte[i][j] != null && mem0.aByte[i][j] == pPrior) Debugger.Break(); #endif mem0.mf_Byte++; for (int j = 0; j <= mem0.aByte_used[i]; j++) { if (mem0.aByte[i][j] == null) { mem0.aByte[i][j] = pPrior; pPrior = null; return; } if (mem0.aByte[i][j].Length < Smallest) { savej = j; Smallest = mem0.aByte[i][j].Length; } } if (mem0.aByte_used[i] < mem0.aByte[i].Length - 1) mem0.aByte[i][++mem0.aByte_used[i]] = pPrior; else if (savej >= 0) mem0.aByte[i][savej] = pPrior; } pPrior = null; return; } static void sqlite3MemFreeInt(ref int[] pPrior) { if (pPrior == null) return; if (pPrior.Length >= 10) { int savei = -1; int Smallest = int.MaxValue; #if DEBUG for (int i = 0; i < mem0.aInt.Length; i++) if (mem0.aInt[i] != null && mem0.aInt[i] == pPrior) Debugger.Break(); #endif mem0.mf_Int++; for (int i = 0; i < mem0.aInt.Length; i++) { if (mem0.aInt[i] == null) { mem0.aInt[i] = pPrior; pPrior = null; return; } if (mem0.aInt[i].Length < Smallest) { savei = i; Smallest = mem0.aInt[i].Length; } } if (savei >= 0) mem0.aInt[savei] = pPrior; } pPrior = null; return; } #endif static void sqlite3MemFreeMem( ref Mem pPrior ) { if ( pPrior == null ) return; #if FALSE && DEBUG for (int i = mem0.msMem.next - 1; i >= 0; i--) if (mem0.aMem[i] != null && mem0.aMem[i] == pPrior) Debugger.Break(); #endif mem0.msMem.dealloc++; if ( mem0.msMem.next < mem0.aMem.Length - 1 ) { pPrior.db = null; pPrior._SumCtx = null; pPrior._MD5Context = null; pPrior._SubProgram = null; pPrior.flags = MEM_Null; pPrior.r = 0; pPrior.u.i = 0; pPrior.n = 0; if ( pPrior.zBLOB != null ) sqlite3MemFree( ref pPrior.zBLOB ); mem0.aMem[++mem0.msMem.next] = pPrior; if ( mem0.msMem.next > mem0.msMem.max ) mem0.msMem.max = mem0.msMem.next; } //Array.Resize( ref mem0.aMem, (int)(mem0.hw_Mem * 1.5 + 1 )); //mem0.aMem[mem0.hw_Mem] = pPrior; //mem0.hw_Mem = mem0.aMem.Length; pPrior = null; return; } static void sqlite3MemFreeBtCursor( ref BtCursor pPrior ) { if ( pPrior == null ) return; #if FALSE && DEBUG for ( int i = mem0.msBtCursor.next - 1; i >= 0; i-- ) if ( mem0.aBtCursor[i] != null && mem0.aBtCursor[i] == pPrior ) Debugger.Break(); #endif mem0.msBtCursor.dealloc++; if ( mem0.msBtCursor.next < mem0.aBtCursor.Length - 1 ) { mem0.aBtCursor[++mem0.msBtCursor.next] = pPrior; if ( mem0.msBtCursor.next > mem0.msBtCursor.max ) mem0.msBtCursor.max = mem0.msBtCursor.next; } //Array.Resize( ref mem0.aBtCursor, (int)(mem0.hw_BtCursor * 1.5 + 1 )); //mem0.aBtCursor[mem0.hw_BtCursor] = pPrior; //mem0.hw_BtCursor = mem0.aBtCursor.Length; pPrior = null; return; } /* ** Like realloc(). Resize an allocation previously obtained from ** sqlite3MemMalloc(). ** ** For this low-level interface, we know that pPrior!=0. Cases where ** pPrior==0 while have been intercepted by higher-level routine and ** redirected to xMalloc. Similarly, we know that nByte>0 becauses ** cases where nByte<=0 will have been intercepted by higher-level ** routines and redirected to xFree. */ static byte[] sqlite3MemRealloc( ref byte[] pPrior, int nByte ) { // sqlite3_int64 p = (sqlite3_int64*)pPrior; // Debug.Assert(pPrior!=0 && nByte>0 ); // nByte = ROUND8( nByte ); // p = (sqlite3_int64*)pPrior; // p--; // p = realloc(p, nByte+8 ); // if( p ){ // p[0] = nByte; // p++; // } // return (void*)p; Array.Resize( ref pPrior, nByte ); return pPrior; } #else /* ** No-op versions of all memory allocation routines */ private static byte[] sqlite3MemMalloc(int nByte) { return new byte[nByte]; } private static int[] sqlite3MemMallocInt(int nInt) { return new int[nInt]; } private static Mem sqlite3MemMallocMem(Mem pMem) { return new Mem(); } private static void sqlite3MemFree(ref byte[] pPrior) { pPrior = null; } private static void sqlite3MemFreeInt(ref int[] pPrior) { pPrior = null; } private static void sqlite3MemFreeMem(ref Mem pPrior) { pPrior = null; } private static int sqlite3MemInit() { return SQLITE_OK; } private static void sqlite3MemShutdown() { } private static BtCursor sqlite3MemMallocBtCursor(BtCursor dummy) { return new BtCursor(); } private static void sqlite3MemFreeBtCursor(ref BtCursor pPrior) { pPrior = null; } #endif private static byte[] sqlite3MemRealloc(byte[] pPrior, int nByte) { Array.Resize(ref pPrior, nByte); return pPrior; } /* ** Report the allocated size of a prior return from xMalloc() ** or xRealloc(). */ private static int sqlite3MemSize(byte[] pPrior) { // sqlite3_int64 p; // if( pPrior==0 ) return 0; // p = (sqlite3_int64*)pPrior; // p--; // return p[0]; return pPrior == null ? 0 : (int)pPrior.Length; } /* ** Round up a request size to the next valid allocation size. */ private static int sqlite3MemRoundup(int n) { return n;// ROUND8( n ); } /* ** Initialize this module. */ private static int sqlite3MemInit(object NotUsed) { UNUSED_PARAMETER(NotUsed); if (!sqlite3GlobalConfig.bMemstat) { /* If memory status is enabled, then the malloc.c wrapper will already ** hold the STATIC_MEM mutex when the routines here are invoked. */ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } return SQLITE_OK; } /* ** Deinitialize this module. */ private static void sqlite3MemShutdown(object NotUsed) { UNUSED_PARAMETER(NotUsed); return; } /* ** This routine is the only routine in this file with external linkage. ** ** Populate the low-level memory allocation function pointers in ** sqlite3GlobalConfig.m with pointers to the routines in this file. */ private static void sqlite3MemSetDefault() { sqlite3_mem_methods defaultMethods = new sqlite3_mem_methods( sqlite3MemMalloc, sqlite3MemMallocInt, sqlite3MemMallocMem, sqlite3MemFree, sqlite3MemFreeInt, sqlite3MemFreeMem, sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, (dxMemInit)sqlite3MemInit, (dxMemShutdown)sqlite3MemShutdown, 0 ); sqlite3_config(SQLITE_CONFIG_MALLOC, defaultMethods); } private static void sqlite3DbFree(sqlite3 db, ref int[] pPrior) { if (pPrior != null) sqlite3MemFreeInt(ref pPrior); } private static void sqlite3DbFree(sqlite3 db, ref Mem pPrior) { if (pPrior != null) sqlite3MemFreeMem(ref pPrior); } private static void sqlite3DbFree(sqlite3 db, ref Mem[] pPrior) { if (pPrior != null) for (int i = 0; i < pPrior.Length; i++) sqlite3MemFreeMem(ref pPrior[i]); } private static void sqlite3DbFree(sqlite3 db, ref T pT) where T : class { } private static void sqlite3DbFree(sqlite3 db, ref string pString) { } } }