/ Check-in [fb1b955d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Code simplifications in support of structural testing. (CVS 6900)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:fb1b955dda5105025ef199880afa871e44331d65
User & Date: drh 2009-07-17 11:44:07
Context
2009-07-17
14:37
Skip all tests in tableapi.test if SQLITE_OMIT_GET_TABLE defined. Ticket #3975. (CVS 6901) check-in: 0219a543 user: shane tags: trunk
11:44
Code simplifications in support of structural testing. (CVS 6900) check-in: fb1b955d user: drh tags: trunk
2009-07-16
18:21
Code simplifications and comment improvements in support of structural coverage testing. (CVS 6899) check-in: 94525179 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btmutex.c.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
304
305
306
307
308
309
310




311
312
313
314
315
316
317
318
319
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: btmutex.c,v 1.15 2009/04/10 12:55:17 danielk1977 Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c.  But btree.c is getting too
** big and we want to break it down some.  This packaged seemed like
** a good breakout.
*/
#include "btreeInt.h"
................................................................................
    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( !p->locked || p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );





    p->wantToLock++;
    if( !p->locked && p->sharable ){
      lockBtreeMutex(p);
    }
  }
}

/*
** Leave the mutex of every btree in the group.
................................................................................
*/
void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
  int i;
  for(i=0; i<pArray->nMutex; i++){
    Btree *p = pArray->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( p->locked || !p->sharable );
    assert( p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );

    p->wantToLock--;
    if( p->wantToLock==0 && p->locked ){
      unlockBtreeMutex(p);
    }
  }
}

#else
void sqlite3BtreeEnter(Btree *p){







|







 







>
>
>
>

|







 







|






|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: btmutex.c,v 1.16 2009/07/17 11:44:07 drh Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c.  But btree.c is getting too
** big and we want to break it down some.  This packaged seemed like
** a good breakout.
*/
#include "btreeInt.h"
................................................................................
    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( !p->locked || p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );

    /* The Btree is sharable because only sharable Btrees are entered
    ** into the array in the first place. */
    assert( p->sharable );

    p->wantToLock++;
    if( !p->locked ){
      lockBtreeMutex(p);
    }
  }
}

/*
** Leave the mutex of every btree in the group.
................................................................................
*/
void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
  int i;
  for(i=0; i<pArray->nMutex; i++){
    Btree *p = pArray->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( p->locked );
    assert( p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );

    p->wantToLock--;
    if( p->wantToLock==0 ){
      unlockBtreeMutex(p);
    }
  }
}

#else
void sqlite3BtreeEnter(Btree *p){

Changes to src/malloc.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
** $Id: malloc.c,v 1.65 2009/07/16 18:21:18 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>

/*
** This routine runs when the memory allocator sees that the
** total memory allocation is about to exceed the soft heap
................................................................................
** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(void *p){
  return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
  assert( db==0 || sqlite3_mutex_held(db->mutex) );
  if( p==0 ){
    return 0;
  }else if( isLookaside(db, p) ){
    return db->lookaside.sz;
  }else{
    return sqlite3GlobalConfig.m.xSize(p);
  }
}

/*







|







 







<
<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
419
420
421
422
423
424
425


426
427
428
429
430
431
432
433
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
** $Id: malloc.c,v 1.66 2009/07/17 11:44:07 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>

/*
** This routine runs when the memory allocator sees that the
** total memory allocation is about to exceed the soft heap
................................................................................
** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(void *p){
  return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
  assert( db==0 || sqlite3_mutex_held(db->mutex) );


  if( isLookaside(db, p) ){
    return db->lookaside.sz;
  }else{
    return sqlite3GlobalConfig.m.xSize(p);
  }
}

/*

Changes to src/pcache1.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
214
215
216
217
218
219
220




221
222
223

224
225
226
227
228
229
230
...
467
468
469
470
471
472
473
474







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
509
510
511
512
513
514
515

516
517
518
519
520
521
522
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
**
** This file implements the default page cache implementation (the
** sqlite3_pcache interface). It also contains part of the implementation
** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
** If the default page cache implementation is overriden, then neither of
** these two features are available.
**
** @(#) $Id: pcache1.c,v 1.18 2009/07/16 18:21:18 drh Exp $
*/

#include "sqliteInt.h"

typedef struct PCache1 PCache1;
typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
................................................................................
    p = 0;
  }
  return p;
}

/*
** Free a page object allocated by pcache1AllocPage().




*/
static void pcache1FreePage(PgHdr1 *p){
  if( p ){

    if( p->pCache->bPurgeable ){
      pcache1.nCurrentPage--;
    }
    pcache1Free(PGHDR1_TO_PAGE(p));
  }
}

................................................................................

