/ Check-in [93393993]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Reduce the size of VdbeCursor again, this time without a performance hit.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | OP_Column-refactor
Files: files | file ages | folders
SHA1:933939932c44bccb0958f203a5bd24e683c1cf38
User & Date: drh 2013-11-21 01:04:02
Context
2013-11-21
01:33
Refactor the OP_Column opcode to make it clearer and easier to maintain. Overall, performance tests show about a 1% speed increase with this change. check-in: 972881c6 user: drh tags: trunk
01:04
Reduce the size of VdbeCursor again, this time without a performance hit. Closed-Leaf check-in: 93393993 user: drh tags: OP_Column-refactor
00:10
Unpack some fields, adding some space back to the VdbeCursor object, in order to help the code to run a little faster. check-in: f8d5efcd user: drh tags: OP_Column-refactor
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   208    208     ** cursor 1 is managed by memory cell (p->nMem-1), etc.
   209    209     */
   210    210     Mem *pMem = &p->aMem[p->nMem-iCur];
   211    211   
   212    212     int nByte;
   213    213     VdbeCursor *pCx = 0;
   214    214     nByte = 
   215         -      ROUND8(sizeof(VdbeCursor)) + 
   216         -      (isBtreeCursor?sqlite3BtreeCursorSize():0) + 
   217         -      (2*nField+2)*sizeof(u32);
          215  +      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
          216  +      (isBtreeCursor?sqlite3BtreeCursorSize():0);
   218    217   
   219    218     assert( iCur<p->nCursor );
   220    219     if( p->apCsr[iCur] ){
   221    220       sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
   222    221       p->apCsr[iCur] = 0;
   223    222     }
   224    223     if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){
   225    224       p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
   226    225       memset(pCx, 0, sizeof(VdbeCursor));
   227    226       pCx->iDb = iDb;
   228    227       pCx->nField = nField;
   229         -    if( nField ){
   230         -      pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))];
   231         -    }
   232    228       if( isBtreeCursor ){
   233    229         pCx->pCursor = (BtCursor*)
   234         -          &pMem->z[ROUND8(sizeof(VdbeCursor))+(2*nField+2)*sizeof(u32)];
          230  +          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
   235    231         sqlite3BtreeCursorZero(pCx->pCursor);
   236    232       }
   237    233     }
   238    234     return pCx;
   239    235   }
   240    236   
   241    237   /*
................................................................................
  5803   5799       /* Initialize sqlite3_vtab_cursor base class */
  5804   5800       pVtabCursor->pVtab = pVtab;
  5805   5801   
  5806   5802       /* Initialize vdbe cursor object */
  5807   5803       pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
  5808   5804       if( pCur ){
  5809   5805         pCur->pVtabCursor = pVtabCursor;
  5810         -      pCur->pModule = pVtabCursor->pVtab->pModule;
  5811   5806       }else{
  5812   5807         db->mallocFailed = 1;
  5813   5808         pModule->xClose(pVtabCursor);
  5814   5809       }
  5815   5810     }
  5816   5811     break;
  5817   5812   }

Changes to src/vdbeInt.h.

    49     49   
    50     50   /*
    51     51   ** A cursor is a pointer into a single BTree within a database file.
    52     52   ** The cursor can seek to a BTree entry with a particular key, or
    53     53   ** loop over all entries of the Btree.  You can also insert new BTree
    54     54   ** entries or retrieve the key or data from the entry that the cursor
    55     55   ** is currently pointing to.
           56  +**
           57  +** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
           58  +** A pseudo-table is a single-row table implemented by registers.
    56     59   ** 
    57     60   ** Every cursor that the virtual machine has open is represented by an
    58     61   ** instance of the following structure.
    59     62   */
    60     63   struct VdbeCursor {
    61     64     BtCursor *pCursor;    /* The cursor structure of the backend */
    62     65     Btree *pBt;           /* Separate file holding temporary table */
................................................................................
    70     73     u8 rowidIsValid;      /* True if lastRowid is valid */
    71     74     u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
    72     75     Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
    73     76     Bool isTable:1;       /* True if a table requiring integer keys */
    74     77     Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
    75     78     Bool multiPseudo:1;   /* Multi-register pseudo-cursor */
    76     79     sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
    77         -  const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
    78     80     i64 seqCount;         /* Sequence counter */
    79     81     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
    80     82     i64 lastRowid;        /* Rowid being deleted by OP_Delete */
    81     83     VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
    82     84   
    83     85     /* Cached information about the header for the data record that the
    84     86     ** cursor is currently pointing to.  Only valid if cacheStatus matches
................................................................................
    89     91     ** aRow might point to (ephemeral) data for the current row, or it might
    90     92     ** be NULL.
    91     93     */
    92     94     u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
    93     95     u32 payloadSize;      /* Total number of bytes in the record */
    94     96     u32 szRow;            /* Byte available in aRow */
    95     97     u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
    96         -  u32 *aType;           /* Type values for all entries in the record */
    97     98     const u8 *aRow;       /* Data for the current row, if all on one page */
           99  +  u32 aType[1];         /* Type values for all entries in the record */
          100  +  /* 2*nField extra array elements allocated for aType[], beyond the one
          101  +  ** static element declared in the structure.  nField total array slots for
          102  +  ** aType[] and nField+1 array slots for aOffset[] */
    98    103   };
    99    104   typedef struct VdbeCursor VdbeCursor;
   100    105   
   101    106   /*
   102    107   ** When a sub-program is executed (OP_Program), a structure of this type
   103    108   ** is allocated to store the current value of the program counter, as
   104    109   ** well as the current memory cell array and various other frame specific

Changes to src/vdbeaux.c.

  1670   1670       ** the call above. */
  1671   1671     }else if( pCx->pCursor ){
  1672   1672       sqlite3BtreeCloseCursor(pCx->pCursor);
  1673   1673     }
  1674   1674   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1675   1675     if( pCx->pVtabCursor ){
  1676   1676       sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
  1677         -    const sqlite3_module *pModule = pCx->pModule;
         1677  +    const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
  1678   1678       p->inVtabMethod = 1;
  1679   1679       pModule->xClose(pVtabCursor);
  1680   1680       p->inVtabMethod = 0;
  1681   1681     }
  1682   1682   #endif
  1683   1683   }
  1684   1684