os/persistentdata/persistentstorage/sql/SQLite/vdbefifo.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
** 2005 June 16
sl@0
     3
**
sl@0
     4
** The author disclaims copyright to this source code.  In place of
sl@0
     5
** a legal notice, here is a blessing:
sl@0
     6
**
sl@0
     7
**    May you do good and not evil.
sl@0
     8
**    May you find forgiveness for yourself and forgive others.
sl@0
     9
**    May you share freely, never taking more than you give.
sl@0
    10
**
sl@0
    11
*************************************************************************
sl@0
    12
** This file implements a FIFO queue of rowids used for processing
sl@0
    13
** UPDATE and DELETE statements.
sl@0
    14
**
sl@0
    15
** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
sl@0
    16
*/
sl@0
    17
#include "sqliteInt.h"
sl@0
    18
#include "vdbeInt.h"
sl@0
    19
sl@0
    20
/*
sl@0
    21
** Constants FIFOSIZE_FIRST and FIFOSIZE_MAX are the initial
sl@0
    22
** number of entries in a fifo page and the maximum number of
sl@0
    23
** entries in a fifo page.
sl@0
    24
*/
sl@0
    25
#define FIFOSIZE_FIRST (((128-sizeof(FifoPage))/8)+1)
sl@0
    26
#ifdef SQLITE_MALLOC_SOFT_LIMIT
sl@0
    27
# define FIFOSIZE_MAX   (((SQLITE_MALLOC_SOFT_LIMIT-sizeof(FifoPage))/8)+1)
sl@0
    28
#else
sl@0
    29
# define FIFOSIZE_MAX   (((262144-sizeof(FifoPage))/8)+1)
sl@0
    30
#endif
sl@0
    31
sl@0
    32
/*
sl@0
    33
** Allocate a new FifoPage and return a pointer to it.  Return NULL if
sl@0
    34
** we run out of memory.  Leave space on the page for nEntry entries.
sl@0
    35
*/
sl@0
    36
static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
sl@0
    37
  FifoPage *pPage;
sl@0
    38
  if( nEntry>FIFOSIZE_MAX ){
sl@0
    39
    nEntry = FIFOSIZE_MAX;
sl@0
    40
  }
sl@0
    41
  pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
sl@0
    42
  if( pPage ){
sl@0
    43
    pPage->nSlot = nEntry;
sl@0
    44
    pPage->iWrite = 0;
sl@0
    45
    pPage->iRead = 0;
sl@0
    46
    pPage->pNext = 0;
sl@0
    47
  }
sl@0
    48
  return pPage;
sl@0
    49
}
sl@0
    50
sl@0
    51
/*
sl@0
    52
** Initialize a Fifo structure.
sl@0
    53
*/
sl@0
    54
void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
sl@0
    55
  memset(pFifo, 0, sizeof(*pFifo));
sl@0
    56
  pFifo->db = db;
sl@0
    57
}
sl@0
    58
sl@0
    59
/*
sl@0
    60
** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
sl@0
    61
** normally.   SQLITE_NOMEM is returned if we are unable to allocate
sl@0
    62
** memory.
sl@0
    63
*/
sl@0
    64
int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
sl@0
    65
  FifoPage *pPage;
sl@0
    66
  pPage = pFifo->pLast;
sl@0
    67
  if( pPage==0 ){
sl@0
    68
    pPage = pFifo->pLast = pFifo->pFirst =
sl@0
    69
         allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
sl@0
    70
    if( pPage==0 ){
sl@0
    71
      return SQLITE_NOMEM;
sl@0
    72
    }
sl@0
    73
  }else if( pPage->iWrite>=pPage->nSlot ){
sl@0
    74
    pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
sl@0
    75
    if( pPage->pNext==0 ){
sl@0
    76
      return SQLITE_NOMEM;
sl@0
    77
    }
sl@0
    78
    pPage = pFifo->pLast = pPage->pNext;
sl@0
    79
  }
sl@0
    80
  pPage->aSlot[pPage->iWrite++] = val;
sl@0
    81
  pFifo->nEntry++;
sl@0
    82
  return SQLITE_OK;
sl@0
    83
}
sl@0
    84
sl@0
    85
/*
sl@0
    86
** Extract a single 64-bit integer value from the Fifo.  The integer
sl@0
    87
** extracted is the one least recently inserted.  If the Fifo is empty
sl@0
    88
** return SQLITE_DONE.
sl@0
    89
*/
sl@0
    90
int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
sl@0
    91
  FifoPage *pPage;
sl@0
    92
  if( pFifo->nEntry==0 ){
sl@0
    93
    return SQLITE_DONE;
sl@0
    94
  }
sl@0
    95
  assert( pFifo->nEntry>0 );
sl@0
    96
  pPage = pFifo->pFirst;
sl@0
    97
  assert( pPage!=0 );
sl@0
    98
  assert( pPage->iWrite>pPage->iRead );
sl@0
    99
  assert( pPage->iWrite<=pPage->nSlot );
sl@0
   100
  assert( pPage->iRead<pPage->nSlot );
sl@0
   101
  assert( pPage->iRead>=0 );
sl@0
   102
  *pVal = pPage->aSlot[pPage->iRead++];
sl@0
   103
  pFifo->nEntry--;
sl@0
   104
  if( pPage->iRead>=pPage->iWrite ){
sl@0
   105
    pFifo->pFirst = pPage->pNext;
sl@0
   106
    sqlite3DbFree(pFifo->db, pPage);
sl@0
   107
    if( pFifo->nEntry==0 ){
sl@0
   108
      assert( pFifo->pLast==pPage );
sl@0
   109
      pFifo->pLast = 0;
sl@0
   110
    }else{
sl@0
   111
      assert( pFifo->pFirst!=0 );
sl@0
   112
    }
sl@0
   113
  }else{
sl@0
   114
    assert( pFifo->nEntry>0 );
sl@0
   115
  }
sl@0
   116
  return SQLITE_OK;
sl@0
   117
}
sl@0
   118
sl@0
   119
/*
sl@0
   120
** Delete all information from a Fifo object.   Free all memory held
sl@0
   121
** by the Fifo.
sl@0
   122
*/
sl@0
   123
void sqlite3VdbeFifoClear(Fifo *pFifo){
sl@0
   124
  FifoPage *pPage, *pNextPage;
sl@0
   125
  for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
sl@0
   126
    pNextPage = pPage->pNext;
sl@0
   127
    sqlite3DbFree(pFifo->db, pPage);
sl@0
   128
  }
sl@0
   129
  sqlite3VdbeFifoInit(pFifo, pFifo->db);
sl@0
   130
}