1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/SQLite/vdbefifo.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,130 @@
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 +** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
1.19 +*/
1.20 +#include "sqliteInt.h"
1.21 +#include "vdbeInt.h"
1.22 +
1.23 +/*
1.24 +** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial
1.25 +** number of entries in a fifo page and the maximum number of
1.26 +** entries in a fifo page.
1.27 +*/
1.28 +#define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1)
1.29 +#ifdef SQLITE_MALLOC_SOFT_LIMIT
1.30 +# define FIFOSIZE_MAX (((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1)
1.31 +#else
1.32 +# define FIFOSIZE_MAX (((262144-sizeof(FifoPage))/8)+1)
1.33 +#endif
1.34 +
1.35 +/*
1.36 +** Allocate a new FifoPage and return a pointer to it. Return NULL if
1.37 +** we run out of memory. Leave space on the page for nEntry entries.
1.38 +*/
1.39 +static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
1.40 + FifoPage *pPage;
1.41 + if( nEntry>FIFOSIZE_MAX ){
1.42 + nEntry = FIFOSIZE_MAX;
1.43 + }
1.44 + pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
1.45 + if( pPage ){
1.46 + pPage->nSlot = nEntry;
1.47 + pPage->iWrite = 0;
1.48 + pPage->iRead = 0;
1.49 + pPage->pNext = 0;
1.50 + }
1.51 + return pPage;
1.52 +}
1.53 +
1.54 +/*
1.55 +** Initialize a Fifo structure.
1.56 +*/
1.57 +void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
1.58 + memset(pFifo, 0, sizeof(*pFifo));
1.59 + pFifo->db = db;
1.60 +}
1.61 +
1.62 +/*
1.63 +** Push a single 64-bit integer value into the Fifo. Return SQLITE_OK
1.64 +** normally. SQLITE_NOMEM is returned if we are unable to allocate
1.65 +** memory.
1.66 +*/
1.67 +int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
1.68 + FifoPage *pPage;
1.69 + pPage = pFifo->pLast;
1.70 + if( pPage==0 ){
1.71 + pPage = pFifo->pLast = pFifo->pFirst =
1.72 + allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
1.73 + if( pPage==0 ){
1.74 + return SQLITE_NOMEM;
1.75 + }
1.76 + }else if( pPage->iWrite>=pPage->nSlot ){
1.77 + pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
1.78 + if( pPage->pNext==0 ){
1.79 + return SQLITE_NOMEM;
1.80 + }
1.81 + pPage = pFifo->pLast = pPage->pNext;
1.82 + }
1.83 + pPage->aSlot[pPage->iWrite++] = val;
1.84 + pFifo->nEntry++;
1.85 + return SQLITE_OK;
1.86 +}
1.87 +
1.88 +/*
1.89 +** Extract a single 64-bit integer value from the Fifo. The integer
1.90 +** extracted is the one least recently inserted. If the Fifo is empty
1.91 +** return SQLITE_DONE.
1.92 +*/
1.93 +int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
1.94 + FifoPage *pPage;
1.95 + if( pFifo->nEntry==0 ){
1.96 + return SQLITE_DONE;
1.97 + }
1.98 + assert( pFifo->nEntry>0 );
1.99 + pPage = pFifo->pFirst;
1.100 + assert( pPage!=0 );
1.101 + assert( pPage->iWrite>pPage->iRead );
1.102 + assert( pPage->iWrite<=pPage->nSlot );
1.103 + assert( pPage->iRead<pPage->nSlot );
1.104 + assert( pPage->iRead>=0 );
1.105 + *pVal = pPage->aSlot[pPage->iRead++];
1.106 + pFifo->nEntry--;
1.107 + if( pPage->iRead>=pPage->iWrite ){
1.108 + pFifo->pFirst = pPage->pNext;
1.109 + sqlite3DbFree(pFifo->db, pPage);
1.110 + if( pFifo->nEntry==0 ){
1.111 + assert( pFifo->pLast==pPage );
1.112 + pFifo->pLast = 0;
1.113 + }else{
1.114 + assert( pFifo->pFirst!=0 );
1.115 + }
1.116 + }else{
1.117 + assert( pFifo->nEntry>0 );
1.118 + }
1.119 + return SQLITE_OK;
1.120 +}
1.121 +
1.122 +/*
1.123 +** Delete all information from a Fifo object. Free all memory held
1.124 +** by the Fifo.
1.125 +*/
1.126 +void sqlite3VdbeFifoClear(Fifo *pFifo){
1.127 + FifoPage *pPage, *pNextPage;
1.128 + for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
1.129 + pNextPage = pPage->pNext;
1.130 + sqlite3DbFree(pFifo->db, pPage);
1.131 + }
1.132 + sqlite3VdbeFifoInit(pFifo, pFifo->db);
1.133 +}