extensions/sqlite/sqlite-source/vdbefifo.c
author David Anderson <dvander@alliedmods.net>
Sun Aug 30 01:54:45 2009 -0700 (2009-08-30)
changeset 2790 6dd851ba15fd
parent 1952 b7aa2b626807
permissions -rw-r--r--
Fixed extension version reporting.
ds@1952
     1
/*
ds@1952
     2
** 2005 June 16
ds@1952
     3
**
ds@1952
     4
** The author disclaims copyright to this source code.  In place of
ds@1952
     5
** a legal notice, here is a blessing:
ds@1952
     6
**
ds@1952
     7
**    May you do good and not evil.
ds@1952
     8
**    May you find forgiveness for yourself and forgive others.
ds@1952
     9
**    May you share freely, never taking more than you give.
ds@1952
    10
**
ds@1952
    11
*************************************************************************
ds@1952
    12
** This file implements a FIFO queue of rowids used for processing
ds@1952
    13
** UPDATE and DELETE statements.
ds@1952
    14
*/
ds@1952
    15
#include "sqliteInt.h"
ds@1952
    16
#include "vdbeInt.h"
ds@1952
    17
ds@1952
    18
/*
ds@1952
    19
** Allocate a new FifoPage and return a pointer to it.  Return NULL if
ds@1952
    20
** we run out of memory.  Leave space on the page for nEntry entries.
ds@1952
    21
*/
ds@1952
    22
static FifoPage *allocateFifoPage(int nEntry){
ds@1952
    23
  FifoPage *pPage;
ds@1952
    24
  if( nEntry>32767 ){
ds@1952
    25
    nEntry = 32767;
ds@1952
    26
  }
ds@1952
    27
  pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
ds@1952
    28
  if( pPage ){
ds@1952
    29
    pPage->nSlot = nEntry;
ds@1952
    30
    pPage->iWrite = 0;
ds@1952
    31
    pPage->iRead = 0;
ds@1952
    32
    pPage->pNext = 0;
ds@1952
    33
  }
ds@1952
    34
  return pPage;
ds@1952
    35
}
ds@1952
    36
ds@1952
    37
/*
ds@1952
    38
** Initialize a Fifo structure.
ds@1952
    39
*/
ds@1952
    40
void sqlite3VdbeFifoInit(Fifo *pFifo){
ds@1952
    41
  memset(pFifo, 0, sizeof(*pFifo));
ds@1952
    42
}
ds@1952
    43
ds@1952
    44
/*
ds@1952
    45
** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
ds@1952
    46
** normally.   SQLITE_NOMEM is returned if we are unable to allocate
ds@1952
    47
** memory.
ds@1952
    48
*/
ds@1952
    49
int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
ds@1952
    50
  FifoPage *pPage;
ds@1952
    51
  pPage = pFifo->pLast;
ds@1952
    52
  if( pPage==0 ){
ds@1952
    53
    pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(20);
ds@1952
    54
    if( pPage==0 ){
ds@1952
    55
      return SQLITE_NOMEM;
ds@1952
    56
    }
ds@1952
    57
  }else if( pPage->iWrite>=pPage->nSlot ){
ds@1952
    58
    pPage->pNext = allocateFifoPage(pFifo->nEntry);
ds@1952
    59
    if( pPage->pNext==0 ){
ds@1952
    60
      return SQLITE_NOMEM;
ds@1952
    61
    }
ds@1952
    62
    pPage = pFifo->pLast = pPage->pNext;
ds@1952
    63
  }
ds@1952
    64
  pPage->aSlot[pPage->iWrite++] = val;
ds@1952
    65
  pFifo->nEntry++;
ds@1952
    66
  return SQLITE_OK;
ds@1952
    67
}
ds@1952
    68
ds@1952
    69
/*
ds@1952
    70
** Extract a single 64-bit integer value from the Fifo.  The integer
ds@1952
    71
** extracted is the one least recently inserted.  If the Fifo is empty
ds@1952
    72
** return SQLITE_DONE.
ds@1952
    73
*/
ds@1952
    74
int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
ds@1952
    75
  FifoPage *pPage;
ds@1952
    76
  if( pFifo->nEntry==0 ){
ds@1952
    77
    return SQLITE_DONE;
ds@1952
    78
  }
ds@1952
    79
  assert( pFifo->nEntry>0 );
ds@1952
    80
  pPage = pFifo->pFirst;
ds@1952
    81
  assert( pPage!=0 );
ds@1952
    82
  assert( pPage->iWrite>pPage->iRead );
ds@1952
    83
  assert( pPage->iWrite<=pPage->nSlot );
ds@1952
    84
  assert( pPage->iRead<pPage->nSlot );
ds@1952
    85
  assert( pPage->iRead>=0 );
ds@1952
    86
  *pVal = pPage->aSlot[pPage->iRead++];
ds@1952
    87
  pFifo->nEntry--;
ds@1952
    88
  if( pPage->iRead>=pPage->iWrite ){
ds@1952
    89
    pFifo->pFirst = pPage->pNext;
ds@1952
    90
    sqlite3_free(pPage);
ds@1952
    91
    if( pFifo->nEntry==0 ){
ds@1952
    92
      assert( pFifo->pLast==pPage );
ds@1952
    93
      pFifo->pLast = 0;
ds@1952
    94
    }else{
ds@1952
    95
      assert( pFifo->pFirst!=0 );
ds@1952
    96
    }
ds@1952
    97
  }else{
ds@1952
    98
    assert( pFifo->nEntry>0 );
ds@1952
    99
  }
ds@1952
   100
  return SQLITE_OK;
ds@1952
   101
}
ds@1952
   102
ds@1952
   103
/*
ds@1952
   104
** Delete all information from a Fifo object.   Free all memory held
ds@1952
   105
** by the Fifo.
ds@1952
   106
*/
ds@1952
   107
void sqlite3VdbeFifoClear(Fifo *pFifo){
ds@1952
   108
  FifoPage *pPage, *pNextPage;
ds@1952
   109
  for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
ds@1952
   110
    pNextPage = pPage->pNext;
ds@1952
   111
    sqlite3_free(pPage);
ds@1952
   112
  }
ds@1952
   113
  sqlite3VdbeFifoInit(pFifo);
ds@1952
   114
}