1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/extensions/sqlite/sqlite-source/vdbefifo.c Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,114 @@
1.4 +/*
1.5 +** 2005 June 16
1.6 +**
1.7 +** The author disclaims copyright to this source code. In place of
1.8 +** a legal notice, here is a blessing:
1.9 +**
1.10 +** May you do good and not evil.
1.11 +** May you find forgiveness for yourself and forgive others.
1.12 +** May you share freely, never taking more than you give.
1.13 +**
1.14 +*************************************************************************
1.15 +** This file implements a FIFO queue of rowids used for processing
1.16 +** UPDATE and DELETE statements.
1.17 +*/
1.18 +#include "sqliteInt.h"
1.19 +#include "vdbeInt.h"
1.20 +
1.21 +/*
1.22 +** Allocate a new FifoPage and return a pointer to it. Return NULL if
1.23 +** we run out of memory. Leave space on the page for nEntry entries.
1.24 +*/
1.25 +static FifoPage *allocateFifoPage(int nEntry){
1.26 + FifoPage *pPage;
1.27 + if( nEntry>32767 ){
1.28 + nEntry = 32767;
1.29 + }
1.30 + pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
1.31 + if( pPage ){
1.32 + pPage->nSlot = nEntry;
1.33 + pPage->iWrite = 0;
1.34 + pPage->iRead = 0;
1.35 + pPage->pNext = 0;
1.36 + }
1.37 + return pPage;
1.38 +}
1.39 +
1.40 +/*
1.41 +** Initialize a Fifo structure.
1.42 +*/
1.43 +void sqlite3VdbeFifoInit(Fifo *pFifo){
1.44 + memset(pFifo, 0, sizeof(*pFifo));
1.45 +}
1.46 +
1.47 +/*
1.48 +** Push a single 64-bit integer value into the Fifo. Return SQLITE_OK
1.49 +** normally. SQLITE_NOMEM is returned if we are unable to allocate
1.50 +** memory.
1.51 +*/
1.52 +int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
1.53 + FifoPage *pPage;
1.54 + pPage = pFifo->pLast;
1.55 + if( pPage==0 ){
1.56 + pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(20);
1.57 + if( pPage==0 ){
1.58 + return SQLITE_NOMEM;
1.59 + }
1.60 + }else if( pPage->iWrite>=pPage->nSlot ){
1.61 + pPage->pNext = allocateFifoPage(pFifo->nEntry);
1.62 + if( pPage->pNext==0 ){
1.63 + return SQLITE_NOMEM;
1.64 + }
1.65 + pPage = pFifo->pLast = pPage->pNext;
1.66 + }
1.67 + pPage->aSlot[pPage->iWrite++] = val;
1.68 + pFifo->nEntry++;
1.69 + return SQLITE_OK;
1.70 +}
1.71 +
1.72 +/*
1.73 +** Extract a single 64-bit integer value from the Fifo. The integer
1.74 +** extracted is the one least recently inserted. If the Fifo is empty
1.75 +** return SQLITE_DONE.
1.76 +*/
1.77 +int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
1.78 + FifoPage *pPage;
1.79 + if( pFifo->nEntry==0 ){
1.80 + return SQLITE_DONE;
1.81 + }
1.82 + assert( pFifo->nEntry>0 );
1.83 + pPage = pFifo->pFirst;
1.84 + assert( pPage!=0 );
1.85 + assert( pPage->iWrite>pPage->iRead );
1.86 + assert( pPage->iWrite<=pPage->nSlot );
1.87 + assert( pPage->iRead<pPage->nSlot );
1.88 + assert( pPage->iRead>=0 );
1.89 + *pVal = pPage->aSlot[pPage->iRead++];
1.90 + pFifo->nEntry--;
1.91 + if( pPage->iRead>=pPage->iWrite ){
1.92 + pFifo->pFirst = pPage->pNext;
1.93 + sqlite3_free(pPage);
1.94 + if( pFifo->nEntry==0 ){
1.95 + assert( pFifo->pLast==pPage );
1.96 + pFifo->pLast = 0;
1.97 + }else{
1.98 + assert( pFifo->pFirst!=0 );
1.99 + }
1.100 + }else{
1.101 + assert( pFifo->nEntry>0 );
1.102 + }
1.103 + return SQLITE_OK;
1.104 +}
1.105 +
1.106 +/*
1.107 +** Delete all information from a Fifo object. Free all memory held
1.108 +** by the Fifo.
1.109 +*/
1.110 +void sqlite3VdbeFifoClear(Fifo *pFifo){
1.111 + FifoPage *pPage, *pNextPage;
1.112 + for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
1.113 + pNextPage = pPage->pNext;
1.114 + sqlite3_free(pPage);
1.115 + }
1.116 + sqlite3VdbeFifoInit(pFifo);
1.117 +}