vdbefifo.c
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:3k
源码类别:

数据库系统

开发平台:

C/C++

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