/*
** Implementation of the sqlite3_pcache.xFetch method. 
**
** Fetch a page by key value.
**
** Whether or not a new page may be allocated by this function depends on
** the value of the createFlag argument.







**
** There are three different approaches to obtaining space for a page,
** depending on the value of parameter createFlag (which may be 0, 1 or 2).
**
**   1. Regardless of the value of createFlag, the cache is searched for a 
**      copy of the requested page. If one is found, it is returned.
**
**   2. If createFlag==0 and the page is not already in the cache, NULL is
**      returned.
**
**   3. If createFlag is 1, the cache is marked as purgeable and the page is 
**      not already in the cache, and if either of the following are true, 
**      return NULL:
**
**       (a) the number of pages pinned by the cache is greater than
**           PCache1.nMax, or
**       (b) the number of pages pinned by the cache is greater than
**           the sum of nMax for all purgeable caches, less the sum of 
**           nMin for all other purgeable caches. 
**
................................................................................
**   5. Otherwise, allocate and return a new page buffer.
*/
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
  unsigned int nPinned;
  PCache1 *pCache = (PCache1 *)p;
  PgHdr1 *pPage = 0;


  pcache1EnterMutex();
  if( createFlag==1 ) sqlite3BeginBenignMalloc();

  /* Search the hash table for an existing entry. */
  if( pCache->nHash>0 ){
    unsigned int h = iKey % pCache->nHash;
    for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
................................................................................
  if( pPage || createFlag==0 ){
    pcache1PinPage(pPage);
    goto fetch_out;
  }

  /* Step 3 of header comment. */
  nPinned = pCache->nPage - pCache->nRecyclable;
  if( createFlag==1 && pCache->bPurgeable && (
        nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
     || nPinned>=(pCache->nMax * 9 / 10)
  )){
    goto fetch_out;
  }

  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){







|







 







>
>
>
>


<
>







 







|
>
>
>
>
>
>
>










|
|
<







 







>







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
214
215
216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
...
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
...
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
**
** This file implements the default page cache implementation (the
** sqlite3_pcache interface). It also contains part of the implementation
** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
** If the default page cache implementation is overriden, then neither of
** these two features are available.
**
** @(#) $Id: pcache1.c,v 1.19 2009/07/17 11:44:07 drh Exp $
*/

#include "sqliteInt.h"

typedef struct PCache1 PCache1;
typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
................................................................................
    p = 0;
  }
  return p;
}

/*
** Free a page object allocated by pcache1AllocPage().
**
** The pointer is allowed to be NULL, which is prudent.  But it turns out
** that the current implementation happens to never call this routine
** with a NULL pointer, so we mark the NULL test with ALWAYS().
*/
static void pcache1FreePage(PgHdr1 *p){

  if( ALWAYS(p) ){
    if( p->pCache->bPurgeable ){
      pcache1.nCurrentPage--;
    }
    pcache1Free(PGHDR1_TO_PAGE(p));
  }
}

................................................................................

/*
** Implementation of the sqlite3_pcache.xFetch method. 
**
** Fetch a page by key value.
**
** Whether or not a new page may be allocated by this function depends on
** the value of the createFlag argument.  0 means do not allocate a new
** page.  1 means allocate a new page if space is easily available.  2 
** means to try really hard to allocate a new page.
**
** For a non-purgeable cache (a cache used as the storage for an in-memory
** database) there is really no difference between createFlag 1 and 2.  So
** the calling function (pcache.c) will never have a createFlag of 1 on
** a non-purgable cache.
**
** There are three different approaches to obtaining space for a page,
** depending on the value of parameter createFlag (which may be 0, 1 or 2).
**
**   1. Regardless of the value of createFlag, the cache is searched for a 
**      copy of the requested page. If one is found, it is returned.
**
**   2. If createFlag==0 and the page is not already in the cache, NULL is
**      returned.
**
**   3. If createFlag is 1, and the page is not already in the cache,
**      and if either of the following are true, return NULL:

**
**       (a) the number of pages pinned by the cache is greater than
**           PCache1.nMax, or
**       (b) the number of pages pinned by the cache is greater than
**           the sum of nMax for all purgeable caches, less the sum of 
**           nMin for all other purgeable caches. 
**
................................................................................
**   5. Otherwise, allocate and return a new page buffer.
*/
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
  unsigned int nPinned;
  PCache1 *pCache = (PCache1 *)p;
  PgHdr1 *pPage = 0;

  assert( pCache->bPurgeable || createFlag!=1 );
  pcache1EnterMutex();
  if( createFlag==1 ) sqlite3BeginBenignMalloc();

  /* Search the hash table for an existing entry. */
  if( pCache->nHash>0 ){
    unsigned int h = iKey % pCache->nHash;
    for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
................................................................................
  if( pPage || createFlag==0 ){
    pcache1PinPage(pPage);
    goto fetch_out;
  }

  /* Step 3 of header comment. */
  nPinned = pCache->nPage - pCache->nRecyclable;
  if( createFlag==1 && (
        nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
     || nPinned>=(pCache->nMax * 9 / 10)
  )){
    goto fetch_out;
  }

  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){