SQLite

Check-in [cf48ad8353]
Login

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

Overview
Comment:Combine two malloc calls in vdbesort.c.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | merge-sort
Files: files | file ages | folders
SHA1: cf48ad8353e28339d00f448bb729e10a7f2aad72
User & Date: dan 2011-09-02 18:03:16.975
Context
2011-09-02
21:42
Remove some dead code. Fix a faulty assert(). Improve some variable names. (check-in: a9a64592cf user: drh tags: merge-sort)
18:03
Combine two malloc calls in vdbesort.c. (check-in: cf48ad8353 user: dan tags: merge-sort)
15:41
Reduce the number of malloc() calls made when creating an index on more than 2 columns. (check-in: 065b0c9858 user: dan tags: merge-sort)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
  }
  return rc;  
}
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  BtShared *pBt = p->pBt;
  int rc;
  sqlite3BtreeEnter(p);
  if( (pBt->openFlags&BTREE_SINGLE) ){
    pBt->nPage = 0;
    sqlite3PagerTruncateImage(pBt->pPager, 1);
    rc = newDatabase(pBt);
  }else{
    rc = btreeDropTable(p, iTable, piMoved);
  }
  sqlite3BtreeLeave(p);
  return rc;
}


/*
** This function may only be called if the b-tree connection already







<
<
<
<
<
|
<







7284
7285
7286
7287
7288
7289
7290





7291

7292
7293
7294
7295
7296
7297
7298
  }
  return rc;  
}
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  BtShared *pBt = p->pBt;
  int rc;
  sqlite3BtreeEnter(p);





  rc = btreeDropTable(p, iTable, piMoved);

  sqlite3BtreeLeave(p);
  return rc;
}


/*
** This function may only be called if the b-tree connection already
Changes to src/vdbesort.c.
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
**     aTree[] = { X, 0   0, 6    0, 3, 5, 6 }
**
** In other words, each time we advance to the next sorter element, log2(N)
** key comparison operations are required, where N is the number of segments
** being merged (rounded up to the next power of 2).
*/
struct VdbeSorter {
  int nInMemory;                  /* Current size of b-tree contents as PMA */
  int nTree;                      /* Used size of aTree/aIter (power of 2) */
  VdbeSorterIter *aIter;          /* Array of iterators to merge */
  int *aTree;                     /* Current state of incremental merge */
  i64 iWriteOff;                  /* Current write offset within file pTemp1 */
  i64 iReadOff;                   /* Current read offset within file pTemp1 */
  sqlite3_file *pTemp1;           /* PMA file 1 */
  int nPMA;                       /* Number of PMAs stored in pTemp1 */







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
**     aTree[] = { X, 0   0, 6    0, 3, 5, 6 }
**
** In other words, each time we advance to the next sorter element, log2(N)
** key comparison operations are required, where N is the number of segments
** being merged (rounded up to the next power of 2).
*/
struct VdbeSorter {
  int nInMemory;                  /* Current size of pRecord list as PMA */
  int nTree;                      /* Used size of aTree/aIter (power of 2) */
  VdbeSorterIter *aIter;          /* Array of iterators to merge */
  int *aTree;                     /* Current state of incremental merge */
  i64 iWriteOff;                  /* Current write offset within file pTemp1 */
  i64 iReadOff;                   /* Current read offset within file pTemp1 */
  sqlite3_file *pTemp1;           /* PMA file 1 */
  int nPMA;                       /* Number of PMAs stored in pTemp1 */
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
** Free the list of sorted records starting at pRecord.
*/
static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
  SorterRecord *p;
  SorterRecord *pNext;
  for(p=pRecord; p; p=pNext){
    pNext = p->pNext;
    sqlite3DbFree(db, p->pVal);
    sqlite3DbFree(db, p);
  }
}

/*
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/







<







418
419
420
421
422
423
424

425
426
427
428
429
430
431
** Free the list of sorted records starting at pRecord.
*/
static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
  SorterRecord *p;
  SorterRecord *pNext;
  for(p=pRecord; p; p=pNext){
    pNext = p->pNext;

    sqlite3DbFree(db, p);
  }
}

/*
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
      rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff);

      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff);
        iOff += p->nVal;
      }

      sqlite3DbFree(db, p->pVal);
      sqlite3DbFree(db, p);
    }

    /* This assert verifies that unless an error has occurred, the size of 
    ** the PMA on disk is the same as the expected size stored in
    ** pSorter->nInMemory. */ 
    assert( rc!=SQLITE_OK || pSorter->nInMemory==(







<







625
626
627
628
629
630
631

632
633
634
635
636
637
638
      rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff);

      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff);
        iOff += p->nVal;
      }


      sqlite3DbFree(db, p);
    }

    /* This assert verifies that unless an error has occurred, the size of 
    ** the PMA on disk is the same as the expected size stored in
    ** pSorter->nInMemory. */ 
    assert( rc!=SQLITE_OK || pSorter->nInMemory==(
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
*/
int sqlite3VdbeSorterWrite(
  sqlite3 *db,                    /* Database handle */
  VdbeCursor *pCsr,               /* Sorter cursor */
  Mem *pVal                       /* Memory cell containing record */
){
  VdbeSorter *pSorter = pCsr->pSorter;
  int rc;
  SorterRecord *pNew;

  assert( pSorter );
  pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n;

  pNew = (SorterRecord *)sqlite3DbMallocZero(db, sizeof(SorterRecord));
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3VdbeMemMakeWriteable(pVal);
    if( rc==SQLITE_OK ){
      pNew->pVal = pVal->z;

      pNew->nVal = pVal->n;
      pVal->zMalloc = 0;
      sqlite3VdbeMemSetNull(pVal);
      pNew->pNext = pSorter->pRecord;
      pSorter->pRecord = pNew;
    }else{
      sqlite3DbFree(db, pNew);
      rc = SQLITE_NOMEM;
    }
  }

  /* See if the contents of the sorter should now be written out. They
  ** are written out when either of the following are true:
  **
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * cache-size), or







|
|




|



<
<
|
>
|
<
<
|
|
<
<
<
<







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667


668
669
670


671
672




673
674
675
676
677
678
679
*/
int sqlite3VdbeSorterWrite(
  sqlite3 *db,                    /* Database handle */
  VdbeCursor *pCsr,               /* Sorter cursor */
  Mem *pVal                       /* Memory cell containing record */
){
  VdbeSorter *pSorter = pCsr->pSorter;
  int rc = SQLITE_OK;             /* Return Code */
  SorterRecord *pNew;             /* New list element */

  assert( pSorter );
  pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n;

  pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord));
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
  }else{


    pNew->pVal = (void *)&pNew[1];
    memcpy(pNew->pVal, pVal->z, pVal->n);
    pNew->nVal = pVal->n;


    pNew->pNext = pSorter->pRecord;
    pSorter->pRecord = pNew;




  }

  /* See if the contents of the sorter should now be written out. They
  ** are written out when either of the following are true:
  **
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * cache-size), or