vdbefifo.c

Go to the documentation of this file.
00001 /*
00002 ** 2005 June 16
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file implements a FIFO queue of rowids used for processing
00013 ** UPDATE and DELETE statements.
00014 **
00015 ** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
00016 */
00017 #include "sqliteInt.h"
00018 #include "vdbeInt.h"
00019 
00020 /*
00021 ** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial
00022 ** number of entries in a fifo page and the maximum number of
00023 ** entries in a fifo page.
00024 */
00025 #define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1)
00026 #ifdef SQLITE_MALLOC_SOFT_LIMIT
00027 # define FIFOSIZE_MAX   (((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1)
00028 #else
00029 # define FIFOSIZE_MAX   (((262144-sizeof(FifoPage))/8)+1)
00030 #endif
00031 
00032 /*
00033 ** Allocate a new FifoPage and return a pointer to it.  Return NULL if
00034 ** we run out of memory.  Leave space on the page for nEntry entries.
00035 */
00036 static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
00037   FifoPage *pPage;
00038   if( nEntry>FIFOSIZE_MAX ){
00039     nEntry = FIFOSIZE_MAX;
00040   }
00041   pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
00042   if( pPage ){
00043     pPage->nSlot = nEntry;
00044     pPage->iWrite = 0;
00045     pPage->iRead = 0;
00046     pPage->pNext = 0;
00047   }
00048   return pPage;
00049 }
00050 
00051 /*
00052 ** Initialize a Fifo structure.
00053 */
00054 void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
00055   memset(pFifo, 0, sizeof(*pFifo));
00056   pFifo->db = db;
00057 }
00058 
00059 /*
00060 ** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
00061 ** normally.   SQLITE_NOMEM is returned if we are unable to allocate
00062 ** memory.
00063 */
00064 int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
00065   FifoPage *pPage;
00066   pPage = pFifo->pLast;
00067   if( pPage==0 ){
00068     pPage = pFifo->pLast = pFifo->pFirst =
00069          allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
00070     if( pPage==0 ){
00071       return SQLITE_NOMEM;
00072     }
00073   }else if( pPage->iWrite>=pPage->nSlot ){
00074     pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
00075     if( pPage->pNext==0 ){
00076       return SQLITE_NOMEM;
00077     }
00078     pPage = pFifo->pLast = pPage->pNext;
00079   }
00080   pPage->aSlot[pPage->iWrite++] = val;
00081   pFifo->nEntry++;
00082   return SQLITE_OK;
00083 }
00084 
00085 /*
00086 ** Extract a single 64-bit integer value from the Fifo.  The integer
00087 ** extracted is the one least recently inserted.  If the Fifo is empty
00088 ** return SQLITE_DONE.
00089 */
00090 int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
00091   FifoPage *pPage;
00092   if( pFifo->nEntry==0 ){
00093     return SQLITE_DONE;
00094   }
00095   assert( pFifo->nEntry>0 );
00096   pPage = pFifo->pFirst;
00097   assert( pPage!=0 );
00098   assert( pPage->iWrite>pPage->iRead );
00099   assert( pPage->iWrite<=pPage->nSlot );
00100   assert( pPage->iRead<pPage->nSlot );
00101   assert( pPage->iRead>=0 );
00102   *pVal = pPage->aSlot[pPage->iRead++];
00103   pFifo->nEntry--;
00104   if( pPage->iRead>=pPage->iWrite ){
00105     pFifo->pFirst = pPage->pNext;
00106     sqlite3DbFree(pFifo->db, pPage);
00107     if( pFifo->nEntry==0 ){
00108       assert( pFifo->pLast==pPage );
00109       pFifo->pLast = 0;
00110     }else{
00111       assert( pFifo->pFirst!=0 );
00112     }
00113   }else{
00114     assert( pFifo->nEntry>0 );
00115   }
00116   return SQLITE_OK;
00117 }
00118 
00119 /*
00120 ** Delete all information from a Fifo object.   Free all memory held
00121 ** by the Fifo.
00122 */
00123 void sqlite3VdbeFifoClear(Fifo *pFifo){
00124   FifoPage *pPage, *pNextPage;
00125   for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
00126     pNextPage = pPage->pNext;
00127     sqlite3DbFree(pFifo->db, pPage);
00128   }
00129   sqlite3VdbeFifoInit(pFifo, pFifo->db);
00130 }

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:57 2011 by Doxygen 1.6.1