vdbefifo.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. ** Allocate a new FifoPage and return a pointer to it. Return NULL if
  19. ** we run out of memory. Leave space on the page for nEntry entries.
  20. */
  21. static FifoPage *allocateFifoPage(int nEntry){
  22. FifoPage *pPage;
  23. if( nEntry>32767 ){
  24. nEntry = 32767;
  25. }
  26. pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
  27. if( pPage ){
  28. pPage->nSlot = nEntry;
  29. pPage->iWrite = 0;
  30. pPage->iRead = 0;
  31. pPage->pNext = 0;
  32. }
  33. return pPage;
  34. }
  35. /*
  36. ** Initialize a Fifo structure.
  37. */
  38. void sqlite3VdbeFifoInit(Fifo *pFifo){
  39. memset(pFifo, 0, sizeof(*pFifo));
  40. }
  41. /*
  42. ** Push a single 64-bit integer value into the Fifo. Return SQLITE_OK
  43. ** normally. SQLITE_NOMEM is returned if we are unable to allocate
  44. ** memory.
  45. */
  46. int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
  47. FifoPage *pPage;
  48. pPage = pFifo->pLast;
  49. if( pPage==0 ){
  50. pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(20);
  51. if( pPage==0 ){
  52. return SQLITE_NOMEM;
  53. }
  54. }else if( pPage->iWrite>=pPage->nSlot ){
  55. pPage->pNext = allocateFifoPage(pFifo->nEntry);
  56. if( pPage->pNext==0 ){
  57. return SQLITE_NOMEM;
  58. }
  59. pPage = pFifo->pLast = pPage->pNext;
  60. }
  61. pPage->aSlot[pPage->iWrite++] = val;
  62. pFifo->nEntry++;
  63. return SQLITE_OK;
  64. }
  65. /*
  66. ** Extract a single 64-bit integer value from the Fifo. The integer
  67. ** extracted is the one least recently inserted. If the Fifo is empty
  68. ** return SQLITE_DONE.
  69. */
  70. int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
  71. FifoPage *pPage;
  72. if( pFifo->nEntry==0 ){
  73. return SQLITE_DONE;
  74. }
  75. assert( pFifo->nEntry>0 );
  76. pPage = pFifo->pFirst;
  77. assert( pPage!=0 );
  78. assert( pPage->iWrite>pPage->iRead );
  79. assert( pPage->iWrite<=pPage->nSlot );
  80. assert( pPage->iRead<pPage->nSlot );
  81. assert( pPage->iRead>=0 );
  82. *pVal = pPage->aSlot[pPage->iRead++];
  83. pFifo->nEntry--;
  84. if( pPage->iRead>=pPage->iWrite ){
  85. pFifo->pFirst = pPage->pNext;
  86. sqlite3_free(pPage);
  87. if( pFifo->nEntry==0 ){
  88. assert( pFifo->pLast==pPage );
  89. pFifo->pLast = 0;
  90. }else{
  91. assert( pFifo->pFirst!=0 );
  92. }
  93. }else{
  94. assert( pFifo->nEntry>0 );
  95. }
  96. return SQLITE_OK;
  97. }
  98. /*
  99. ** Delete all information from a Fifo object. Free all memory held
  100. ** by the Fifo.
  101. */
  102. void sqlite3VdbeFifoClear(Fifo *pFifo){
  103. FifoPage *pPage, *pNextPage;
  104. for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
  105. pNextPage = pPage->pNext;
  106. sqlite3_free(pPage);
  107. }
  108. sqlite3VdbeFifoInit(pFifo);
  109. }