DBD-SQLite-Amalgamation
view release on metacpan or search on metacpan
sqlite-amalgamation.c view on Meta::CPAN
}
}
while( p ){
sqlite3_mutex_enter(p->pBt->mutex);
p->locked++;
p = p->pNext;
}
}
}
}
}
SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
int i;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nDb; i++){
p = db->aDb[i].pBt;
if( p && p->sharable ){
assert( p->wantToLock>0 );
p->wantToLock--;
if( p->wantToLock==0 ){
assert( p->locked );
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
}
}
}
}
#ifndef NDEBUG
/*
** Return true if the current thread holds the database connection
** mutex and all required BtShared mutexes.
**
** This routine is used inside assert() statements only.
*/
SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){
int i;
if( !sqlite3_mutex_held(db->mutex) ){
return 0;
}
for(i=0; i<db->nDb; i++){
Btree *p;
p = db->aDb[i].pBt;
if( p && p->sharable &&
(p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){
return 0;
}
}
return 1;
}
#endif /* NDEBUG */
/*
** Add a new Btree pointer to a BtreeMutexArray.
** if the pointer can possibly be shared with
** another database connection.
**
** The pointers are kept in sorted order by pBtree->pBt. That
** way when we go to enter all the mutexes, we can enter them
** in order without every having to backup and retry and without
** worrying about deadlock.
**
** The number of shared btrees will always be small (usually 0 or 1)
** so an insertion sort is an adequate algorithm here.
*/
SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){
int i, j;
BtShared *pBt;
if( pBtree==0 || pBtree->sharable==0 ) return;
#ifndef NDEBUG
{
for(i=0; i<pArray->nMutex; i++){
assert( pArray->aBtree[i]!=pBtree );
}
}
#endif
assert( pArray->nMutex>=0 );
assert( pArray->nMutex<sizeof(pArray->aBtree)/sizeof(pArray->aBtree[0])-1 );
pBt = pBtree->pBt;
for(i=0; i<pArray->nMutex; i++){
assert( pArray->aBtree[i]!=pBtree );
if( pArray->aBtree[i]->pBt>pBt ){
for(j=pArray->nMutex; j>i; j--){
pArray->aBtree[j] = pArray->aBtree[j-1];
}
pArray->aBtree[i] = pBtree;
pArray->nMutex++;
return;
}
}
pArray->aBtree[pArray->nMutex++] = pBtree;
}
/*
** Enter the mutex of every btree in the array. This routine is
** called at the beginning of sqlite3VdbeExec(). The mutexes are
** exited at the end of the same function.
*/
SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
int i;
for(i=0; i<pArray->nMutex; i++){
Btree *p = pArray->aBtree[i];
/* Some basic sanity checking */
assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
assert( !p->locked || p->wantToLock>0 );
/* We should already hold a lock on the database connection */
assert( sqlite3_mutex_held(p->db->mutex) );
p->wantToLock++;
if( !p->locked && p->sharable ){
sqlite3_mutex_enter(p->pBt->mutex);
p->locked = 1;
}
}
}
/*
** Leave the mutex of every btree in the group.
*/
sqlite-amalgamation.c view on Meta::CPAN
** end. We use the OP_Sort opcode instead of OP_Rewind to do the
** rewinding so that the global variable will be incremented and
** regression tests can determine whether or not the optimizer is
** correctly optimizing out sorts.
*/
case OP_Sort: { /* jump */
#ifdef SQLITE_TEST
sqlite3_sort_count++;
sqlite3_search_count--;
#endif
/* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: { /* jump */
int i = pOp->p1;
Cursor *pC;
BtCursor *pCrsr;
int res;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
assert( pC!=0 );
if( (pCrsr = pC->pCursor)!=0 ){
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->atFirst = res==0;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}else{
res = 1;
}
pC->nullRow = res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
if( res ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Next P1 P2 * * *
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
**
** The P1 cursor must be for a real table, not a pseudo-table.
**
** See also: Prev
*/
/* Opcode: Prev P1 P2 * * *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index. If there is no previous key/value pairs then fall through
** to the following instruction. But if the cursor backup was successful,
** jump immediately to P2.
**
** The P1 cursor must be for a real table, not a pseudo-table.
*/
case OP_Prev: /* jump */
case OP_Next: { /* jump */
Cursor *pC;
BtCursor *pCrsr;
int res;
CHECK_FOR_INTERRUPT;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
if( pC==0 ){
break; /* See ticket #2273 */
}
pCrsr = pC->pCursor;
assert( pCrsr );
res = 1;
assert( pC->deferredMoveto==0 );
rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
sqlite3BtreePrevious(pCrsr, &res);
pC->nullRow = res;
pC->cacheStatus = CACHE_STALE;
if( res==0 ){
pc = pOp->p2 - 1;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
}
pC->rowidIsValid = 0;
break;
}
/* Opcode: IdxInsert P1 P2 P3 * *
**
** Register P2 holds a SQL index key made using the
** MakeIdxRec instructions. This opcode writes that key
** into the index P1. Data for the entry is nil.
**
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
**
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
case OP_IdxInsert: { /* in2 */
int i = pOp->p1;
Cursor *pC;
BtCursor *pCrsr;
assert( i>=0 && i<p->nCursor );
assert( p->apCsr[i]!=0 );
assert( pIn2->flags & MEM_Blob );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
int nKey = pIn2->n;
const char *zKey = pIn2->z;
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3);
( run in 2.940 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )