wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Runtime.InteropServices; |
||
4 | |||
5 | using sqlite3_int64 = System.Int64; |
||
6 | using u32 = System.UInt32; |
||
7 | using System.Text; |
||
8 | |||
9 | namespace Community.CsharpSqlite |
||
10 | { |
||
11 | public partial class Sqlite3 |
||
12 | { |
||
13 | /* |
||
14 | ************************************************************************* |
||
15 | ** |
||
16 | ** This file contains low-level memory & pool allocation drivers |
||
17 | ** |
||
18 | ** This file contains implementations of the low-level memory allocation |
||
19 | ** routines specified in the sqlite3_mem_methods object. |
||
20 | ** |
||
21 | ************************************************************************* |
||
22 | */ |
||
23 | |||
24 | /* |
||
25 | ** Like malloc(), but remember the size of the allocation |
||
26 | ** so that we can find it later using sqlite3MemSize(). |
||
27 | ** |
||
28 | ** For this low-level routine, we are guaranteed that nByte>0 because |
||
29 | ** cases of nByte<=0 will be intercepted and dealt with by higher level |
||
30 | ** routines. |
||
31 | */ |
||
32 | #if SQLITE_POOL_MEM |
||
33 | #if TRUE |
||
34 | static byte[] sqlite3MemMalloc( u32 nByte ) |
||
35 | { |
||
36 | return new byte[nByte]; |
||
37 | } |
||
38 | static byte[] sqlite3MemMalloc( int nByte ) |
||
39 | { |
||
40 | return new byte[nByte]; |
||
41 | } |
||
42 | static int[] sqlite3MemMallocInt( int nInt ) |
||
43 | { |
||
44 | return new int[nInt]; |
||
45 | } |
||
46 | #else |
||
47 | static byte[] sqlite3MemMalloc(int nByte) |
||
48 | { |
||
49 | byte[] pByte = null; |
||
50 | int savej = -1; |
||
51 | int BestSize = int.MaxValue; |
||
52 | if (nByte > mem0.aByteSize[0]) |
||
53 | { |
||
54 | int i; |
||
55 | for (i = 0; i < mem0.aByteSize.Length - 1; i++) if (nByte <= mem0.aByteSize[i]) break; |
||
56 | mem0.mr_Byte++; |
||
57 | for (int j = 0; j <= mem0.aByte_used[i]; j++) |
||
58 | if (mem0.aByte[i][j] != null) |
||
59 | { |
||
60 | if (mem0.aByte[i][j].Length == nByte) |
||
61 | { |
||
62 | pByte = mem0.aByte[i][j]; mem0.aByte[i][j] = null; mem0.cf_Byte++; |
||
63 | if (j == mem0.aByte_used[i]) mem0.aByte_used[i]--; |
||
64 | break; |
||
65 | } |
||
66 | if (mem0.aByte[i][j].Length > nByte) |
||
67 | { |
||
68 | if (mem0.aByte[i][j].Length < BestSize) |
||
69 | { |
||
70 | BestSize = mem0.aByte[i][j].Length; |
||
71 | savej = j; |
||
72 | } |
||
73 | } |
||
74 | } |
||
75 | if (pByte == null && savej >= 0) |
||
76 | { |
||
77 | pByte = mem0.aByte[i][savej]; mem0.aByte[i][savej] = null; mem0.cf_Byte++; |
||
78 | Array.Resize(ref pByte, nByte); |
||
79 | } |
||
80 | if (mem0.aByte_used[i] >=0 && mem0.aByte[i][mem0.aByte_used[i]] == null) mem0.aByte_used[i]--; |
||
81 | } |
||
82 | if (pByte == null) pByte = new byte[nByte]; |
||
83 | return pByte; |
||
84 | } |
||
85 | static int[] sqlite3MemMallocInt(int nInt) |
||
86 | { |
||
87 | int[] pInt = null; |
||
88 | int savei = -1; |
||
89 | int BestSize = int.MaxValue; |
||
90 | if (nInt >=10) |
||
91 | { |
||
92 | mem0.mr_Int++; |
||
93 | int i; |
||
94 | for (i = 0; i < mem0.hw_Int; i++) |
||
95 | if (mem0.aInt[i] != null) |
||
96 | { |
||
97 | if (mem0.aInt[i].Length == nInt) |
||
98 | { |
||
99 | pInt = mem0.aInt[i]; mem0.aInt[i] = null; mem0.cf_Int++; break; |
||
100 | } |
||
101 | if (mem0.aInt[i].Length > nInt) |
||
102 | { |
||
103 | if (mem0.aInt[i].Length < BestSize) |
||
104 | { |
||
105 | BestSize = mem0.aInt[i].Length; |
||
106 | savei = i; |
||
107 | } |
||
108 | } |
||
109 | } |
||
110 | if (pInt == null && savei >= 0) |
||
111 | { |
||
112 | pInt = mem0.aInt[savei]; mem0.aInt[savei] = null; mem0.cf_Int++; |
||
113 | } |
||
114 | } |
||
115 | if (pInt == null) pInt = new int[nInt]; |
||
116 | return pInt; |
||
117 | } |
||
118 | #endif |
||
119 | |||
120 | static Mem sqlite3MemMallocMem( Mem dummy ) |
||
121 | { |
||
122 | Mem pMem; |
||
123 | mem0.msMem.alloc++; |
||
124 | if ( mem0.msMem.next > 0 && mem0.aMem[mem0.msMem.next] != null ) |
||
125 | { |
||
126 | pMem = mem0.aMem[mem0.msMem.next]; |
||
127 | mem0.aMem[mem0.msMem.next] = null; |
||
128 | mem0.msMem.cached++; |
||
129 | mem0.msMem.next--; |
||
130 | } |
||
131 | else |
||
132 | pMem = new Mem(); |
||
133 | return pMem; |
||
134 | } |
||
135 | static BtCursor sqlite3MemMallocBtCursor( BtCursor dummy ) |
||
136 | { |
||
137 | BtCursor pBtCursor; |
||
138 | mem0.msBtCursor.alloc++; |
||
139 | if ( mem0.msBtCursor.next > 0 && mem0.aBtCursor[mem0.msBtCursor.next] != null ) |
||
140 | { |
||
141 | pBtCursor = mem0.aBtCursor[mem0.msBtCursor.next]; |
||
142 | Debug.Assert( pBtCursor.pNext == null && pBtCursor.pPrev == null && pBtCursor.wrFlag == 0 ); |
||
143 | mem0.aBtCursor[mem0.msBtCursor.next] = null; |
||
144 | mem0.msBtCursor.cached++; |
||
145 | mem0.msBtCursor.next--; |
||
146 | } |
||
147 | else |
||
148 | pBtCursor = new BtCursor(); |
||
149 | return pBtCursor; |
||
150 | } |
||
151 | #endif |
||
152 | /* |
||
153 | ** Free memory. |
||
154 | */ |
||
155 | // -- overloads --------------------------------------- |
||
156 | static void sqlite3MemFree<T>( ref T x ) where T : class |
||
157 | { |
||
158 | x = null; |
||
159 | } |
||
160 | static void sqlite3MemFree( ref string x ) |
||
161 | { |
||
162 | x = null; |
||
163 | } |
||
164 | // |
||
165 | |||
166 | /* |
||
167 | ** Like free() but works for allocations obtained from sqlite3MemMalloc() |
||
168 | ** or sqlite3MemRealloc(). |
||
169 | ** |
||
170 | ** For this low-level routine, we already know that pPrior!=0 since |
||
171 | ** cases where pPrior==0 will have been intecepted and dealt with |
||
172 | ** by higher-level routines. |
||
173 | */ |
||
174 | #if SQLITE_POOL_MEM |
||
175 | #if TRUE |
||
176 | static void sqlite3MemFreeInt( ref int[] pPrior ) |
||
177 | { |
||
178 | pPrior = null; |
||
179 | } |
||
180 | #else |
||
181 | static void sqlite3MemFree(ref byte[] pPrior) |
||
182 | { |
||
183 | if (pPrior == null) return; |
||
184 | if (pPrior.Length > mem0.aByteSize[0]) |
||
185 | { |
||
186 | int savej = -1; |
||
187 | int Smallest = int.MaxValue; |
||
188 | int i; |
||
189 | for (i = 0; i < mem0.aByteSize.Length - 1; i++) if (pPrior.Length <= mem0.aByteSize[i]) break; |
||
190 | #if DEBUG |
||
191 | for (int j = 0; j < mem0.aByte[i].Length; j++) if (mem0.aByte[i][j] != null && mem0.aByte[i][j] == pPrior) Debugger.Break(); |
||
192 | #endif |
||
193 | mem0.mf_Byte++; |
||
194 | for (int j = 0; j <= mem0.aByte_used[i]; j++) |
||
195 | { |
||
196 | if (mem0.aByte[i][j] == null) |
||
197 | { |
||
198 | mem0.aByte[i][j] = pPrior; |
||
199 | pPrior = null; |
||
200 | return; |
||
201 | } |
||
202 | if (mem0.aByte[i][j].Length < Smallest) |
||
203 | { |
||
204 | savej = j; |
||
205 | Smallest = mem0.aByte[i][j].Length; |
||
206 | } |
||
207 | } |
||
208 | |||
209 | if (mem0.aByte_used[i] < mem0.aByte[i].Length - 1) mem0.aByte[i][++mem0.aByte_used[i]] = pPrior; |
||
210 | else if (savej >= 0) mem0.aByte[i][savej] = pPrior; |
||
211 | } |
||
212 | pPrior = null; |
||
213 | return; |
||
214 | } |
||
215 | static void sqlite3MemFreeInt(ref int[] pPrior) |
||
216 | { |
||
217 | if (pPrior == null) return; |
||
218 | if (pPrior.Length >= 10) |
||
219 | { |
||
220 | int savei = -1; |
||
221 | int Smallest = int.MaxValue; |
||
222 | #if DEBUG |
||
223 | for (int i = 0; i < mem0.aInt.Length; i++) if (mem0.aInt[i] != null && mem0.aInt[i] == pPrior) Debugger.Break(); |
||
224 | #endif |
||
225 | mem0.mf_Int++; |
||
226 | for (int i = 0; i < mem0.aInt.Length; i++) |
||
227 | { |
||
228 | if (mem0.aInt[i] == null) |
||
229 | { |
||
230 | mem0.aInt[i] = pPrior; |
||
231 | pPrior = null; |
||
232 | return; |
||
233 | } |
||
234 | if (mem0.aInt[i].Length < Smallest) |
||
235 | { |
||
236 | savei = i; |
||
237 | Smallest = mem0.aInt[i].Length; |
||
238 | } |
||
239 | } |
||
240 | if (savei >= 0) mem0.aInt[savei] = pPrior; |
||
241 | } |
||
242 | pPrior = null; |
||
243 | return; |
||
244 | } |
||
245 | #endif |
||
246 | static void sqlite3MemFreeMem( ref Mem pPrior ) |
||
247 | { |
||
248 | if ( pPrior == null ) |
||
249 | return; |
||
250 | #if FALSE && DEBUG |
||
251 | for (int i = mem0.msMem.next - 1; i >= 0; i--) if (mem0.aMem[i] != null && mem0.aMem[i] == pPrior) Debugger.Break(); |
||
252 | #endif |
||
253 | mem0.msMem.dealloc++; |
||
254 | if ( mem0.msMem.next < mem0.aMem.Length - 1 ) |
||
255 | { |
||
256 | pPrior.db = null; |
||
257 | pPrior._SumCtx = null; |
||
258 | pPrior._MD5Context = null; |
||
259 | pPrior._SubProgram = null; |
||
260 | pPrior.flags = MEM_Null; |
||
261 | pPrior.r = 0; |
||
262 | pPrior.u.i = 0; |
||
263 | pPrior.n = 0; |
||
264 | if ( pPrior.zBLOB != null ) |
||
265 | sqlite3MemFree( ref pPrior.zBLOB ); |
||
266 | mem0.aMem[++mem0.msMem.next] = pPrior; |
||
267 | if ( mem0.msMem.next > mem0.msMem.max ) |
||
268 | mem0.msMem.max = mem0.msMem.next; |
||
269 | |||
270 | } |
||
271 | //Array.Resize( ref mem0.aMem, (int)(mem0.hw_Mem * 1.5 + 1 )); |
||
272 | //mem0.aMem[mem0.hw_Mem] = pPrior; |
||
273 | //mem0.hw_Mem = mem0.aMem.Length; |
||
274 | pPrior = null; |
||
275 | return; |
||
276 | } |
||
277 | static void sqlite3MemFreeBtCursor( ref BtCursor pPrior ) |
||
278 | { |
||
279 | if ( pPrior == null ) |
||
280 | return; |
||
281 | #if FALSE && DEBUG |
||
282 | for ( int i = mem0.msBtCursor.next - 1; i >= 0; i-- ) if ( mem0.aBtCursor[i] != null && mem0.aBtCursor[i] == pPrior ) Debugger.Break(); |
||
283 | #endif |
||
284 | mem0.msBtCursor.dealloc++; |
||
285 | if ( mem0.msBtCursor.next < mem0.aBtCursor.Length - 1 ) |
||
286 | { |
||
287 | mem0.aBtCursor[++mem0.msBtCursor.next] = pPrior; |
||
288 | if ( mem0.msBtCursor.next > mem0.msBtCursor.max ) |
||
289 | mem0.msBtCursor.max = mem0.msBtCursor.next; |
||
290 | } |
||
291 | //Array.Resize( ref mem0.aBtCursor, (int)(mem0.hw_BtCursor * 1.5 + 1 )); |
||
292 | //mem0.aBtCursor[mem0.hw_BtCursor] = pPrior; |
||
293 | //mem0.hw_BtCursor = mem0.aBtCursor.Length; |
||
294 | pPrior = null; |
||
295 | return; |
||
296 | } |
||
297 | /* |
||
298 | ** Like realloc(). Resize an allocation previously obtained from |
||
299 | ** sqlite3MemMalloc(). |
||
300 | ** |
||
301 | ** For this low-level interface, we know that pPrior!=0. Cases where |
||
302 | ** pPrior==0 while have been intercepted by higher-level routine and |
||
303 | ** redirected to xMalloc. Similarly, we know that nByte>0 becauses |
||
304 | ** cases where nByte<=0 will have been intercepted by higher-level |
||
305 | ** routines and redirected to xFree. |
||
306 | */ |
||
307 | static byte[] sqlite3MemRealloc( ref byte[] pPrior, int nByte ) |
||
308 | { |
||
309 | // sqlite3_int64 p = (sqlite3_int64*)pPrior; |
||
310 | // Debug.Assert(pPrior!=0 && nByte>0 ); |
||
311 | // nByte = ROUND8( nByte ); |
||
312 | // p = (sqlite3_int64*)pPrior; |
||
313 | // p--; |
||
314 | // p = realloc(p, nByte+8 ); |
||
315 | // if( p ){ |
||
316 | // p[0] = nByte; |
||
317 | // p++; |
||
318 | // } |
||
319 | // return (void*)p; |
||
320 | Array.Resize( ref pPrior, nByte ); |
||
321 | return pPrior; |
||
322 | } |
||
323 | #else |
||
324 | /* |
||
325 | ** No-op versions of all memory allocation routines |
||
326 | */ |
||
327 | static byte[] sqlite3MemMalloc(int nByte) { return new byte[nByte]; } |
||
328 | static int[] sqlite3MemMallocInt(int nInt) { return new int[nInt]; } |
||
329 | static Mem sqlite3MemMallocMem( Mem pMem) { return new Mem(); } |
||
330 | static void sqlite3MemFree( ref byte[] pPrior ) { pPrior = null; } |
||
331 | static void sqlite3MemFreeInt( ref int[] pPrior ) { pPrior = null; } |
||
332 | static void sqlite3MemFreeMem(ref Mem pPrior) { pPrior = null; } |
||
333 | static int sqlite3MemInit() { return SQLITE_OK; } |
||
334 | static void sqlite3MemShutdown() { } |
||
335 | static BtCursor sqlite3MemMallocBtCursor( BtCursor dummy ){return new BtCursor();} |
||
336 | static void sqlite3MemFreeBtCursor(ref BtCursor pPrior) { pPrior = null; } |
||
337 | #endif |
||
338 | |||
339 | static byte[] sqlite3MemRealloc( byte[] pPrior, int nByte ) |
||
340 | { |
||
341 | Array.Resize( ref pPrior, nByte ); |
||
342 | return pPrior; |
||
343 | } |
||
344 | |||
345 | /* |
||
346 | ** Report the allocated size of a prior return from xMalloc() |
||
347 | ** or xRealloc(). |
||
348 | */ |
||
349 | static int sqlite3MemSize( byte[] pPrior ) |
||
350 | { |
||
351 | // sqlite3_int64 p; |
||
352 | // if( pPrior==0 ) return 0; |
||
353 | // p = (sqlite3_int64*)pPrior; |
||
354 | // p--; |
||
355 | // return p[0]; |
||
356 | return pPrior == null ? 0 : (int)pPrior.Length; |
||
357 | } |
||
358 | |||
359 | /* |
||
360 | ** Round up a request size to the next valid allocation size. |
||
361 | */ |
||
362 | static int sqlite3MemRoundup( int n ) |
||
363 | { |
||
364 | return n;// ROUND8( n ); |
||
365 | } |
||
366 | |||
367 | /* |
||
368 | ** Initialize this module. |
||
369 | */ |
||
370 | static int sqlite3MemInit( object NotUsed ) |
||
371 | { |
||
372 | UNUSED_PARAMETER( NotUsed ); |
||
373 | if ( !sqlite3GlobalConfig.bMemstat ) |
||
374 | { |
||
375 | /* If memory status is enabled, then the malloc.c wrapper will already |
||
376 | ** hold the STATIC_MEM mutex when the routines here are invoked. */ |
||
377 | mem0.mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MEM ); |
||
378 | } |
||
379 | return SQLITE_OK; |
||
380 | } |
||
381 | |||
382 | /* |
||
383 | ** Deinitialize this module. |
||
384 | */ |
||
385 | static void sqlite3MemShutdown( object NotUsed ) |
||
386 | { |
||
387 | |||
388 | UNUSED_PARAMETER( NotUsed ); |
||
389 | return; |
||
390 | } |
||
391 | |||
392 | /* |
||
393 | ** This routine is the only routine in this file with external linkage. |
||
394 | ** |
||
395 | ** Populate the low-level memory allocation function pointers in |
||
396 | ** sqlite3GlobalConfig.m with pointers to the routines in this file. |
||
397 | */ |
||
398 | static void sqlite3MemSetDefault() |
||
399 | { |
||
400 | sqlite3_mem_methods defaultMethods = new sqlite3_mem_methods( |
||
401 | sqlite3MemMalloc, |
||
402 | sqlite3MemMallocInt, |
||
403 | sqlite3MemMallocMem, |
||
404 | sqlite3MemFree, |
||
405 | sqlite3MemFreeInt, |
||
406 | sqlite3MemFreeMem, |
||
407 | sqlite3MemRealloc, |
||
408 | sqlite3MemSize, |
||
409 | sqlite3MemRoundup, |
||
410 | (dxMemInit)sqlite3MemInit, |
||
411 | (dxMemShutdown)sqlite3MemShutdown, |
||
412 | |||
413 | ); |
||
414 | sqlite3_config( SQLITE_CONFIG_MALLOC, defaultMethods ); |
||
415 | } |
||
416 | |||
417 | static void sqlite3DbFree( sqlite3 db, ref int[] pPrior ) |
||
418 | { |
||
419 | if ( pPrior != null ) |
||
420 | sqlite3MemFreeInt( ref pPrior ); |
||
421 | } |
||
422 | static void sqlite3DbFree( sqlite3 db, ref Mem pPrior ) |
||
423 | { |
||
424 | if ( pPrior != null ) |
||
425 | sqlite3MemFreeMem( ref pPrior ); |
||
426 | } |
||
427 | static void sqlite3DbFree( sqlite3 db, ref Mem[] pPrior ) |
||
428 | { |
||
429 | if ( pPrior != null ) |
||
430 | for ( int i = 0; i < pPrior.Length; i++ ) |
||
431 | sqlite3MemFreeMem( ref pPrior[i] ); |
||
432 | } |
||
433 | static void sqlite3DbFree<T>( sqlite3 db, ref T pT ) where T : class |
||
434 | { |
||
435 | } |
||
436 | static void sqlite3DbFree( sqlite3 db, ref string pString ) |
||
437 | { |
||
438 | } |
||
439 | } |
||
440 | } |