persistentstorage/sqlite3api/SQLite/vdbefifo.c
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 /*
       
     2 ** 2005 June 16
       
     3 **
       
     4 ** The author disclaims copyright to this source code.  In place of
       
     5 ** a legal notice, here is a blessing:
       
     6 **
       
     7 **    May you do good and not evil.
       
     8 **    May you find forgiveness for yourself and forgive others.
       
     9 **    May you share freely, never taking more than you give.
       
    10 **
       
    11 *************************************************************************
       
    12 ** This file implements a FIFO queue of rowids used for processing
       
    13 ** UPDATE and DELETE statements.
       
    14 **
       
    15 ** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
       
    16 */
       
    17 #include "sqliteInt.h"
       
    18 #include "vdbeInt.h"
       
    19 
       
    20 /*
       
    21 ** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial
       
    22 ** number of entries in a fifo page and the maximum number of
       
    23 ** entries in a fifo page.
       
    24 */
       
    25 #define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1)
       
    26 #ifdef SQLITE_MALLOC_SOFT_LIMIT
       
    27 # define FIFOSIZE_MAX   (((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1)
       
    28 #else
       
    29 # define FIFOSIZE_MAX   (((262144-sizeof(FifoPage))/8)+1)
       
    30 #endif
       
    31 
       
    32 /*
       
    33 ** Allocate a new FifoPage and return a pointer to it.  Return NULL if
       
    34 ** we run out of memory.  Leave space on the page for nEntry entries.
       
    35 */
       
    36 static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
       
    37   FifoPage *pPage;
       
    38   if( nEntry>FIFOSIZE_MAX ){
       
    39     nEntry = FIFOSIZE_MAX;
       
    40   }
       
    41   pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
       
    42   if( pPage ){
       
    43     pPage->nSlot = nEntry;
       
    44     pPage->iWrite = 0;
       
    45     pPage->iRead = 0;
       
    46     pPage->pNext = 0;
       
    47   }
       
    48   return pPage;
       
    49 }
       
    50 
       
    51 /*
       
    52 ** Initialize a Fifo structure.
       
    53 */
       
    54 void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
       
    55   memset(pFifo, 0, sizeof(*pFifo));
       
    56   pFifo->db = db;
       
    57 }
       
    58 
       
    59 /*
       
    60 ** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
       
    61 ** normally.   SQLITE_NOMEM is returned if we are unable to allocate
       
    62 ** memory.
       
    63 */
       
    64 int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
       
    65   FifoPage *pPage;
       
    66   pPage = pFifo->pLast;
       
    67   if( pPage==0 ){
       
    68     pPage = pFifo->pLast = pFifo->pFirst =
       
    69          allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
       
    70     if( pPage==0 ){
       
    71       return SQLITE_NOMEM;
       
    72     }
       
    73   }else if( pPage->iWrite>=pPage->nSlot ){
       
    74     pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
       
    75     if( pPage->pNext==0 ){
       
    76       return SQLITE_NOMEM;
       
    77     }
       
    78     pPage = pFifo->pLast = pPage->pNext;
       
    79   }
       
    80   pPage->aSlot[pPage->iWrite++] = val;
       
    81   pFifo->nEntry++;
       
    82   return SQLITE_OK;
       
    83 }
       
    84 
       
    85 /*
       
    86 ** Extract a single 64-bit integer value from the Fifo.  The integer
       
    87 ** extracted is the one least recently inserted.  If the Fifo is empty
       
    88 ** return SQLITE_DONE.
       
    89 */
       
    90 int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
       
    91   FifoPage *pPage;
       
    92   if( pFifo->nEntry==0 ){
       
    93     return SQLITE_DONE;
       
    94   }
       
    95   assert( pFifo->nEntry>0 );
       
    96   pPage = pFifo->pFirst;
       
    97   assert( pPage!=0 );
       
    98   assert( pPage->iWrite>pPage->iRead );
       
    99   assert( pPage->iWrite<=pPage->nSlot );
       
   100   assert( pPage->iRead<pPage->nSlot );
       
   101   assert( pPage->iRead>=0 );
       
   102   *pVal = pPage->aSlot[pPage->iRead++];
       
   103   pFifo->nEntry--;
       
   104   if( pPage->iRead>=pPage->iWrite ){
       
   105     pFifo->pFirst = pPage->pNext;
       
   106     sqlite3DbFree(pFifo->db, pPage);
       
   107     if( pFifo->nEntry==0 ){
       
   108       assert( pFifo->pLast==pPage );
       
   109       pFifo->pLast = 0;
       
   110     }else{
       
   111       assert( pFifo->pFirst!=0 );
       
   112     }
       
   113   }else{
       
   114     assert( pFifo->nEntry>0 );
       
   115   }
       
   116   return SQLITE_OK;
       
   117 }
       
   118 
       
   119 /*
       
   120 ** Delete all information from a Fifo object.   Free all memory held
       
   121 ** by the Fifo.
       
   122 */
       
   123 void sqlite3VdbeFifoClear(Fifo *pFifo){
       
   124   FifoPage *pPage, *pNextPage;
       
   125   for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
       
   126     pNextPage = pPage->pNext;
       
   127     sqlite3DbFree(pFifo->db, pPage);
       
   128   }
       
   129   sqlite3VdbeFifoInit(pFifo, pFifo->db);
       
   130 }