extensions/sqlite/sqlite-source/vdbefifo.c
changeset 1952 b7aa2b626807
     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 +}