Back to index

lightning-sunbird  0.9+nobinonly
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 #include "sqliteInt.h"
00016 #include "vdbeInt.h"
00017 
00018 /*
00019 ** Allocate a new FifoPage and return a pointer to it.  Return NULL if
00020 ** we run out of memory.  Leave space on the page for nEntry entries.
00021 */
00022 static FifoPage *allocatePage(int nEntry){
00023   FifoPage *pPage;
00024   if( nEntry>32767 ){
00025     nEntry = 32767;
00026   }
00027   pPage = sqliteMallocRaw( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
00028   if( pPage ){
00029     pPage->nSlot = nEntry;
00030     pPage->iWrite = 0;
00031     pPage->iRead = 0;
00032     pPage->pNext = 0;
00033   }
00034   return pPage;
00035 }
00036 
00037 /*
00038 ** Initialize a Fifo structure.
00039 */
00040 void sqlite3VdbeFifoInit(Fifo *pFifo){
00041   memset(pFifo, 0, sizeof(*pFifo));
00042 }
00043 
00044 /*
00045 ** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
00046 ** normally.   SQLITE_NOMEM is returned if we are unable to allocate
00047 ** memory.
00048 */
00049 int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
00050   FifoPage *pPage;
00051   pPage = pFifo->pLast;
00052   if( pPage==0 ){
00053     pPage = pFifo->pLast = pFifo->pFirst = allocatePage(20);
00054     if( pPage==0 ){
00055       return SQLITE_NOMEM;
00056     }
00057   }else if( pPage->iWrite>=pPage->nSlot ){
00058     pPage->pNext = allocatePage(pFifo->nEntry);
00059     if( pPage->pNext==0 ){
00060       return SQLITE_NOMEM;
00061     }
00062     pPage = pFifo->pLast = pPage->pNext;
00063   }
00064   pPage->aSlot[pPage->iWrite++] = val;
00065   pFifo->nEntry++;
00066   return SQLITE_OK;
00067 }
00068 
00069 /*
00070 ** Extract a single 64-bit integer value from the Fifo.  The integer
00071 ** extracted is the one least recently inserted.  If the Fifo is empty
00072 ** return SQLITE_DONE.
00073 */
00074 int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
00075   FifoPage *pPage;
00076   if( pFifo->nEntry==0 ){
00077     return SQLITE_DONE;
00078   }
00079   assert( pFifo->nEntry>0 );
00080   pPage = pFifo->pFirst;
00081   assert( pPage!=0 );
00082   assert( pPage->iWrite>pPage->iRead );
00083   assert( pPage->iWrite<=pPage->nSlot );
00084   assert( pPage->iRead<pPage->nSlot );
00085   assert( pPage->iRead>=0 );
00086   *pVal = pPage->aSlot[pPage->iRead++];
00087   pFifo->nEntry--;
00088   if( pPage->iRead>=pPage->iWrite ){
00089     pFifo->pFirst = pPage->pNext;
00090     sqliteFree(pPage);
00091     if( pFifo->nEntry==0 ){
00092       assert( pFifo->pLast==pPage );
00093       pFifo->pLast = 0;
00094     }else{
00095       assert( pFifo->pFirst!=0 );
00096     }
00097   }else{
00098     assert( pFifo->nEntry>0 );
00099   }
00100   return SQLITE_OK;
00101 }
00102 
00103 /*
00104 ** Delete all information from a Fifo object.   Free all memory held
00105 ** by the Fifo.
00106 */
00107 void sqlite3VdbeFifoClear(Fifo *pFifo){
00108   FifoPage *pPage, *pNextPage;
00109   for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
00110     pNextPage = pPage->pNext;
00111     sqliteFree(pPage);
00112   }
00113   sqlite3VdbeFifoInit(pFifo);
00114 }