Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Avoid attempting to reclaim memory from in-memory databases in sqlite3_release_memory(). (CVS 3812) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c20f7563c0ffa1df47df5464f1f1cc47 |
User & Date: | danielk1977 2007-04-05 13:12:14 |
Context
2007-04-05
| ||
14:29 | Use the MEMDB macro instead of OMIT_MEMORYDB in pager_recycle(). (CVS 3813) check-in: 97c51598 user: danielk1977 tags: trunk | |
13:12 | Avoid attempting to reclaim memory from in-memory databases in sqlite3_release_memory(). (CVS 3812) check-in: c20f7563 user: danielk1977 tags: trunk | |
11:54 | Add some assert() statements to pager.c. (CVS 3811) check-in: 973b2a5f user: danielk1977 tags: trunk | |
Changes
Changes to src/pager.c.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 .... 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 .... 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 .... 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 .... 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 |
** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.320 2007/04/05 11:54:43 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> ................................................................................ ** ** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It ** does not set the pPager->errCode variable. */ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){ PgHdr *pPg; *ppPg = 0; /* Find a page to recycle. Try to locate a page that does not ** require us to do an fsync() on the journal. */ pPg = pPager->pFirstSynced; /* If we could not find a page that does not require an fsync() ................................................................................ assert( pPg->nRef==0 ); /* Write the page to the database file if it is dirty. */ if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); assert( !MEMDB ); makeClean(pPg); pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); if( rc!=SQLITE_OK ){ return rc; } ................................................................................ */ for(i=0; i<=1; i++){ /* Loop through all the SQLite pagers opened by the current thread. */ for(p=pTsdro->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){ PgHdr *pPg; int rc; /* For each pager, try to free as many pages as possible (without ** calling fsync() if this is the first iteration of the outermost ** loop). */ while( SQLITE_OK==(rc = pager_recycle(p, i, &pPg)) && pPg) { /* We've found a page to free. At this point the page has been ................................................................................ /* ** Allocate or recycle space for a single page. */ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ int rc = SQLITE_OK; PgHdr *pPg; if( !(pPager->pFirstSynced && pPager->pFirstSynced->pgno==0) && ( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB || (pPager->pFirstSynced==0 && pPager->doNotSync) ) ){ /* Create a new page */ if( pPager->nPage>=pPager->nHash ){ pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); if( pPager->nHash==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; |
| > > < > > > > > > | | | |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 .... 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 .... 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 .... 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 .... 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 |
** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.321 2007/04/05 13:12:14 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> ................................................................................ ** ** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It ** does not set the pPager->errCode variable. */ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){ PgHdr *pPg; *ppPg = 0; assert(!MEMDB); /* Find a page to recycle. Try to locate a page that does not ** require us to do an fsync() on the journal. */ pPg = pPager->pFirstSynced; /* If we could not find a page that does not require an fsync() ................................................................................ assert( pPg->nRef==0 ); /* Write the page to the database file if it is dirty. */ if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); makeClean(pPg); pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); if( rc!=SQLITE_OK ){ return rc; } ................................................................................ */ for(i=0; i<=1; i++){ /* Loop through all the SQLite pagers opened by the current thread. */ for(p=pTsdro->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){ PgHdr *pPg; int rc; #ifndef SQLITE_OMIT_MEMORYDB if( p->memDb ){ continue; } #endif /* For each pager, try to free as many pages as possible (without ** calling fsync() if this is the first iteration of the outermost ** loop). */ while( SQLITE_OK==(rc = pager_recycle(p, i, &pPg)) && pPg) { /* We've found a page to free. At this point the page has been ................................................................................ /* ** Allocate or recycle space for a single page. */ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ int rc = SQLITE_OK; PgHdr *pPg; if( MEMDB || (!(pPager->pFirstSynced && pPager->pFirstSynced->pgno==0) && ( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || (pPager->pFirstSynced==0 && pPager->doNotSync) )) ){ /* Create a new page */ if( pPager->nPage>=pPager->nHash ){ pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); if( pPager->nHash==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; |
Changes to test/malloc5.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
217
218
219
220
221
222
223
224
225
226
227
|
# May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains test cases focused on the two memory-management APIs, # sqlite3_soft_heap_limit() and sqlite3_release_memory(). # # $Id: malloc5.test,v 1.8 2007/04/02 05:07:48 danielk1977 Exp $ #--------------------------------------------------------------------------- # NOTES ON EXPECTED BEHAVIOUR # #--------------------------------------------------------------------------- ................................................................................ execsql { SELECT count(*), sum(a), sum(b) FROM abc; } } [list 20000 [expr int(20000.0 * 4999.5)] [expr int(20000.0 * 4999.5)]] # Restore the soft heap limit. sqlite3_soft_heap_limit $::soft_limit finish_test catch {db close} |
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
# May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains test cases focused on the two memory-management APIs, # sqlite3_soft_heap_limit() and sqlite3_release_memory(). # # $Id: malloc5.test,v 1.9 2007/04/05 13:12:14 danielk1977 Exp $ #--------------------------------------------------------------------------- # NOTES ON EXPECTED BEHAVIOUR # #--------------------------------------------------------------------------- ................................................................................ execsql { SELECT count(*), sum(a), sum(b) FROM abc; } } [list 20000 [expr int(20000.0 * 4999.5)] [expr int(20000.0 * 4999.5)]] # Restore the soft heap limit. sqlite3_soft_heap_limit $::soft_limit # Test that there are no problems calling sqlite3_release_memory when # there are open in-memory databases. # # At one point these tests would cause a seg-fault. # do_test malloc5-5.1 { db close sqlite3 db :memory: execsql { BEGIN; CREATE TABLE abc(a, b, c); INSERT INTO abc VALUES('abcdefghi', 1234567890, NULL); INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } sqlite3_release_memory } 0 do_test malloc5-5.1 { sqlite3_soft_heap_limit 5000 execsql { COMMIT; PRAGMA temp_store = memory; SELECT * FROM abc ORDER BY a; } expr 1 } {1} sqlite3_soft_heap_limit $::soft_limit finish_test catch {db close} |