engine/sqlite/src/btree.cpp
author skip
Thu, 25 Feb 2010 14:29:19 +0000
changeset 2 29cda98b007e
permissions -rw-r--r--
Initial import of Podcatcher from the Bergamot project
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2004 April 6
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** $Id: btree.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
** This file implements a external (disk-based) database using BTrees.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** See the header comment on "btreeInt.h" for additional information.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** Including a description of file format and an overview of operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
#include "btreeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** The header string that appears at the beginning of every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
** SQLite database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
static const char zMagicHeader[] = SQLITE_FILE_HEADER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
** Set this global variable to 1 to enable tracing using the TRACE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** macro.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
#if SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
int sqlite3_btree_trace=0;  /* True to enable tracing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
** A flag to indicate whether or not shared cache is enabled.  Also,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
** a list of BtShared objects that are eligible for participation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
** in shared cache.  The variables have file scope during normal builds,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
** but the test harness needs to access these variables so we make them
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
** global for test builds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
BtShared *sqlite3SharedCacheList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
int sqlite3SharedCacheEnabled = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
static BtShared *sqlite3SharedCacheList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
static int sqlite3SharedCacheEnabled = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
#endif /* SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
** Enable or disable the shared pager and schema features.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
** This routine has no effect on existing database connections.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
** The shared cache setting effects only future calls to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
EXPORT_C int sqlite3_enable_shared_cache(int enable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
  sqlite3SharedCacheEnabled = enable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
** Forward declaration
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
static int checkReadLocks(Btree*,Pgno,BtCursor*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
#ifdef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  ** The functions queryTableLock(), lockTable() and unlockAllTables()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  ** manipulate entries in the BtShared.pLock linked list used to store
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
  ** shared-cache table level locks. If the library is compiled with the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  ** shared-cache feature disabled, then there is only ever one user
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  ** of each BtShared structure and so this locking is not necessary. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  ** So define the lock related functions as no-ops.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
  #define queryTableLock(a,b,c) SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  #define lockTable(a,b,c) SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  #define unlockAllTables(a)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
** Query to see if btree handle p may obtain a lock of type eLock 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** SQLITE_LOCKED if not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  BtLock *pIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  /* This is a no-op if the shared-cache is not enabled */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
  if( !p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
  /* This (along with lockTable()) is where the ReadUncommitted flag is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  ** dealt with. If the caller is querying for a read-lock and the flag is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
  ** set, it is unconditionally granted - even if there are write-locks
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
  ** is not considered.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  ** In function lockTable(), if a read-lock is demanded and the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  ** ReadUncommitted flag is set, no entry is added to the locks list 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
  ** (BtShared.pLock).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
  ** To summarize: If the ReadUncommitted flag is set, then read cursors do
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  ** not create or respect table locks. The locking procedure for a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
  ** write-cursor does not change.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
    !p->db || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
    0==(p->db->flags&SQLITE_ReadUncommitted) || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
    eLock==WRITE_LOCK ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
    iTab==MASTER_ROOT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      if( pIter->pBtree!=p && pIter->iTable==iTab && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
          (pIter->eLock!=eLock || eLock!=READ_LOCK) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
        return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
#endif /* !SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
** Add a lock on the table with root-page iTable to the shared-btree used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
** by Btree handle p. Parameter eLock must be either READ_LOCK or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
** WRITE_LOCK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
** SQLITE_NOMEM may also be returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
static int lockTable(Btree *p, Pgno iTable, u8 eLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  BtLock *pLock = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  BtLock *pIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  /* This is a no-op if the shared-cache is not enabled */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  if( !p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
  /* If the read-uncommitted flag is set and a read-lock is requested,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  ** return early without adding an entry to the BtShared.pLock list. See
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  ** comment in function queryTableLock() for more info on handling 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
  ** the ReadUncommitted flag.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
    (p->db) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
    (p->db->flags&SQLITE_ReadUncommitted) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
    (eLock==READ_LOCK) &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
    iTable!=MASTER_ROOT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  /* First search the list for an existing lock on this table. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
    if( pIter->iTable==iTable && pIter->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
      pLock = pIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
  /* If the above search did not find a BtLock struct associating Btree p
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
  ** with table iTable, allocate one and link it into the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  if( !pLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
    pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
    if( !pLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
      return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
    pLock->iTable = iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    pLock->pBtree = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
    pLock->pNext = pBt->pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
    pBt->pLock = pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
  /* Set the BtLock.eLock variable to the maximum of the current lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  ** and the requested lock. This means if a write-lock was already held
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
  ** and a read-lock requested, we don't incorrectly downgrade the lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
  assert( WRITE_LOCK>READ_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  if( eLock>pLock->eLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
    pLock->eLock = eLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
#endif /* !SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
** Release all the table locks (locks obtained via calls to the lockTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
** procedure) held by Btree handle p.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
static void unlockAllTables(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
  BtLock **ppIter = &p->pBt->pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
  assert( p->sharable || 0==*ppIter );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
  while( *ppIter ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
    BtLock *pLock = *ppIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
    if( pLock->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
      *ppIter = pLock->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
      sqlite3_free(pLock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
      ppIter = &pLock->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
#endif /* SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
static void releasePage(MemPage *pPage);  /* Forward reference */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
** Verify that the cursor holds a mutex on the BtShared
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
static int cursorHoldsMutex(BtCursor *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  return sqlite3_mutex_held(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
** Invalidate the overflow page-list cache for cursor pCur, if any.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
static void invalidateOverflowCache(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  sqlite3_free(pCur->aOverflow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  pCur->aOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Invalidate the overflow page-list cache for all cursors opened
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
** on the shared btree structure pBt.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
static void invalidateAllOverflowCache(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
    invalidateOverflowCache(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
  #define invalidateOverflowCache(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
  #define invalidateAllOverflowCache(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
** Save the current cursor position in the variables BtCursor.nKey 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
static int saveCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  assert( CURSOR_VALID==pCur->eState );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  assert( 0==pCur->pKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  /* If this is an intKey table, then the above call to BtreeKeySize()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  ** stores the integer key in pCur->nKey. In this case this value is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  ** all that is required. Otherwise, if pCur is not open on an intKey
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  ** table, then malloc space for and store the pCur->nKey bytes of key 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
  ** data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
    void *pKey = sqlite3_malloc(pCur->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
    if( pKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
        pCur->pKey = pKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
        sqlite3_free(pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
  assert( !pCur->pPage->intKey || !pCur->pKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
    pCur->pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    pCur->eState = CURSOR_REQUIRESEEK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  invalidateOverflowCache(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
** Save the positions of all cursors except pExcept open on the table 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
** with root-page iRoot. Usually, this is called just before cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  assert( pExcept==0 || pExcept->pBt==pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
        p->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
      int rc = saveCursorPosition(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
      if( SQLITE_OK!=rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
** Clear the current cursor position.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
static void clearCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
  sqlite3_free(pCur->pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  pCur->pKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
** Restore the cursor to the position it was in (or as close to as possible)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
** when saveCursorPosition() was called. Note that this call deletes the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
** saved position info stored by saveCursorPosition(), so there can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
** at most one effective restoreOrClearCursorPosition() call after each 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
** saveCursorPosition().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
** If the second argument argument - doSeek - is false, then instead of 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
** returning the cursor to its saved position, any saved position is deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
** and the cursor state set to CURSOR_INVALID.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
  assert( pCur->eState>=CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  if( pCur->isIncrblobHandle ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
    return SQLITE_ABORT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
    sqlite3_free(pCur->pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
    pCur->pKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
#define restoreOrClearCursorPosition(p) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
  (p->eState>=CURSOR_REQUIRESEEK ? \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
         sqlite3BtreeRestoreOrClearCursorPosition(p) : \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
         SQLITE_OK)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
** Given a page number of a regular database page, return the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
** number for the pointer-map page that contains the entry for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
** input page number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  int nPagesPerMapPage, iPtrMap, ret;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  nPagesPerMapPage = (pBt->usableSize/5)+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  iPtrMap = (pgno-2)/nPagesPerMapPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  ret = (iPtrMap*nPagesPerMapPage) + 2; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  if( ret==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
    ret++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
  return ret;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
** Write an entry into the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
** This routine updates the pointer map entry for page number 'key'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
** so that it maps to type 'eType' and parent page number 'pgno'.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
  DbPage *pDbPage;  /* The pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
  u8 *pPtrmap;      /* The pointer map data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
  Pgno iPtrmap;     /* The pointer map page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
  int offset;       /* Offset in pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
  /* The master-journal page number must never be used as a pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
  assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
  assert( pBt->autoVacuum );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
  if( key==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
  iPtrmap = PTRMAP_PAGENO(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
  offset = PTRMAP_PTROFFSET(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
  if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
    TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
    rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
      pPtrmap[offset] = eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
      put4byte(&pPtrmap[offset+1], parent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
** Read an entry from the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
** This routine retrieves the pointer map entry for page 'key', writing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** the type and parent page number to *pEType and *pPgno respectively.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
  DbPage *pDbPage;   /* The pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
  int iPtrmap;       /* Pointer map page index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
  u8 *pPtrmap;       /* Pointer map page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
  int offset;        /* Offset of entry in pointer map */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  iPtrmap = PTRMAP_PAGENO(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
  if( rc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
  offset = PTRMAP_PTROFFSET(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  assert( pEType!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  *pEType = pPtrmap[offset];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
#endif /* SQLITE_OMIT_AUTOVACUUM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
** Given a btree page and a cell index (0 means the first cell on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
** the page, 1 means the second cell, and so forth) return a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
** to the cell content.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
** This routine works only for pages that do not contain overflow cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
#define findCell(pPage, iCell) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
  ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)]))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  assert( iCell>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
  assert( iCell<get2byte(&pPage->aData[pPage->hdrOffset+3]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
  return findCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
** This a more complex version of sqlite3BtreeFindCell() that works for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
** pages that do contain overflow cells.  See insert
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
static u8 *findOverflowCell(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
  for(i=pPage->nOverflow-1; i>=0; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
    int k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
	MemPage::_OvflCell *pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
    pOvfl = &pPage->aOvfl[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
    k = pOvfl->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
    if( k<=iCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
      if( k==iCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
        return pOvfl->pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
      iCell--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
  return findCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
** Parse a cell content block and fill in the CellInfo structure.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
** are two versions of this function.  sqlite3BtreeParseCell() takes a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
** cell index as the second argument and sqlite3BtreeParseCellPtr() 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
** takes a pointer to the body of the cell as its second argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
** Within this file, the parseCell() macro can be called instead of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
void sqlite3BtreeParseCellPtr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  MemPage *pPage,         /* Page containing the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
  u8 *pCell,              /* Pointer to the cell text. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
  CellInfo *pInfo         /* Fill in this structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
  int n;                  /* Number bytes in cell content header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  u32 nPayload;           /* Number of bytes of cell payload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
  pInfo->pCell = pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
  assert( pPage->leaf==0 || pPage->leaf==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  n = pPage->childPtrSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  assert( n==4-4*pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
  if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
    n += getVarint32(&pCell[n], &nPayload);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
    nPayload = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
  pInfo->nData = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
    u32 x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
    n += getVarint32(&pCell[n], &x);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
    pInfo->nKey = x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
    nPayload += x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
  pInfo->nPayload = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
  pInfo->nHeader = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
  if( nPayload<=pPage->maxLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
    /* This is the (easy) common case where the entire payload fits
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
    ** on the local page.  No overflow is required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
    int nSize;          /* Total size of cell content in bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
    pInfo->nLocal = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
    pInfo->iOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
    nSize = nPayload + n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
    if( nSize<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
      nSize = 4;        /* Minimum cell size is 4 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
    pInfo->nSize = nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
    /* If the payload will not fit completely on the local page, we have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
    ** to decide how much to store locally and how much to spill onto
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
    ** overflow pages.  The strategy is to minimize the amount of unused
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
    ** space on overflow pages while keeping the amount of local storage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
    ** in between minLocal and maxLocal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    ** Warning:  changing the way overflow payload is distributed in any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
    ** way will result in an incompatible file format.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
    int minLocal;  /* Minimum amount of payload held locally */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
    int maxLocal;  /* Maximum amount of payload held locally */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    int surplus;   /* Overflow payload available for local storage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
    minLocal = pPage->minLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
    maxLocal = pPage->maxLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
    if( surplus <= maxLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
      pInfo->nLocal = surplus;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
      pInfo->nLocal = minLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
    pInfo->iOverflow = pInfo->nLocal + n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
    pInfo->nSize = pInfo->iOverflow + 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
#define parseCell(pPage, iCell, pInfo) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
void sqlite3BtreeParseCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  MemPage *pPage,         /* Page containing the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  int iCell,              /* The cell index.  First cell is 0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  CellInfo *pInfo         /* Fill in this structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
  parseCell(pPage, iCell, pInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
** Compute the total number of bytes that a Cell needs in the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
** data area of the btree-page.  The return number includes the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
** data header and the local payload, but not any overflow page or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
** the space used by the cell pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
static int cellSize(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  sqlite3BtreeParseCell(pPage, iCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
  return info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
static int cellSizePtr(MemPage *pPage, u8 *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
  return info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
** If the cell pCell, part of page pPage contains a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
** to an overflow page, insert an entry into the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
** for the overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
  if( pCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
    assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
    if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
      Pgno ovfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
      return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
** If the cell with index iCell on page pPage contains a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
** to an overflow page, insert an entry into the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
** for the overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
static int ptrmapPutOvfl(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
  u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
  pCell = findOverflowCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
  return ptrmapPutOvflPtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
** Defragment the page given.  All Cells are moved to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
** end of the page and all free space is collected into one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
** big FreeBlk that occurs in between the header and cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
** pointer array and the cell content area.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
static int defragmentPage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
  int i;                     /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
  int pc;                    /* Address of a i-th cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
  int addr;                  /* Offset of first byte after cell pointer array */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
  int hdr;                   /* Offset to the page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
  int size;                  /* Size of a cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
  int usableSize;            /* Number of usable bytes on a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
  int cellOffset;            /* Offset to the cell pointer array */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
  int brk;                   /* Offset to the cell content area */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
  int nCell;                 /* Number of cells on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
  unsigned char *data;       /* The page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
  unsigned char *temp;       /* Temp area for cell content */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
  assert( pPage->pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
  assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
  temp = (unsigned char*)sqlite3PagerTempSpace(pPage->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
  cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
  nCell = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
  assert( nCell==get2byte(&data[hdr+3]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
  usableSize = pPage->pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
  brk = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
  memcpy(&temp[brk], &data[brk], usableSize - brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
  brk = usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
    u8 *pAddr;     /* The i-th cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
    pAddr = &data[cellOffset + i*2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
    pc = get2byte(pAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
    assert( pc<pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
    size = cellSizePtr(pPage, &temp[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
    brk -= size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
    memcpy(&data[brk], &temp[pc], size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
    put2byte(pAddr, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
  assert( brk>=cellOffset+2*nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
  put2byte(&data[hdr+5], brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
  data[hdr+1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
  data[hdr+2] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
  data[hdr+7] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
  addr = cellOffset+2*nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
  memset(&data[addr], 0, brk-addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
** Allocate nByte bytes of space on a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
** Return the index into pPage->aData[] of the first byte of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
** the new allocation. Or return 0 if there is not enough free
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
** space on the page to satisfy the allocation request.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
** If the page contains nBytes of free space but does not contain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
** nBytes of contiguous free space, then this routine automatically
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
** calls defragementPage() to consolidate all free space before 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
** allocating the new chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
static int allocateSpace(MemPage *pPage, int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
  int addr, pc, hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
  int size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  int nFrag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
  int top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
  int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
  int cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
  unsigned char *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
  assert( pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
  if( nByte<4 ) nByte = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
  if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
  pPage->nFree -= nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  nFrag = data[hdr+7];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
  if( nFrag<60 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
    /* Search the freelist looking for a slot big enough to satisfy the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
    ** space request. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
    addr = hdr+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
    while( (pc = get2byte(&data[addr]))>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
      size = get2byte(&data[pc+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
      if( size>=nByte ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
        if( size<nByte+4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
          memcpy(&data[addr], &data[pc], 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
          data[hdr+7] = nFrag + size - nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
          return pc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
          put2byte(&data[pc+2], size-nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
          return pc + size - nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
      addr = pc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
  /* Allocate memory from the gap in between the cell pointer array
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
  ** and the cell content area.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
  top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
  nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
  cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
  if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
    if( defragmentPage(pPage) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
  top -= nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
  assert( cellOffset + 2*nCell <= top );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
  put2byte(&data[hdr+5], top);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
  return top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
** Return a section of the pPage->aData to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
** The first byte of the new free block is pPage->aDisk[start]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
** and the size of the block is "size" bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
** Most of the effort here is involved in coalesing adjacent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
** free blocks into a single big free block.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
static void freeSpace(MemPage *pPage, int start, int size){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  int addr, pbegin, hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
  unsigned char *data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
  assert( pPage->pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
  assert( (start + size)<=pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
  if( size<4 ) size = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
#ifdef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
  /* Overwrite deleted information with zeros when the SECURE_DELETE 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
  ** option is enabled at compile-time */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
  memset(&data[start], 0, size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
  /* Add the space back into the linked list of freeblocks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  addr = hdr + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
    assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
    assert( pbegin>addr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
    addr = pbegin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
  assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  assert( pbegin>addr || pbegin==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
  put2byte(&data[addr], start);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
  put2byte(&data[start], pbegin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
  put2byte(&data[start+2], size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
  pPage->nFree += size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
  /* Coalesce adjacent free blocks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
  addr = pPage->hdrOffset + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
  while( (pbegin = get2byte(&data[addr]))>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
    int pnext, psize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
    assert( pbegin>addr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
    assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
    pnext = get2byte(&data[pbegin]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
    psize = get2byte(&data[pbegin+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
    if( pbegin + psize + 3 >= pnext && pnext>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
      int frag = pnext - (pbegin+psize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
      assert( frag<=data[pPage->hdrOffset+7] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
      data[pPage->hdrOffset+7] -= frag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
      put2byte(&data[pbegin], get2byte(&data[pnext]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
      put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
      addr = pbegin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
  /* If the cell content area begins with a freeblock, remove it. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
  if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
    int top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
    pbegin = get2byte(&data[hdr+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
    memcpy(&data[hdr+1], &data[pbegin], 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
    put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
** Decode the flags byte (the first byte of the header) for a page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
** and initialize fields of the MemPage structure accordingly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
static void decodeFlags(MemPage *pPage, int flagByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
  BtShared *pBt;     /* A copy of pPage->pBt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
  pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
  pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  pPage->leaf = (flagByte & PTF_LEAF)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  pPage->childPtrSize = 4*(pPage->leaf==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  if( flagByte & PTF_LEAFDATA ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
    pPage->leafData = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
    pPage->maxLocal = pBt->maxLeaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
    pPage->minLocal = pBt->minLeaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
    pPage->leafData = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
    pPage->maxLocal = pBt->maxLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
    pPage->minLocal = pBt->minLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
** Initialize the auxiliary information for a disk block.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
** The pParent parameter must be a pointer to the MemPage which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
** is the parent of the page being initialized.  The root of a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
** BTree has no parent and so for that page, pParent==NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
** Return SQLITE_OK on success.  If we see that the page does
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
** not contain a well-formed database page, then return 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
** guarantee that the page is well-formed.  It only shows that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
** we failed to detect any corruption.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
int sqlite3BtreeInitPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
  MemPage *pPage,        /* The page to be initialized */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
  MemPage *pParent       /* The parent.  Might be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
  int pc;            /* Address of a freeblock within pPage->aData[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
  int hdr;           /* Offset to beginning of page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
  u8 *data;          /* Equal to pPage->aData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
  BtShared *pBt;        /* The main btree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
  int usableSize;    /* Amount of usable space on each page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
  int cellOffset;    /* Offset from start of page to first cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
  int nFree;         /* Number of unused bytes on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
  int top;           /* First byte of the cell content area */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
  assert( pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
  assert( pParent==0 || pParent->pBt==pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
  assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
  assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
  if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
    /* The parent page should never change unless the file is corrupt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
  if( pPage->isInit ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
  if( pPage->pParent==0 && pParent!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
    pPage->pParent = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
    sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
  decodeFlags(pPage, data[hdr]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
  pPage->nOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
  pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
  top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
  pPage->nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
  if( pPage->nCell>MX_CELL(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
    /* To many cells for a single page.  The page must be corrupt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
  if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
    /* All pages must have at least one cell, except for root pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
  /* Compute the total free space on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
  pc = get2byte(&data[hdr+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
  nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
  while( pc>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
    int next, size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
    if( pc>usableSize-4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
      /* Free block is off the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
      return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
    next = get2byte(&data[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
    size = get2byte(&data[pc+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
    if( next>0 && next<=pc+size+3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
      /* Free blocks must be in accending order */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
      return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
    nFree += size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
    pc = next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
  pPage->nFree = nFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
  if( nFree>=usableSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
    /* Free space cannot exceed total page size */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
    return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
  pPage->isInit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
** Set up a raw page so that it looks like a database page holding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
** no entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
static void zeroPage(MemPage *pPage, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
  unsigned char *data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
  int hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
  int first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
  assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  assert( sqlite3PagerGetData(pPage->pDbPage) == data );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
  memset(&data[hdr], 0, pBt->usableSize - hdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
  data[hdr] = flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
  memset(&data[hdr+1], 0, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
  data[hdr+7] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
  put2byte(&data[hdr+5], pBt->usableSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
  pPage->nFree = pBt->usableSize - first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
  decodeFlags(pPage, flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
  pPage->hdrOffset = hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
  pPage->cellOffset = first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
  pPage->nOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
  pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
  pPage->nCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
  pPage->isInit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
** Get a page from the pager.  Initialize the MemPage.pBt and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
** MemPage.aData elements if needed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
** If the noContent flag is set, it means that we do not care about
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
** the content of the page at this time.  So do not go to the disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
** to fetch the content.  Just fill in the content with zeros for now.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
** If in the future we call sqlite3PagerWrite() on this page, that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
** means we have started to be concerned about content and the disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
** read should occur at that point.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
int sqlite3BtreeGetPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
  BtShared *pBt,       /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
  Pgno pgno,           /* Number of the page to fetch */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
  MemPage **ppPage,    /* Return the page in this parameter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  int noContent        /* Do not load page content if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  pPage->aData = (u8*)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
  pPage->pDbPage = pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
  pPage->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  pPage->pgno = pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
  *ppPage = pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
** Get a page from the pager and initialize it.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
** is just a convenience wrapper around separate calls to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
** sqlite3BtreeGetPage() and sqlite3BtreeInitPage().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
static int getAndInitPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
  BtShared *pBt,          /* The database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
  Pgno pgno,           /* Number of the page to get */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
  MemPage **ppPage,    /* Write the page pointer here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
  MemPage *pParent     /* Parent of the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  if( pgno==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
    return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
    rc = sqlite3BtreeInitPage(*ppPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
** Release a MemPage.  This should be called once for each prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
** call to sqlite3BtreeGetPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
static void releasePage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
  if( pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
    assert( pPage->aData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
    assert( pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
    assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
    sqlite3PagerUnref(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
** This routine is called when the reference count for a page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
** reaches zero.  We need to unref the pParent pointer when that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
** happens.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
static void pageDestructor(DbPage *pData, int pageSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
  assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
  assert( pPage->isInit==0 || sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
  if( pPage->pParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
    MemPage *pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
    assert( pParent->pBt==pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
    pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
    releasePage(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
  pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
** During a rollback, when the pager reloads information into the cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
** so that the cache is restored to its original state at the start of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
** the transaction, for each page restored this routine is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
** This routine needs to reset the extra data section at the end of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
** page to agree with the restored data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
static void pageReinit(DbPage *pData, int pageSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
  assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  if( pPage->isInit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
    pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
    sqlite3BtreeInitPage(pPage, pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
** Invoke the busy handler for a btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
static int sqlite3BtreeInvokeBusyHandler(void *pArg, int n){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  BtShared *pBt = (BtShared*)pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
  assert( pBt->db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
  assert( sqlite3_mutex_held(pBt->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
** Open a database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
** zFilename is the name of the database file.  If zFilename is NULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
** a new database with a random name is created.  This randomly named
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
** database file will be deleted when sqlite3BtreeClose() is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
** If zFilename is ":memory:" then an in-memory database is created
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
** that is automatically destroyed when it is closed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
int sqlite3BtreeOpen(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
  const char *zFilename,  /* Name of the file containing the BTree database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
  sqlite3 *db,            /* Associated database handle */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
  Btree **ppBtree,        /* Pointer to new Btree object written here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
  int flags,              /* Options */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
  int vfsFlags            /* Flags passed through to sqlite3_vfs.xOpen() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
  sqlite3_vfs *pVfs;      /* The VFS to use for this btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
  BtShared *pBt = 0;      /* Shared part of btree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
  Btree *p;               /* Handle to return */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
  int nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
  unsigned char zDbHeader[100];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
  /* Set the variable isMemdb to true for an in-memory database, or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
  ** false for a file-based database. This symbol is only required if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
  ** either of the shared-data or autovacuum features are compiled 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
  ** into the library.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  #ifdef SQLITE_OMIT_MEMORYDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
    const int isMemdb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
  #else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
    const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
  #endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
  assert( db!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
  assert( sqlite3_mutex_held(db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
  pVfs = db->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
  p = (Btree*)sqlite3MallocZero(sizeof(Btree));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
  if( !p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
  p->db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
  ** If this Btree is a candidate for shared cache, try to find an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
  ** existing BtShared object that we can share with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
  if( (flags & BTREE_PRIVATE)==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
   && isMemdb==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
   && (db->flags & SQLITE_Vtab)==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
   && zFilename && zFilename[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
    if( sqlite3SharedCacheEnabled ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
      int nFullPathname = pVfs->mxPathname+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
      char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
      sqlite3_mutex *mutexShared;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
      p->sharable = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
      if( db ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
        db->flags |= SQLITE_SharedCache;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
      if( !zFullPathname ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
        sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
        return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
      sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
      sqlite3_mutex_enter(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
      for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
        assert( pBt->nRef>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
        if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
                 && sqlite3PagerVfs(pBt->pPager)==pVfs ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
          p->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
          pBt->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
      sqlite3_mutex_leave(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
      sqlite3_free(zFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
    else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
      /* In debug mode, we mark all persistent databases as sharable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
      ** even when they are not.  This exercises the locking code and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
      ** gives more opportunity for asserts(sqlite3_mutex_held())
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
      ** statements to find locking problems.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
      p->sharable = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  if( pBt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
	/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
    ** The following asserts make sure that structures used by the btree are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
    ** the right size.  This is to guard against size changes that result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
    ** when compiling on a different architecture.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
    assert( sizeof(i64)==8 || sizeof(i64)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
    assert( sizeof(u64)==8 || sizeof(u64)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
    assert( sizeof(u32)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
    assert( sizeof(u16)==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
    assert( sizeof(Pgno)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
    pBt = (BtShared*)sqlite3MallocZero( sizeof(*pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
    if( pBt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
      goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
    pBt->busyHdr.xFunc = sqlite3BtreeInvokeBusyHandler;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
    pBt->busyHdr.pArg = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
	rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
                          EXTRA_SIZE, flags, vfsFlags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
      rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
      goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    sqlite3PagerSetBusyhandler(pBt->pPager, &pBt->busyHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
    p->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
    sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
    sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
    pBt->pCursor = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
    pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
    pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
    pBt->pageSize = get2byte(&zDbHeader[16]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
    if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
         || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
      pBt->pageSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
      sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
      pBt->maxEmbedFrac = 64;   /* 25% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
      pBt->minEmbedFrac = 32;   /* 12.5% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
      pBt->minLeafFrac = 32;    /* 12.5% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
      /* If the magic name ":memory:" will create an in-memory database, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
      ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
      ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
      ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
      ** regular file-name. In this case the auto-vacuum applies as per normal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
      if( zFilename && !isMemdb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
        pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
        pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
      nReserve = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
      nReserve = zDbHeader[20];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
      pBt->maxEmbedFrac = zDbHeader[21];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
      pBt->minEmbedFrac = zDbHeader[22];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
      pBt->minLeafFrac = zDbHeader[23];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
      pBt->pageSizeFixed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
      pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
      pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
    pBt->usableSize = pBt->pageSize - nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
    assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
    sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
    /* Add the new BtShared object to the linked list sharable BtShareds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
    if( p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
      sqlite3_mutex *mutexShared;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
      pBt->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
      if( SQLITE_THREADSAFE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
        pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
        if( pBt->mutex==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
          rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
          db->mallocFailed = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
          goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
      sqlite3_mutex_enter(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
      pBt->pNext = sqlite3SharedCacheList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
      sqlite3SharedCacheList = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
      sqlite3_mutex_leave(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
  /* If the new Btree uses a sharable pBtShared, then link the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
  ** Btree into the list of all sharable Btrees for the same connection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
  ** The list is kept in ascending order by pBt address.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
  if( p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
    Btree *pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
    for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
      if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
        while( pSib->pPrev ){ pSib = pSib->pPrev; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
        if( p->pBt<pSib->pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
          p->pNext = pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
          p->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
          pSib->pPrev = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
          while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
            pSib = pSib->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
          p->pNext = pSib->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
          p->pPrev = pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
          if( p->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
            p->pNext->pPrev = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
          pSib->pNext = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
  *ppBtree = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
btree_open_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
    if( pBt && pBt->pPager ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
      sqlite3PagerClose(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
    sqlite3_free(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
    sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
    *ppBtree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
** Decrement the BtShared.nRef counter.  When it reaches zero,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
** remove the BtShared structure from the sharing list.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
** true if the BtShared.nRef counter reaches zero and return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
** false if it is still positive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
static int removeFromSharingList(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
  sqlite3_mutex *pMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
  BtShared *pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
  int removed = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
  assert( sqlite3_mutex_notheld(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
  pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
  sqlite3_mutex_enter(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
  pBt->nRef--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
  if( pBt->nRef<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
    if( sqlite3SharedCacheList==pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
      sqlite3SharedCacheList = pBt->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
      pList = sqlite3SharedCacheList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
      while( pList && pList->pNext!=pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
        pList=pList->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
      if( pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
        pList->pNext = pBt->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
    if( SQLITE_THREADSAFE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
      sqlite3_mutex_free(pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
    removed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
  sqlite3_mutex_leave(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
  return removed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
** Close an open database and invalidate all cursors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
int sqlite3BtreeClose(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
  /* Close all cursors opened via this handle.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
  pCur = pBt->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
  while( pCur ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
    BtCursor *pTmp = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
    pCur = pCur->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
    if( pTmp->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
      sqlite3BtreeCloseCursor(pTmp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
  /* Rollback any active transaction and free the handle structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
  ** The call to sqlite3BtreeRollback() drops any table-locks held by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
  ** this handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
  sqlite3BtreeRollback(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
  /* If there are still other outstanding references to the shared-btree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
  ** structure, return now. The remainder of this procedure cleans 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
  ** up the shared-btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
  assert( p->wantToLock==0 && p->locked==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
  if( !p->sharable || removeFromSharingList(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
    /* The pBt is no longer on the sharing list, so we can access
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
    ** it without having to hold the mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
    ** Clean out and delete the BtShared object.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
    assert( !pBt->pCursor );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
    sqlite3PagerClose(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
    if( pBt->xFreeSchema && pBt->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
      pBt->xFreeSchema(pBt->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
    sqlite3_free(pBt->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
    sqlite3_free(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
  assert( p->wantToLock==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
  assert( p->locked==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
  if( p->pPrev ) p->pPrev->pNext = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
  if( p->pNext ) p->pNext->pPrev = p->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
  sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
** Change the limit on the number of pages allowed in the cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
** The maximum number of cache pages is set to the absolute
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
** value of mxPage.  If mxPage is negative, the pager will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
** operate asynchronously - it will not stop to do fsync()s
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
** to insure data is written to the disk surface before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
** continuing.  Transactions still work if synchronous is off,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
** and the database cannot be corrupted if this program
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
** crashes.  But if the operating system crashes or there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
** an abrupt power failure when synchronous is off, the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
** could be left in an inconsistent and unrecoverable state.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
** Synchronous is on by default so database corruption is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
** normally a worry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
  sqlite3PagerSetCachesize(pBt->pPager, mxPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
** Change the way data is synced to disk in order to increase or decrease
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
** how well the database resists damage due to OS crashes and power
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
** there is a high probability of damage)  Level 2 is the default.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
** is a very low but non-zero probability of damage.  Level 3 reduces the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
** probability of damage to near zero but with a write performance reduction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
  sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
** Return TRUE if the given btree is set to safety level 1.  In other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
** words, return TRUE if no sync() occurs on the disk files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
int sqlite3BtreeSyncDisabled(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
  assert( sqlite3_mutex_held(p->db->mutex) );  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
  assert( pBt && pBt->pPager );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
  rc = sqlite3PagerNosync(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
** Change the default pages size and the number of reserved bytes per page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
** The page size must be a power of 2 between 512 and 65536.  If the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
** size supplied does not meet this constraint then the page size is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
** changed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
** Page sizes are constrained to be a power of two so that the region
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
** of the database file used for locking (beginning at PENDING_BYTE,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
** the first byte past the 1GB boundary, 0x40000000) needs to occur
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
** at the beginning of a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
** If parameter nReserve is less than zero, then the number of reserved
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
** bytes per page is left unchanged.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
  if( pBt->pageSizeFixed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
    return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  if( nReserve<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
    nReserve = pBt->pageSize - pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
        ((pageSize-1)&pageSize)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
    assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
    assert( !pBt->pPage1 && !pBt->pCursor );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
    pBt->pageSize = pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
    rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
  pBt->usableSize = pBt->pageSize - nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
** Return the currently defined page size
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
int sqlite3BtreeGetPageSize(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
  return p->pBt->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
int sqlite3BtreeGetReserve(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
  n = p->pBt->pageSize - p->pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
** Set the maximum page count for a database if mxPage is positive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
** No changes are made if mxPage is 0 or negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
** Regardless of the value of mxPage, return the maximum page count.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1576
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1577
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
** is disabled. The default value for the auto-vacuum property is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1582
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1583
int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
  return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
  int av = (autoVacuum?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1590
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1591
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
  if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1593
    rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1594
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
    pBt->autoVacuum = av;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
** enabled 1 is returned. Otherwise 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1605
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1606
int sqlite3BtreeGetAutoVacuum(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
  return BTREE_AUTOVACUUM_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
  rc = (
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
    (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
    (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
    BTREE_AUTOVACUUM_INCR
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
** Get a reference to pPage1 of the database file.  This will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
** also acquire a readlock on that file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
** SQLITE_OK is returned on success.  If the file is not a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
** well-formed database file, then SQLITE_CORRUPT is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
** is returned if we run out of memory. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1631
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1632
static int lockBtree(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
  int rc, pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
  MemPage *pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1635
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1636
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
  if( pBt->pPage1 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1638
  rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1639
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1641
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1642
  /* Do some checking to help insure the file we opened really is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
  ** a valid database file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
  rc = SQLITE_NOTADB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
  if( sqlite3PagerPagecount(pBt->pPager)>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
    u8 *page1 = pPage1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1648
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1649
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1651
    if( page1[18]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1652
      pBt->readOnly = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
    if( page1[19]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
    pageSize = get2byte(&page1[16]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
    if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
        (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1660
    ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1661
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1662
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1663
    assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
    pBt->pageSize = pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1665
    pBt->usableSize = pageSize - page1[20];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1666
    if( pBt->usableSize<500 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
    pBt->maxEmbedFrac = page1[21];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
    pBt->minEmbedFrac = page1[22];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
    pBt->minLeafFrac = page1[23];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1673
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1674
    pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1677
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1678
  /* maxLocal is the maximum amount of payload to store locally for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
  ** a cell.  Make sure it is small enough so that at least minFanout
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
  ** cells can will fit on one page.  We assume a 10-byte page header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
  ** Besides the payload, the cell must store:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
  **     2-byte pointer to the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1683
  **     4-byte child pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1684
  **     9-byte nKey value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
  **     4-byte nData value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
  **     4-byte overflow page pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
  ** So a cell consists of a 2-byte poiner, a header which is as much as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
  ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
  ** page pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
  pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
  pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
  pBt->maxLeaf = pBt->usableSize - 35;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
  pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
  if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
    goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
  assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
  pBt->pPage1 = pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
page1_init_failed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
  releasePage(pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
  pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
** This routine works like lockBtree() except that it also invokes the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
** busy callback if there is lock contention.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
static int lockBtreeWithRetry(Btree *pRef){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
  assert( sqlite3BtreeHoldsMutex(pRef) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
  if( pRef->inTrans==TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
    u8 inTransaction = pRef->pBt->inTransaction;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
    btreeIntegrity(pRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
    rc = sqlite3BtreeBeginTrans(pRef, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
    pRef->pBt->inTransaction = inTransaction;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
    pRef->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
      pRef->pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
    btreeIntegrity(pRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
       
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1731
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1732
** If there are no outstanding cursors and we are not in the middle
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
** of a transaction but there is a read lock on the database, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
** this routine unrefs the first page of the database file which 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
** has the effect of releasing the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
** If there are any outstanding cursors, this routine is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1738
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1739
** If there is a transaction in progress, this routine is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
static void unlockBtreeIfUnused(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
    if( sqlite3PagerRefcount(pBt->pPager)>=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1745
      if( pBt->pPage1->aData==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1746
        MemPage *pPage = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
        pPage->aData = (u8*)sqlite3PagerGetData(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
        pPage->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
        pPage->pgno = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
      releasePage(pBt->pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
    pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
    pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1756
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1757
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1758
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
** Create a new database by initializing the first page of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
** file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
static int newDatabase(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
  MemPage *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
  unsigned char *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
  if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
  pP1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
  assert( pP1!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
  data = pP1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
  rc = sqlite3PagerWrite(pP1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
  memcpy(data, zMagicHeader, sizeof(zMagicHeader));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1775
  assert( sizeof(zMagicHeader)==16 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1776
  put2byte(&data[16], pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
  data[18] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
  data[19] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
  data[20] = pBt->pageSize - pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
  data[21] = pBt->maxEmbedFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
  data[22] = pBt->minEmbedFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1782
  data[23] = pBt->minLeafFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1783
  memset(&data[24], 0, 100-24);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
  zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
  pBt->pageSizeFixed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
  assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
  assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
  put4byte(&data[36 + 4*4], pBt->autoVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
  put4byte(&data[36 + 7*4], pBt->incrVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
** Attempt to start a new transaction. A write-transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
** is started if the second argument is nonzero, otherwise a read-
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
** transaction.  If the second argument is 2 or more and exclusive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
** transaction is started, meaning that no other process is allowed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
** to access the database.  A preexisting transaction may not be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
** upgraded to exclusive by calling this routine a second time - the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
** exclusivity flag only works for a new transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
** A write-transaction must be started before attempting any 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
** changes to the database.  None of the following routines 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
** will work unless a transaction is started first:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
**      sqlite3BtreeCreateTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
**      sqlite3BtreeCreateIndex()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
**      sqlite3BtreeClearTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
**      sqlite3BtreeDropTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
**      sqlite3BtreeInsert()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1813
**      sqlite3BtreeDelete()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1814
**      sqlite3BtreeUpdateMeta()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
** If an initial attempt to acquire the lock fails because of lock contention
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
** and the database was previously unlocked, then invoke the busy handler
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
** if there is one.  But if there was previously a read-lock, do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
** invoke the busy handler - just return SQLITE_BUSY.  SQLITE_BUSY is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1820
** returned when there is already a read-lock in order to avoid a deadlock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1821
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
** Suppose there are two processes A and B.  A has a read lock and B has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
** a reserved lock.  B tries to promote to exclusive but is blocked because
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
** of A's read lock.  A tries to promote to reserved but is blocked by B.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
** One or the other of the two processes must give way or there can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
** no progress.  By returning SQLITE_BUSY and not invoking the busy callback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
** when A already has a read lock, we encourage A to give up and let B
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1828
** proceed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1829
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1833
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1834
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1835
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1836
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
  /* If the btree is already in a write-transaction, or it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
  ** is already in a read-transaction and a read-transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
  ** is requested, this is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
  if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
    goto trans_begun;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1844
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1845
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1846
  /* Write transactions are not possible on a read-only database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
  if( pBt->readOnly && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
    rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
    goto trans_begun;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1851
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1852
  /* If another database handle has already opened a write transaction 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
  ** on this shared-btree structure and a second write transaction is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
  ** requested, return SQLITE_BUSY.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
  if( pBt->inTransaction==TRANS_WRITE && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
    rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1858
    goto trans_begun;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1859
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1860
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
  do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
    if( pBt->pPage1==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
      rc = lockBtree(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1865
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1866
    if( rc==SQLITE_OK && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
      if( pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
        rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
        rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
        if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
          rc = newDatabase(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1873
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1874
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1875
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1876
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
      if( wrflag ) pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
      unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
  }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
          sqlite3BtreeInvokeBusyHandler(pBt, 0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1884
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1885
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
    if( p->inTrans==TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
      pBt->nTransaction++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1888
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1889
    p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
    if( p->inTrans>pBt->inTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
      pBt->inTransaction = p->inTrans;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1895
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1896
trans_begun:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1903
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1904
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
** Set the pointer-map entries for all children of page pPage. Also, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
** pPage contains cells that point to overflow pages, set the pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
** map entries for the overflow pages as well.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
static int setChildPtrmaps(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
  int i;                             /* Counter variable */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1911
  int nCell;                         /* Number of cells in page pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1912
  int rc;                            /* Return code */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
  int isInitOrig = pPage->isInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
  Pgno pgno = pPage->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1916
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1917
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
  rc = sqlite3BtreeInitPage(pPage, pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
    goto set_child_ptrmaps_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1921
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1922
  nCell = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1923
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1924
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
    u8 *pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1926
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1927
    rc = ptrmapPutOvflPtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
      goto set_child_ptrmaps_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1931
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1932
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
      Pgno childPgno = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1937
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1938
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1939
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1943
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1944
set_child_ptrmaps_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
  pPage->isInit = isInitOrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1947
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1948
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
** page, is a pointer to page iFrom. Modify this pointer so that it points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
** iTo. Parameter eType describes the type of pointer to be modified, as 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
** follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1954
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1955
** PTRMAP_BTREE:     pPage is a btree-page. The pointer points at a child 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
**                   page of pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
**                   page pointed to by one of the cells on pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
**                   overflow page in the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
  if( eType==PTRMAP_OVERFLOW2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
    /* The pointer is always the first 4 bytes of the page in this case.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
    if( get4byte(pPage->aData)!=iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1971
    put4byte(pPage->aData, iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
    int isInitOrig = pPage->isInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
    int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
    sqlite3BtreeInitPage(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
    nCell = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1979
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1980
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
      u8 *pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
      if( eType==PTRMAP_OVERFLOW1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
        CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
        sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
        if( info.iOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
          if( iFrom==get4byte(&pCell[info.iOverflow]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
            put4byte(&pCell[info.iOverflow], iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1988
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1989
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
        if( get4byte(pCell)==iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
          put4byte(pCell, iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1998
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1999
    if( i==nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2000
      if( eType!=PTRMAP_BTREE || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2001
          get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
        return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
      put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
    pPage->isInit = isInitOrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2008
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2009
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
** Move the open database page pDbPage to location iFreePage in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
** database. The pDbPage reference remains valid.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2016
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2017
static int relocatePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
  BtShared *pBt,           /* Btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
  MemPage *pDbPage,        /* Open page to move */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
  Pgno iFreePage           /* The location to move pDbPage to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
  Pgno iDbPage = pDbPage->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
  Pager *pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2028
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2029
  assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
      eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
  assert( pDbPage->pBt==pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2033
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2034
  /* Move page iDbPage from its current location to page number iFreePage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
  TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
      iDbPage, iFreePage, iPtrPage, eType));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
  rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2040
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2041
  pDbPage->pgno = iFreePage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
  /* If pDbPage was a btree-page, then it may have child pages and/or cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
  ** that point to overflow pages. The pointer map entries for all these
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
  ** pages need to be changed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
  ** If pDbPage is an overflow page, then the first 4 bytes may store a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
  ** pointer to a subsequent overflow page. If this is the case, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
  ** the pointer map needs to be updated for the subsequent overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2050
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2051
  if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
    rc = setChildPtrmaps(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
    Pgno nextOvfl = get4byte(pDbPage->aData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
    if( nextOvfl!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
      rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2063
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2064
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2065
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2066
  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
  ** that it points at iFreePage. Also fix the pointer map entry for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
  ** iPtrPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
  if( eType!=PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
    rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
      releasePage(pPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2079
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2080
    rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
    releasePage(pPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2084
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2085
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2087
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2088
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2089
/* Forward declaration required by incrVacuumStep(). */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2092
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2093
** Perform a single step of an incremental-vacuum. If successful,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
** return SQLITE_OK. If there is no work to do (and therefore no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
** point in calling this function again), return SQLITE_DONE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
** More specificly, this function attempts to re-organize the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
** database so that the last page of the file currently in use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
** is no longer in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2100
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2101
** If the nFin parameter is non-zero, the implementation assumes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
** that the caller will keep calling incrVacuumStep() until
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
** it returns SQLITE_DONE or an error, and that nFin is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
** number of pages the database file will contain after this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
** process is complete.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
static int incrVacuumStep(BtShared *pBt, Pgno nFin){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
  Pgno iLastPg;             /* Last page in the database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
  Pgno nFreeList;           /* Number of pages still on the free-list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
  iLastPg = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
  if( iLastPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
    iLastPg = sqlite3PagerPagecount(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2115
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2116
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
  if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
    u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
    Pgno iPtrPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
    nFreeList = get4byte(&pBt->pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
    if( nFreeList==0 || nFin==iLastPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
      return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
    rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
    if( eType==PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2132
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2133
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2134
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
    if( eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
      if( nFin==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
        /* Remove the page from the files free-list. This is not required
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
        ** if nFin is non-zero. In that case, the free-list will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
        ** truncated to zero after this function returns, so it doesn't 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
        ** matter if it still contains some garbage entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2141
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2142
        Pgno iFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
        MemPage *pFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
        rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
        assert( iFreePg==iLastPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
        releasePage(pFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
    } else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
      Pgno iFreePg;             /* Index of free page to move pLastPg to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
      MemPage *pLastPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
      rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
      /* If nFin is zero, this loop runs exactly once and page pLastPg
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
      ** is swapped with the first free page pulled off the free list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
      ** On the other hand, if nFin is greater than zero, then keep
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
      ** looping until a free-page located within the first nFin pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
      ** of the file is found.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
      do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
        MemPage *pFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
        rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
          releasePage(pLastPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
        releasePage(pFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
      }while( nFin!=0 && iFreePg>nFin );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
      assert( iFreePg<iLastPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
      rc = sqlite3PagerWrite(pLastPg->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
        rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
      releasePage(pLastPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2186
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2187
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
  pBt->nTrunc = iLastPg - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
  while( pBt->nTrunc==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, pBt->nTrunc) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
    pBt->nTrunc--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2196
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
** A write-transaction must be opened before calling this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
** It performs a single unit of work towards an incremental vacuum.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
** If the incremental vacuum is finished after this function has run,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
** SQLITE_DONE is returned. If it is not finished, but no error occured,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
** SQLITE_OK is returned. Otherwise an SQLite error code. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
int sqlite3BtreeIncrVacuum(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
  assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
  if( !pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
    rc = SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
    invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
    rc = incrVacuumStep(pBt, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2220
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2221
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2222
** This routine is called prior to sqlite3PagerCommit when a transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
** is commited for an auto-vacuum database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2224
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2225
** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
** the database file should be truncated to during the commit process. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
** i.e. the database has been reorganized so that only the first *pnTrunc
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
** pages are in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
  Pager *pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
  int nRef = sqlite3PagerRefcount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2236
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2237
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
  invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
  assert(pBt->autoVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
  if( !pBt->incrVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
    Pgno nFin = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
    if( pBt->nTrunc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
      Pgno nFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
      Pgno nPtrmap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
      const int pgsz = pBt->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
      Pgno nOrig = sqlite3PagerPagecount(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
      if( PTRMAP_ISPAGE(pBt, nOrig) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
        return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
      if( nOrig==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
        nOrig--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
      nFree = get4byte(&pBt->pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
      nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+pgsz/5)/(pgsz/5);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
      nFin = nOrig - nFree - nPtrmap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
      if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
        nFin--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2261
      while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2262
        nFin--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2263
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2264
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2265
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2266
    while( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2267
      rc = incrVacuumStep(pBt, nFin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2268
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2269
    if( rc==SQLITE_DONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2270
      assert(nFin==0 || pBt->nTrunc==0 || nFin<=pBt->nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2271
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2272
      if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2273
        rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2274
        put4byte(&pBt->pPage1->aData[32], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2275
        put4byte(&pBt->pPage1->aData[36], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2276
        pBt->nTrunc = nFin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2277
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2278
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2279
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2280
      sqlite3PagerRollback(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2281
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2282
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2283
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2284
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2285
    *pnTrunc = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2286
    pBt->nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2287
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2288
  assert( nRef==sqlite3PagerRefcount(pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2289
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2290
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2291
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2292
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2293
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2294
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2295
** This routine does the first phase of a two-phase commit.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2296
** causes a rollback journal to be created (if it does not already exist)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2297
** and populated with enough information so that if a power loss occurs
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2298
** the database can be restored to its original state by playing back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2299
** the journal.  Then the contents of the journal are flushed out to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2300
** the disk.  After the journal is safely on oxide, the changes to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2301
** database are written into the database file and flushed to oxide.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2302
** At the end of this call, the rollback journal still exists on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2303
** disk and we are still holding all locks, so the transaction has not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2304
** committed.  See sqlite3BtreeCommit() for the second phase of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2305
** commit process.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2306
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2307
** This call is a no-op if no write-transaction is currently active on pBt.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2308
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2309
** Otherwise, sync the database file for the btree pBt. zMaster points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2310
** the name of a master journal file that should be written into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2311
** individual journal file, or is NULL, indicating no master journal file 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2312
** (single database transaction).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2313
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2314
** When this is called, the master journal should already have been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2315
** created, populated with this journal pointer and synced to disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2316
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2317
** Once this is routine has returned, the only thing required to commit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2318
** the write-transaction for this database file is to delete the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2319
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2320
int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2321
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2322
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2323
    BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2324
    Pgno nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2325
    sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2326
    pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2327
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2328
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2329
      rc = autoVacuumCommit(pBt, &nTrunc); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2330
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2331
        sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2332
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2333
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2334
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2335
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2336
    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2337
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2338
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2339
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2340
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2341
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2342
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2343
** Commit the transaction currently in progress.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2344
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2345
** This routine implements the second phase of a 2-phase commit.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2346
** sqlite3BtreeSync() routine does the first phase and should be invoked
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2347
** prior to calling this routine.  The sqlite3BtreeSync() routine did
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2348
** all the work of writing information out to disk and flushing the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2349
** contents so that they are written onto the disk platter.  All this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2350
** routine has to do is delete or truncate the rollback journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2351
** (which causes the transaction to commit) and drop locks.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2352
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2353
** This will release the write lock on the database file.  If there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2354
** are no active cursors, it also releases the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2355
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2356
int sqlite3BtreeCommitPhaseTwo(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2357
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2358
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2359
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2360
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2361
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2362
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2363
  /* If the handle has a write-transaction open, commit the shared-btrees 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2364
  ** transaction and set the shared state to TRANS_READ.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2365
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2366
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2367
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2368
    assert( pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2369
    assert( pBt->nTransaction>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2370
    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2371
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2372
      sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2373
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2374
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2375
    pBt->inTransaction = TRANS_READ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2376
    pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2377
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2378
  unlockAllTables(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2379
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2380
  /* If the handle has any kind of transaction open, decrement the transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2381
  ** count of the shared btree. If the transaction count reaches 0, set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2382
  ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2383
  ** will unlock the pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2384
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2385
  if( p->inTrans!=TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2386
    pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2387
    if( 0==pBt->nTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2388
      pBt->inTransaction = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2389
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2390
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2391
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2392
  /* Set the handles current transaction state to TRANS_NONE and unlock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2393
  ** the pager if this call closed the only read or write transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2394
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2395
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2396
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2397
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2398
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2399
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2400
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2401
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2402
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2403
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2404
** Do both phases of a commit.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2405
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2406
int sqlite3BtreeCommit(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2407
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2408
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2409
  rc = sqlite3BtreeCommitPhaseOne(p, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2410
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2411
    rc = sqlite3BtreeCommitPhaseTwo(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2412
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2413
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2414
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2415
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2416
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2417
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2418
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2419
** Return the number of write-cursors open on this handle. This is for use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2420
** in assert() expressions, so it is only compiled if NDEBUG is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2421
** defined.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2422
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2423
** For the purposes of this routine, a write-cursor is any cursor that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2424
** is capable of writing to the databse.  That means the cursor was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2425
** originally opened for writing and the cursor has not be disabled
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2426
** by having its state changed to CURSOR_FAULT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2427
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2428
static int countWriteCursors(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2429
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2430
  int r = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2431
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2432
    if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2433
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2434
  return r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2435
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2436
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2437
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2438
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2439
** This routine sets the state to CURSOR_FAULT and the error
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2440
** code to errCode for every cursor on BtShared that pBtree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2441
** references.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2442
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2443
** Every cursor is tripped, including cursors that belong
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2444
** to other database connections that happen to be sharing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2445
** the cache with pBtree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2446
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2447
** This routine gets called when a rollback occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2448
** All cursors using the same cache must be tripped
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2449
** to prevent them from trying to use the btree after
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2450
** the rollback.  The rollback may have deleted tables
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2451
** or moved root pages, so it is not sufficient to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2452
** save the state of the cursor.  The cursor must be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2453
** invalidated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2454
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2455
void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2456
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2457
  sqlite3BtreeEnter(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2458
  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2459
    clearCursorPosition(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2460
    p->eState = CURSOR_FAULT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2461
    p->skip = errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2462
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2463
  sqlite3BtreeLeave(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2464
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2465
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2466
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2467
** Rollback the transaction in progress.  All cursors will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2468
** invalided by this operation.  Any attempt to use a cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2469
** that was open at the beginning of this operation will result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2470
** in an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2471
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2472
** This will release the write lock on the database file.  If there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2473
** are no active cursors, it also releases the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2474
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2475
int sqlite3BtreeRollback(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2476
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2477
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2478
  MemPage *pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2479
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2480
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2481
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2482
  rc = saveAllCursors(pBt, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2483
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2484
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2485
    /* This is a horrible situation. An IO or malloc() error occured whilst
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2486
    ** trying to save cursor positions. If this is an automatic rollback (as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2487
    ** the result of a constraint, malloc() failure or IO error) then 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2488
    ** the cache may be internally inconsistent (not contain valid trees) so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2489
    ** we cannot simply return the error to the caller. Instead, abort 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2490
    ** all queries that may be using any of the cursors that failed to save.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2491
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2492
    sqlite3BtreeTripAllCursors(p, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2493
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2494
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2495
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2496
  unlockAllTables(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2497
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2498
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2499
    int rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2500
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2501
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2502
    pBt->nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2503
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2504
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2505
    assert( TRANS_WRITE==pBt->inTransaction );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2506
    rc2 = sqlite3PagerRollback(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2507
    if( rc2!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2508
      rc = rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2509
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2510
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2511
    /* The rollback may have destroyed the pPage1->aData value.  So
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2512
    ** call sqlite3BtreeGetPage() on page 1 again to make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2513
    ** sure pPage1->aData is set correctly. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2514
    if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2515
      releasePage(pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2516
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2517
    assert( countWriteCursors(pBt)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2518
    pBt->inTransaction = TRANS_READ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2519
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2520
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2521
  if( p->inTrans!=TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2522
    assert( pBt->nTransaction>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2523
    pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2524
    if( 0==pBt->nTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2525
      pBt->inTransaction = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2526
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2527
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2528
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2529
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2530
  pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2531
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2532
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2533
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2534
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2535
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2536
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2537
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2538
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2539
** Start a statement subtransaction.  The subtransaction can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2540
** can be rolled back independently of the main transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2541
** You must start a transaction before starting a subtransaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2542
** The subtransaction is ended automatically if the main transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2543
** commits or rolls back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2544
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2545
** Only one subtransaction may be active at a time.  It is an error to try
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2546
** to start a new subtransaction if another subtransaction is already active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2547
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2548
** Statement subtransactions are used around individual SQL statements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2549
** that are contained within a BEGIN...COMMIT block.  If a constraint
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2550
** error occurs within the statement, the effect of that one statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2551
** can be rolled back without having to rollback the entire transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2552
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2553
int sqlite3BtreeBeginStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2554
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2555
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2556
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2557
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2558
  if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2559
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2560
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2561
    assert( pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2562
    rc = pBt->readOnly ? SQLITE_OK : sqlite3PagerStmtBegin(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2563
    pBt->inStmt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2564
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2565
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2566
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2567
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2568
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2569
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2570
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2571
** Commit the statment subtransaction currently in progress.  If no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2572
** subtransaction is active, this is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2573
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2574
int sqlite3BtreeCommitStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2575
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2576
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2577
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2578
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2579
  if( pBt->inStmt && !pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2580
    rc = sqlite3PagerStmtCommit(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2581
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2582
    rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2583
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2584
  pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2585
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2586
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2587
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2588
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2589
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2590
** Rollback the active statement subtransaction.  If no subtransaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2591
** is active this routine is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2592
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2593
** All cursors will be invalidated by this operation.  Any attempt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2594
** to use a cursor that was open at the beginning of this operation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2595
** will result in an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2596
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2597
int sqlite3BtreeRollbackStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2598
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2599
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2600
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2601
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2602
  if( pBt->inStmt && !pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2603
    rc = sqlite3PagerStmtRollback(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2604
    assert( countWriteCursors(pBt)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2605
    pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2606
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2607
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2608
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2609
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2610
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2611
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2612
** Default key comparison function to be used if no comparison function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2613
** is specified on the sqlite3BtreeCursor() call.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2614
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2615
static int dfltCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2616
  void *NotUsed,             /* User data is not used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2617
  int n1, const void *p1,    /* First key to compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2618
  int n2, const void *p2     /* Second key to compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2619
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2620
  int c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2621
  c = memcmp(p1, p2, n1<n2 ? n1 : n2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2622
  if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2623
    c = n1 - n2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2624
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2625
  return c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2626
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2627
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2628
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2629
** Create a new cursor for the BTree whose root is on the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2630
** iTable.  The act of acquiring a cursor gets a read lock on 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2631
** the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2632
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2633
** If wrFlag==0, then the cursor can only be used for reading.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2634
** If wrFlag==1, then the cursor can be used for reading or for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2635
** writing if other conditions for writing are also met.  These
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2636
** are the conditions that must be met in order for writing to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2637
** be allowed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2638
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2639
** 1:  The cursor must have been opened with wrFlag==1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2640
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2641
** 2:  Other database connections that share the same pager cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2642
**     but which are not in the READ_UNCOMMITTED state may not have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2643
**     cursors open with wrFlag==0 on the same table.  Otherwise
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2644
**     the changes made by this write cursor would be visible to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2645
**     the read cursors in the other database connection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2646
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2647
** 3:  The database must be writable (not on read-only media)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2648
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2649
** 4:  There must be an active transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2650
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2651
** No checking is done to make sure that page iTable really is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2652
** root page of a b-tree.  If it is not, then the cursor acquired
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2653
** will not work correctly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2654
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2655
** The comparison function must be logically the same for every cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2656
** on a particular table.  Changing the comparison function will result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2657
** in incorrect operations.  If the comparison function is NULL, a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2658
** default comparison function is used.  The comparison function is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2659
** always ignored for INTKEY tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2660
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2661
static int btreeCursor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2662
  Btree *p,                                   /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2663
  int iTable,                                 /* Root page of table to open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2664
  int wrFlag,                                 /* 1 to write. 0 read-only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2665
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2666
  void *pArg,                                 /* First arg to xCompare() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2667
  BtCursor **ppCur                            /* Write new cursor here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2668
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2669
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2670
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2671
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2673
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2674
  *ppCur = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2675
  if( wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2676
    if( pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2677
      return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2678
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2679
    if( checkReadLocks(p, iTable, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2680
      return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2681
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2682
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2683
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2684
  if( pBt->pPage1==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2685
    rc = lockBtreeWithRetry(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2686
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2687
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2688
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2689
    if( pBt->readOnly && wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2690
      return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2691
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2692
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2693
  pCur = (BtCursor*)sqlite3MallocZero( sizeof(*pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2694
  if( pCur==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2695
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2696
    goto create_cursor_exception;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2698
  pCur->pgnoRoot = (Pgno)iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2699
  if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2700
    rc = SQLITE_EMPTY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2701
    goto create_cursor_exception;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2702
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2703
  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2704
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2705
    goto create_cursor_exception;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2706
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2707
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2708
  /* Now that no other errors can occur, finish filling in the BtCursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2709
  ** variables, link the cursor into the BtShared list and set *ppCur (the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2710
  ** output argument to this function).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2711
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2712
  pCur->xCompare = xCmp ? xCmp : dfltCompare;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2713
  pCur->pArg = pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2714
  pCur->pBtree = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2715
  pCur->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2716
  pCur->wrFlag = wrFlag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2717
  pCur->pNext = pBt->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2718
  if( pCur->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2719
    pCur->pNext->pPrev = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2720
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2721
  pBt->pCursor = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2722
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2723
  *ppCur = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2724
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2725
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2726
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2727
create_cursor_exception:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2728
  if( pCur ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2729
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2730
    sqlite3_free(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2731
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2732
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2733
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2734
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2735
int sqlite3BtreeCursor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2736
  Btree *p,                                   /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2737
  int iTable,                                 /* Root page of table to open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2738
  int wrFlag,                                 /* 1 to write. 0 read-only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2739
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2740
  void *pArg,                                 /* First arg to xCompare() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2741
  BtCursor **ppCur                            /* Write new cursor here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2742
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2743
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2744
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2745
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2746
  rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2747
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2748
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2749
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2750
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2751
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2752
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2753
** Close a cursor.  The read lock on the database file is released
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2754
** when the last cursor is closed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2755
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2756
int sqlite3BtreeCloseCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2757
  BtShared *pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2758
  Btree *pBtree = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2759
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2760
  sqlite3BtreeEnter(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2761
  pBt->db = pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2762
  clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2763
  if( pCur->pPrev ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2764
    pCur->pPrev->pNext = pCur->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2765
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2766
    pBt->pCursor = pCur->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2767
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2768
  if( pCur->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2769
    pCur->pNext->pPrev = pCur->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2770
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2771
  releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2772
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2773
  invalidateOverflowCache(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2774
  sqlite3_free(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2775
  sqlite3BtreeLeave(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2776
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2777
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2778
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2779
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2780
** Make a temporary cursor by filling in the fields of pTempCur.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2781
** The temporary cursor is not on the cursor list for the Btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2782
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2783
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2784
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2785
  memcpy(pTempCur, pCur, sizeof(*pCur));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2786
  pTempCur->pNext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2787
  pTempCur->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2788
  if( pTempCur->pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2789
    sqlite3PagerRef(pTempCur->pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2790
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2791
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2792
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2793
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2794
** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2795
** function above.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2796
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2797
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2798
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2799
  if( pCur->pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2800
    sqlite3PagerUnref(pCur->pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2801
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2802
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2803
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2804
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2805
** Make sure the BtCursor* given in the argument has a valid
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2806
** BtCursor.info structure.  If it is not already valid, call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2807
** sqlite3BtreeParseCell() to fill it in.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2808
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2809
** BtCursor.info is a cache of the information in the current cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2810
** Using this cache reduces the number of calls to sqlite3BtreeParseCell().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2811
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2812
** 2007-06-25:  There is a bug in some versions of MSVC that cause the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2813
** compiler to crash when getCellInfo() is implemented as a macro.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2814
** But there is a measureable speed advantage to using the macro on gcc
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2815
** (when less compiler optimizations like -Os or -O0 are used and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2816
** compiler is not doing agressive inlining.)  So we use a real function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2817
** for MSVC and a macro for everything else.  Ticket #2457.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2818
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2819
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2820
  static void assertCellInfo(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2821
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2822
    memset(&info, 0, sizeof(info));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2823
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2824
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2825
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2826
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2827
  #define assertCellInfo(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2828
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2829
#ifdef _MSC_VER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2830
  /* Use a real function in MSVC to work around bugs in that compiler. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2831
  static void getCellInfo(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2832
    if( pCur->info.nSize==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2833
      sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2834
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2835
      assertCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2836
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2837
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2838
#else /* if not _MSC_VER */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2839
  /* Use a macro in all other compilers so that the function is inlined */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2840
#define getCellInfo(pCur)                                               \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2841
  if( pCur->info.nSize==0 ){                                            \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2842
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);         \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2843
  }else{                                                                \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2844
    assertCellInfo(pCur);                                               \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2845
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2846
#endif /* _MSC_VER */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2847
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2848
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2849
** Set *pSize to the size of the buffer needed to hold the value of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2850
** the key for the current entry.  If the cursor is not pointing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2851
** to a valid entry, *pSize is set to 0. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2852
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2853
** For a table with the INTKEY flag set, this routine returns the key
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2854
** itself, not the number of bytes in the key.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2855
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2856
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2857
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2859
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2860
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2861
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2862
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2863
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2864
      *pSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2865
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2866
      getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2867
      *pSize = pCur->info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2868
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2869
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2870
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2871
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2872
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2873
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2874
** Set *pSize to the number of bytes of data in the entry the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2875
** cursor currently points to.  Always return SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2876
** Failure is not possible.  If the cursor is not currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2877
** pointing to an entry (which can happen, for example, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2878
** the database is empty) then *pSize is set to 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2879
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2880
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2881
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2882
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2883
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2884
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2885
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2886
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2887
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2888
      /* Not pointing at a valid entry - set *pSize to 0. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2889
      *pSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2890
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2891
      getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2892
      *pSize = pCur->info.nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2893
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2894
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2895
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2896
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2897
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2898
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2899
** Given the page number of an overflow page in the database (parameter
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2900
** ovfl), this function finds the page number of the next page in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2901
** linked list of overflow pages. If possible, it uses the auto-vacuum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2902
** pointer-map data instead of reading the content of page ovfl to do so. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2903
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2904
** If an error occurs an SQLite error code is returned. Otherwise:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2905
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2906
** Unless pPgnoNext is NULL, the page number of the next overflow 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2907
** page in the linked list is written to *pPgnoNext. If page ovfl
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2908
** is the last page in its linked list, *pPgnoNext is set to zero. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2909
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2910
** If ppPage is not NULL, *ppPage is set to the MemPage* handle
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2911
** for page ovfl. The underlying pager page may have been requested
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2912
** with the noContent flag set, so the page data accessable via
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2913
** this handle may not be trusted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2914
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2915
static int getOverflowPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2916
  BtShared *pBt, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2917
  Pgno ovfl,                   /* Overflow page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2918
  MemPage **ppPage,            /* OUT: MemPage handle */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2919
  Pgno *pPgnoNext              /* OUT: Next overflow page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2920
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2921
  Pgno next = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2922
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2923
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2924
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2925
  /* One of these must not be NULL. Otherwise, why call this function? */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2926
  assert(ppPage || pPgnoNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2928
  /* If pPgnoNext is NULL, then this function is being called to obtain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2929
  ** a MemPage* reference only. No page-data is required in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2930
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2931
  if( !pPgnoNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2932
    return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2933
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2934
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2935
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2936
  /* Try to find the next page in the overflow list using the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2937
  ** autovacuum pointer-map pages. Guess that the next page in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2938
  ** the overflow list is page number (ovfl+1). If that guess turns 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2939
  ** out to be wrong, fall back to loading the data of page 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2940
  ** number ovfl to determine the next page number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2941
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2942
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2943
    Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2944
    Pgno iGuess = ovfl+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2945
    u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2946
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2947
    while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2948
      iGuess++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2949
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2950
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2951
    if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2952
      rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2953
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2954
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2955
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2956
      if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2957
        next = iGuess;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2958
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2959
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2960
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2961
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2962
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2963
  if( next==0 || ppPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2964
    MemPage *pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2965
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2966
    rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2967
    assert(rc==SQLITE_OK || pPage==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2968
    if( next==0 && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2969
      next = get4byte(pPage->aData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2971
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2972
    if( ppPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2973
      *ppPage = pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2974
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2975
      releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2976
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2977
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2978
  *pPgnoNext = next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2979
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2980
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2981
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2982
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2983
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2984
** Copy data from a buffer to a page, or from a page to a buffer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2985
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2986
** pPayload is a pointer to data stored on database page pDbPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2987
** If argument eOp is false, then nByte bytes of data are copied
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2988
** from pPayload to the buffer pointed at by pBuf. If eOp is true,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2989
** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2990
** of data are copied from the buffer pBuf to pPayload.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2991
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2992
** SQLITE_OK is returned on success, otherwise an error code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2993
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2994
static int copyPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2995
  void *pPayload,           /* Pointer to page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2996
  void *pBuf,               /* Pointer to buffer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2997
  int nByte,                /* Number of bytes to copy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2998
  int eOp,                  /* 0 -> copy from page, 1 -> copy to page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2999
  DbPage *pDbPage           /* Page containing pPayload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3000
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3001
  if( eOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3002
    /* Copy data from buffer to page (a write operation) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3003
    int rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3004
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3005
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3006
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3007
    memcpy(pPayload, pBuf, nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3008
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3009
    /* Copy data from page to buffer (a read operation) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3010
    memcpy(pBuf, pPayload, nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3011
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3012
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3013
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3014
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3015
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3016
** This function is used to read or overwrite payload information
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3017
** for the entry that the pCur cursor is pointing to. If the eOp
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3018
** parameter is 0, this is a read operation (data copied into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3019
** buffer pBuf). If it is non-zero, a write (data copied from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3020
** buffer pBuf).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3021
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3022
** A total of "amt" bytes are read or written beginning at "offset".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3023
** Data is read to or from the buffer pBuf.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3024
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3025
** This routine does not make a distinction between key and data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3026
** It just reads or writes bytes from the payload area.  Data might 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3027
** appear on the main page or be scattered out on multiple overflow 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3028
** pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3029
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3030
** If the BtCursor.isIncrblobHandle flag is set, and the current
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3031
** cursor entry uses one or more overflow pages, this function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3032
** allocates space for and lazily popluates the overflow page-list 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3033
** cache array (BtCursor.aOverflow). Subsequent calls use this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3034
** cache to make seeking to the supplied offset more efficient.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3035
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3036
** Once an overflow page-list cache has been allocated, it may be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3037
** invalidated if some other cursor writes to the same table, or if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3038
** the cursor is moved to a different row. Additionally, in auto-vacuum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3039
** mode, the following events may invalidate an overflow page-list cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3040
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3041
**   * An incremental vacuum,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3042
**   * A commit in auto_vacuum="full" mode,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3043
**   * Creating a table (may require moving an overflow page).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3044
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3045
static int accessPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3046
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3047
  int offset,          /* Begin reading this far into payload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3048
  int amt,             /* Read this many bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3049
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3050
  int skipKey,         /* offset begins at data if this is true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3051
  int eOp              /* zero to read. non-zero to write. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3052
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3053
  unsigned char *aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3054
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3055
  u32 nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3056
  int iIdx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3057
  MemPage *pPage = pCur->pPage;     /* Btree page of current cursor entry */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3058
  BtShared *pBt;                   /* Btree this cursor belongs to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3059
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3060
  assert( pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3061
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3062
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3063
  assert( offset>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3064
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3065
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3066
  getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3067
  aPayload = pCur->info.pCell + pCur->info.nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3068
  nKey = (pPage->intKey ? 0 : pCur->info.nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3069
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3070
  if( skipKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3071
    offset += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3072
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3073
  if( offset+amt > nKey+pCur->info.nData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3074
    /* Trying to read or write past the end of the data is an error */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3075
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3076
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3077
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3078
  /* Check if data must be read/written to/from the btree page itself. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3079
  if( offset<pCur->info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3080
    int a = amt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3081
    if( a+offset>pCur->info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3082
      a = pCur->info.nLocal - offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3083
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3084
    rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3085
    offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3086
    pBuf += a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3087
    amt -= a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3088
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3089
    offset -= pCur->info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3090
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3091
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3092
  pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3093
  if( rc==SQLITE_OK && amt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3094
    const int ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3095
    Pgno nextPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3096
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3097
    nextPage = get4byte(&aPayload[pCur->info.nLocal]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3098
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3099
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3100
    /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3101
    ** has not been allocated, allocate it now. The array is sized at
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3102
    ** one entry for each overflow page in the overflow chain. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3103
    ** page number of the first overflow page is stored in aOverflow[0],
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3104
    ** etc. A value of 0 in the aOverflow[] array means "not yet known"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3105
    ** (the cache is lazily populated).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3106
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3107
    if( pCur->isIncrblobHandle && !pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3108
      int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3109
      pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3110
      if( nOvfl && !pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3111
        rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3112
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3113
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3114
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3115
    /* If the overflow page-list cache has been allocated and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3116
    ** entry for the first required overflow page is valid, skip
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3117
    ** directly to it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3118
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3119
    if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3120
      iIdx = (offset/ovflSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3121
      nextPage = pCur->aOverflow[iIdx];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3122
      offset = (offset%ovflSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3123
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3124
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3125
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3126
    for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3127
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3128
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3129
      /* If required, populate the overflow page-list cache. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3130
      if( pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3131
        assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3132
        pCur->aOverflow[iIdx] = nextPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3133
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3134
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3135
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3136
      if( offset>=ovflSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3137
        /* The only reason to read this page is to obtain the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3138
        ** number for the next page in the overflow chain. The page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3139
        ** data is not required. So first try to lookup the overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3140
        ** page-list cache, if any, then fall back to the getOverflowPage()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3141
        ** function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3142
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3143
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3144
        if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3145
          nextPage = pCur->aOverflow[iIdx+1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3146
        } else 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3147
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3148
          rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3149
        offset -= ovflSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3150
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3151
        /* Need to read this page properly. It contains some of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3152
        ** range of data that is being read (eOp==0) or written (eOp!=0).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3153
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3154
        DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3155
        int a = amt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3156
        rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3157
        if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3158
          aPayload = (unsigned char*)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3159
          nextPage = get4byte(aPayload);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3160
          if( a + offset > ovflSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3161
            a = ovflSize - offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3162
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3163
          rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3164
          sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3165
          offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3166
          amt -= a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3167
          pBuf += a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3168
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3169
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3170
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3171
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3172
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3173
  if( rc==SQLITE_OK && amt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3174
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3175
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3176
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3177
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3178
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3179
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3180
** Read part of the key associated with cursor pCur.  Exactly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3181
** "amt" bytes will be transfered into pBuf[].  The transfer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3182
** begins at "offset".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3183
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3184
** Return SQLITE_OK on success or an error code if anything goes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3185
** wrong.  An error is returned if "offset+amt" is larger than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3186
** the available payload.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3187
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3188
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3189
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3190
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3191
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3192
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3193
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3194
    assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3195
    assert( pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3196
    if( pCur->pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3197
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3198
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3199
    assert( pCur->pPage->intKey==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3200
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3201
    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3202
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3203
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3204
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3205
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3206
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3207
** Read part of the data associated with cursor pCur.  Exactly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3208
** "amt" bytes will be transfered into pBuf[].  The transfer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3209
** begins at "offset".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3210
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3211
** Return SQLITE_OK on success or an error code if anything goes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3212
** wrong.  An error is returned if "offset+amt" is larger than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3213
** the available payload.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3214
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3215
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3216
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3217
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3218
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3219
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3220
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3221
    assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3222
    assert( pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3223
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3224
    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3225
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3226
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3227
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3228
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3229
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3230
** Return a pointer to payload information from the entry that the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3231
** pCur cursor is pointing to.  The pointer is to the beginning of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3232
** the key if skipKey==0 and it points to the beginning of data if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3233
** skipKey==1.  The number of bytes of available key/data is written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3234
** into *pAmt.  If *pAmt==0, then the value returned will not be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3235
** a valid pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3236
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3237
** This routine is an optimization.  It is common for the entire key
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3238
** and data to fit on the local page and for there to be no overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3239
** pages.  When that is so, this routine can be used to access the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3240
** key and data without making a copy.  If the key and/or data spills
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3241
** onto overflow pages, then accessPayload() must be used to reassembly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3242
** the key/data and copy it into a preallocated buffer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3243
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3244
** The pointer returned by this routine looks directly into the cached
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3245
** page of the database.  The data might change or move the next time
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3246
** any btree routine is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3247
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3248
static const unsigned char *fetchPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3249
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3250
  int *pAmt,           /* Write the number of available bytes here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3251
  int skipKey          /* read beginning at data if this is true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3252
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3253
  unsigned char *aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3254
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3255
  u32 nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3256
  int nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3257
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3258
  assert( pCur!=0 && pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3259
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3260
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3261
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3262
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3263
  getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3264
  aPayload = pCur->info.pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3265
  aPayload += pCur->info.nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3266
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3267
    nKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3268
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3269
    nKey = pCur->info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3270
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3271
  if( skipKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3272
    aPayload += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3273
    nLocal = pCur->info.nLocal - nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3274
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3275
    nLocal = pCur->info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3276
    if( nLocal>nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3277
      nLocal = nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3278
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3279
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3280
  *pAmt = nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3281
  return aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3282
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3283
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3284
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3285
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3286
** For the entry that cursor pCur is point to, return as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3287
** many bytes of the key or data as are available on the local
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3288
** b-tree page.  Write the number of available bytes into *pAmt.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3289
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3290
** The pointer returned is ephemeral.  The key/data may move
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3291
** or be destroyed on the next call to any Btree routine,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3292
** including calls from other threads against the same cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3293
** Hence, a mutex on the BtShared should be held prior to calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3294
** this routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3295
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3296
** These routines is used to get quick access to key and data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3297
** in the common case where no overflow pages are used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3298
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3299
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3300
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3301
  if( pCur->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3302
    return (const void*)fetchPayload(pCur, pAmt, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3303
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3304
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3305
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3306
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3307
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3308
  if( pCur->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3309
    return (const void*)fetchPayload(pCur, pAmt, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3310
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3311
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3312
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3313
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3316
** Move the cursor down to a new child page.  The newPgno argument is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3317
** page number of the child page to move to.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3318
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3319
static int moveToChild(BtCursor *pCur, u32 newPgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3320
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3321
  MemPage *pNewPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3322
  MemPage *pOldPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3323
  BtShared *pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3324
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3325
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3326
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3327
  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3328
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3329
  pNewPage->idxParent = pCur->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3330
  pOldPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3331
  pOldPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3332
  releasePage(pOldPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3333
  pCur->pPage = pNewPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3334
  pCur->idx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3335
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3336
  if( pNewPage->nCell<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3337
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3338
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3339
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3340
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3341
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3342
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3343
** Return true if the page is the virtual root of its table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3344
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3345
** The virtual root page is the root page for most tables.  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3346
** for the table rooted on page 1, sometime the real root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3347
** is empty except for the right-pointer.  In such cases the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3348
** virtual root page is the page that the right-pointer of page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3349
** 1 is pointing to.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3350
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3351
int sqlite3BtreeIsRootPage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3352
  MemPage *pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3353
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3354
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3355
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3356
  if( pParent==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3357
  if( pParent->pgno>1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3358
  if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3359
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3360
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3361
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3362
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3363
** Move the cursor up to the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3364
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3365
** pCur->idx is set to the cell index that contains the pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3366
** to the page we are coming from.  If we are coming from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3367
** right-most child page then pCur->idx is set to one more than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3368
** the largest cell index.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3369
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3370
void sqlite3BtreeMoveToParent(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3371
  MemPage *pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3372
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3373
  int idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3374
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3375
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3376
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3377
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3378
  assert( pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3379
  assert( !sqlite3BtreeIsRootPage(pPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3380
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3381
  assert( pParent!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3382
  idxParent = pPage->idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3383
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3384
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3385
  pCur->pPage = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3386
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3387
  assert( pParent->idxShift==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3388
  pCur->idx = idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3389
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3390
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3391
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3392
** Move the cursor to the root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3393
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3394
static int moveToRoot(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3395
  MemPage *pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3396
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3397
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3398
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3399
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3400
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3401
  assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3402
  assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3403
  assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3404
  if( pCur->eState>=CURSOR_REQUIRESEEK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3405
    if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3406
      return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3407
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3408
    clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3409
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3410
  pRoot = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3411
  if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3412
    assert( pRoot->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3413
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3414
    if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3415
      SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3416
    ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3417
      pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3418
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3419
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3420
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3421
    pCur->pPage = pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3422
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3423
  pCur->idx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3424
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3425
  if( pRoot->nCell==0 && !pRoot->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3426
    Pgno subpage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3427
    assert( pRoot->pgno==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3428
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3429
    assert( subpage>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3430
    pCur->eState = CURSOR_VALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3431
    rc = moveToChild(pCur, subpage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3432
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3433
  pCur->eState = ((pCur->pPage->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3434
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3435
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3436
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3437
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3438
** Move the cursor down to the left-most leaf entry beneath the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3439
** entry to which it is currently pointing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3440
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3441
** The left-most leaf is the one with the smallest key - the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3442
** in ascending order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3443
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3444
static int moveToLeftmost(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3445
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3446
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3447
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3448
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3449
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3450
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3451
  while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3452
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3453
    pgno = get4byte(findCell(pPage, pCur->idx));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3454
    rc = moveToChild(pCur, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3455
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3456
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3457
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3458
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3459
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3460
** Move the cursor down to the right-most leaf entry beneath the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3461
** page to which it is currently pointing.  Notice the difference
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3462
** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3463
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3464
** finds the right-most entry beneath the *page*.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3465
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3466
** The right-most entry is the one with the largest key - the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3467
** key in ascending order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3468
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3469
static int moveToRightmost(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3470
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3471
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3472
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3473
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3474
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3475
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3476
  while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3477
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3478
    pCur->idx = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3479
    rc = moveToChild(pCur, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3480
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3481
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3482
    pCur->idx = pPage->nCell - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3483
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3484
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3485
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3486
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3487
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3488
/* Move the cursor to the first entry in the table.  Return SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3489
** on success.  Set *pRes to 0 if the cursor actually points to something
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3490
** or set *pRes to 1 if the table is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3491
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3492
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3493
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3494
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3495
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3496
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3497
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3498
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3499
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3500
      assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3501
      *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3502
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3503
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3504
      assert( pCur->pPage->nCell>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3505
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3506
      rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3507
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3508
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3509
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3510
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3511
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3512
/* Move the cursor to the last entry in the table.  Return SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3513
** on success.  Set *pRes to 0 if the cursor actually points to something
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3514
** or set *pRes to 1 if the table is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3515
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3516
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3517
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3518
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3519
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3520
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3521
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3522
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3523
    if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3524
      assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3525
      *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3526
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3527
      assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3528
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3529
      rc = moveToRightmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3530
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3531
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3532
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3533
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3535
/* Move the cursor so that it points to an entry near pKey/nKey.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3536
** Return a success code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3537
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3538
** For INTKEY tables, only the nKey parameter is used.  pKey is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3539
** ignored.  For other tables, nKey is the number of bytes of data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3540
** in pKey.  The comparison function specified when the cursor was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3541
** created is used to compare keys.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3542
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3543
** If an exact match is not found, then the cursor is always
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3544
** left pointing at a leaf page which would hold the entry if it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3545
** were present.  The cursor might point to an entry that comes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3546
** before or after the key.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3547
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3548
** The result of comparing the key with the entry to which the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3549
** cursor is written to *pRes if pRes!=NULL.  The meaning of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3550
** this value is as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3552
**     *pRes<0      The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3553
**                  is smaller than pKey or if the table is empty
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3554
**                  and the cursor is therefore left point to nothing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3555
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3556
**     *pRes==0     The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3557
**                  exactly matches pKey.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3558
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3559
**     *pRes>0      The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3560
**                  is larger than pKey.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3561
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3562
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3563
int sqlite3BtreeMoveto(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3564
  BtCursor *pCur,        /* The cursor to be moved */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3565
  const void *pKey,      /* The key content for indices.  Not used by tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3566
  i64 nKey,              /* Size of pKey.  Or the key for tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3567
  int biasRight,         /* If true, bias the search to the high end */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3568
  int *pRes              /* Search result flag */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3569
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3570
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3571
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3572
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3573
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3574
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3575
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3576
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3577
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3578
  assert( pCur->pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3579
  assert( pCur->pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3580
  if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3581
    *pRes = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3582
    assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3583
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3584
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3585
  for(;;){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3586
    int lwr, upr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3587
    Pgno chldPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3588
    MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3589
    int c = -1;  /* pRes return if table is empty must be -1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3590
    lwr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3591
    upr = pPage->nCell-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3592
    if( !pPage->intKey && pKey==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3593
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3594
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3595
    if( biasRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3596
      pCur->idx = upr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3597
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3598
      pCur->idx = (upr+lwr)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3599
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3600
    if( lwr<=upr ) for(;;){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3601
      void *pCellKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3602
      i64 nCellKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3603
      pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3604
      if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3605
        u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3606
        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3607
        if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3608
          u32 dummy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3609
          pCell += getVarint32(pCell, &dummy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3610
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3611
        getVarint(pCell, (u64 *)&nCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3612
        if( nCellKey<nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3613
          c = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3614
        }else if( nCellKey>nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3615
          c = +1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3616
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3617
          c = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3618
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3619
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3620
        int available;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3621
        pCellKey = (void *)fetchPayload(pCur, &available, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3622
        nCellKey = pCur->info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3623
        if( available>=nCellKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3624
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3625
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3626
          pCellKey = sqlite3_malloc( nCellKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3627
          if( pCellKey==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3628
          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3629
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3630
          sqlite3_free(pCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3631
          if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3632
            return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3633
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3634
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3635
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3636
      if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3637
        if( pPage->leafData && !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3638
          lwr = pCur->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3639
          upr = lwr - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3640
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3641
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3642
          if( pRes ) *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3643
          return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3644
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3645
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3646
      if( c<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3647
        lwr = pCur->idx+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3648
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3649
        upr = pCur->idx-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3650
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3651
      if( lwr>upr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3652
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3653
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3654
      pCur->idx = (lwr+upr)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3655
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3656
    assert( lwr==upr+1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3657
    assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3658
    if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3659
      chldPg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3660
    }else if( lwr>=pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3661
      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3662
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3663
      chldPg = get4byte(findCell(pPage, lwr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3664
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3665
    if( chldPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3666
      assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3667
      if( pRes ) *pRes = c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3668
      return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3669
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3670
    pCur->idx = lwr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3671
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3672
    rc = moveToChild(pCur, chldPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3673
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3674
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3675
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3676
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3677
  /* NOT REACHED */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3678
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3679
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3680
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3681
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3682
** Return TRUE if the cursor is not pointing at an entry of the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3683
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3684
** TRUE will be returned after a call to sqlite3BtreeNext() moves
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3685
** past the last entry in the table or sqlite3BtreePrev() moves past
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3686
** the first entry.  TRUE is also returned if the table is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3687
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3688
int sqlite3BtreeEof(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3689
  /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3690
  ** have been deleted? This API will need to change to return an error code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3691
  ** as well as the boolean result value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3692
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3693
  return (CURSOR_VALID!=pCur->eState);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3694
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3695
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3696
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3697
** Return the database connection handle for a cursor.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3698
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3699
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3700
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3701
  return pCur->pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3702
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3703
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3704
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3705
** Advance the cursor to the next entry in the database.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3706
** successful then set *pRes=0.  If the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3707
** was already pointing to the last entry in the database before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3708
** this routine was called, then set *pRes=1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3709
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3710
static int btreeNext(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3711
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3712
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3713
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3714
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3715
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3716
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3717
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3718
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3719
  assert( pRes!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3720
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3721
  if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3722
    *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3723
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3724
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3725
  if( pCur->skip>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3726
    pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3727
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3728
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3729
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3730
  pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3731
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3732
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3733
  assert( pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3734
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3735
  pCur->idx++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3736
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3737
  if( pCur->idx>=pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3738
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3739
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3740
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3741
      rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3742
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3743
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3744
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3745
    do{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3746
      if( sqlite3BtreeIsRootPage(pPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3747
        *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3748
        pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3749
        return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3750
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3751
      sqlite3BtreeMoveToParent(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3752
      pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3753
    }while( pCur->idx>=pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3754
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3755
    if( pPage->leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3756
      rc = sqlite3BtreeNext(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3757
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3758
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3759
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3760
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3761
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3762
  *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3763
  if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3764
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3765
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3766
  rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3767
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3768
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3769
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3770
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3771
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3772
  rc = btreeNext(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3773
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3774
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3775
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3776
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3777
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3778
** Step the cursor to the back to the previous entry in the database.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3779
** successful then set *pRes=0.  If the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3780
** was already pointing to the first entry in the database before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3781
** this routine was called, then set *pRes=1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3782
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3783
static int btreePrevious(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3784
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3785
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3786
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3787
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3788
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3789
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3790
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3791
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3792
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3793
  if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3794
    *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3795
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3796
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3797
  if( pCur->skip<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3798
    pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3799
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3800
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3801
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3802
  pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3803
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3804
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3805
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3806
  assert( pCur->idx>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3807
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3808
    pgno = get4byte( findCell(pPage, pCur->idx) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3809
    rc = moveToChild(pCur, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3810
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3811
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3812
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3813
    rc = moveToRightmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3814
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3815
    while( pCur->idx==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3816
      if( sqlite3BtreeIsRootPage(pPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3817
        pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3818
        *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3819
        return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3820
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3821
      sqlite3BtreeMoveToParent(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3822
      pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3823
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3824
    pCur->idx--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3825
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3826
    if( pPage->leafData && !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3827
      rc = sqlite3BtreePrevious(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3828
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3829
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3830
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3831
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3832
  *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3833
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3834
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3835
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3836
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3837
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3838
  rc = btreePrevious(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3839
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3840
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3841
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3842
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3843
** Allocate a new page from the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3844
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3845
** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3846
** has already been called on the new page.)  The new page has also
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3847
** been referenced and the calling routine is responsible for calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3848
** sqlite3PagerUnref() on the new page when it is done.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3849
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3850
** SQLITE_OK is returned on success.  Any other return value indicates
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3851
** an error.  *ppPage and *pPgno are undefined in the event of an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3852
** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3853
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3854
** If the "nearby" parameter is not 0, then a (feeble) effort is made to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3855
** locate a page close to the page number "nearby".  This can be used in an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3856
** attempt to keep related pages close to each other in the database file,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3857
** which in turn can make database access faster.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3858
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3859
** If the "exact" parameter is not 0, and the page-number nearby exists 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3860
** anywhere on the free-list, then it is guarenteed to be returned. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3861
** is only used by auto-vacuum databases when allocating a new table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3862
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3863
static int allocateBtreePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3864
  BtShared *pBt, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3865
  MemPage **ppPage, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3866
  Pgno *pPgno, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3867
  Pgno nearby,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3868
  u8 exact
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3869
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3870
  MemPage *pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3871
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3872
  int n;     /* Number of pages on the freelist */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3873
  int k;     /* Number of leaves on the trunk of the freelist */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3874
  MemPage *pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3875
  MemPage *pPrevTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3876
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3877
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3878
  pPage1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3879
  n = get4byte(&pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3880
  if( n>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3881
    /* There are pages on the freelist.  Reuse one of those pages. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3882
    Pgno iTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3883
    u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3884
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3885
    /* If the 'exact' parameter was true and a query of the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3886
    ** shows that the page 'nearby' is somewhere on the free-list, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3887
    ** the entire-list will be searched for that page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3888
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3889
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3890
    if( exact && nearby<=sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3891
      u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3892
      assert( nearby>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3893
      assert( pBt->autoVacuum );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3894
      rc = ptrmapGet(pBt, nearby, &eType, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3895
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3896
      if( eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3897
        searchList = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3898
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3899
      *pPgno = nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3900
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3901
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3902
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3903
    /* Decrement the free-list count by 1. Set iTrunk to the index of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3904
    ** first free-list trunk page. iPrevTrunk is initially 1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3905
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3906
    rc = sqlite3PagerWrite(pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3907
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3908
    put4byte(&pPage1->aData[36], n-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3909
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3910
    /* The code within this loop is run only once if the 'searchList' variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3911
    ** is not true. Otherwise, it runs once for each trunk-page on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3912
    ** free-list until the page 'nearby' is located.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3913
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3914
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3915
      pPrevTrunk = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3916
      if( pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3917
        iTrunk = get4byte(&pPrevTrunk->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3918
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3919
        iTrunk = get4byte(&pPage1->aData[32]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3920
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3921
      rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3922
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3923
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3924
        goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3925
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3926
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3927
      k = get4byte(&pTrunk->aData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3928
      if( k==0 && !searchList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3929
        /* The trunk has no leaves and the list is not being searched. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3930
        ** So extract the trunk page itself and use it as the newly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3931
        ** allocated page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3932
        assert( pPrevTrunk==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3933
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3934
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3935
          goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3936
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3937
        *pPgno = iTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3938
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3939
        *ppPage = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3940
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3941
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3942
      }else if( k>pBt->usableSize/4 - 8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3943
        /* Value of k is out of range.  Database corruption */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3944
        rc = SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3945
        goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3946
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3947
      }else if( searchList && nearby==iTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3948
        /* The list is being searched and this trunk page is the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3949
        ** to allocate, regardless of whether it has leaves.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3950
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3951
        assert( *pPgno==iTrunk );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3952
        *ppPage = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3953
        searchList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3954
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3955
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3956
          goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3957
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3958
        if( k==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3959
          if( !pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3960
            memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3961
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3962
            memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3963
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3964
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3965
          /* The trunk page is required by the caller but it contains 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3966
          ** pointers to free-list leaves. The first leaf becomes a trunk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3967
          ** page in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3968
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3969
          MemPage *pNewTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3970
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3971
          rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3972
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3973
            goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3974
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3975
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3976
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3977
            releasePage(pNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3978
            goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3979
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3980
          memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3981
          put4byte(&pNewTrunk->aData[4], k-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3982
          memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3983
          releasePage(pNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3984
          if( !pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3985
            put4byte(&pPage1->aData[32], iNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3986
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3987
            rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3988
            if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3989
              goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3990
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3991
            put4byte(&pPrevTrunk->aData[0], iNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3992
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3993
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3994
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3995
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3996
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3997
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3998
        /* Extract a leaf from the trunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3999
        int closest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4000
        Pgno iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4001
        unsigned char *aData = pTrunk->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4002
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4003
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4004
          goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4005
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4006
        if( nearby>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4007
          int i, dist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4008
          closest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4009
          dist = get4byte(&aData[8]) - nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4010
          if( dist<0 ) dist = -dist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4011
          for(i=1; i<k; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4012
            int d2 = get4byte(&aData[8+i*4]) - nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4013
            if( d2<0 ) d2 = -d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4014
            if( d2<dist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4015
              closest = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4016
              dist = d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4017
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4018
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4019
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4020
          closest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4021
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4023
        iPage = get4byte(&aData[8+closest*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4024
        if( !searchList || iPage==nearby ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4025
          *pPgno = iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4026
          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4027
            /* Free page off the end of the file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4028
            return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4029
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4030
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4031
                 ": %d more free pages\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4032
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4033
          if( closest<k-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4034
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4035
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4036
          put4byte(&aData[4], k-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4037
          rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4038
          if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4039
            sqlite3PagerDontRollback((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4040
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4041
            if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4042
              releasePage(*ppPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4043
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4044
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4045
          searchList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4046
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4047
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4048
      releasePage(pPrevTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4049
      pPrevTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4050
    }while( searchList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4051
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4052
    /* There are no pages on the freelist, so create a new page at the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4053
    ** end of the file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4054
    *pPgno = sqlite3PagerPagecount(pBt->pPager) + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4055
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4056
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4057
    if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4058
      /* An incr-vacuum has already run within this transaction. So the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4059
      ** page to allocate is not from the physical end of the file, but
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4060
      ** at pBt->nTrunc. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4061
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4062
      *pPgno = pBt->nTrunc+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4063
      if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4064
        (*pPgno)++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4065
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4066
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4067
    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4068
      /* If *pPgno refers to a pointer-map page, allocate two new pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4069
      ** at the end of the file instead of one. The first allocated page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4070
      ** becomes a new pointer-map page, the second is used by the caller.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4071
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4072
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4073
      assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4074
      (*pPgno)++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4075
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4076
    if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4077
      pBt->nTrunc = *pPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4078
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4079
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4080
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4081
    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4082
    rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4083
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4084
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4085
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4086
      releasePage(*ppPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4087
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4088
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4089
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4090
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4091
  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4092
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4093
end_allocate_page:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4094
  releasePage(pTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4095
  releasePage(pPrevTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4096
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4097
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4098
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4099
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4100
** Add a page of the database file to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4101
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4102
** sqlite3PagerUnref() is NOT called for pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4103
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4104
static int freePage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4105
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4106
  MemPage *pPage1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4107
  int rc, n, k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4108
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4109
  /* Prepare the page for freeing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4110
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4111
  assert( pPage->pgno>1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4112
  pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4113
  releasePage(pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4114
  pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4115
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4116
  /* Increment the free page count on pPage1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4117
  rc = sqlite3PagerWrite(pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4118
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4119
  n = get4byte(&pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4120
  put4byte(&pPage1->aData[36], n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4121
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4122
#ifdef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4123
  /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4124
  ** always fully overwrite deleted information with zeros.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4125
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4126
  rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4127
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4128
  memset(pPage->aData, 0, pPage->pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4129
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4130
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4131
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4132
  /* If the database supports auto-vacuum, write an entry in the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4133
  ** to indicate that the page is free.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4134
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4135
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4136
    rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4137
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4138
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4139
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4140
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4141
  if( n==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4142
    /* This is the first free page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4143
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4144
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4145
    memset(pPage->aData, 0, 8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4146
    put4byte(&pPage1->aData[32], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4147
    TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4148
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4149
    /* Other free pages already exist.  Retrive the first trunk page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4150
    ** of the freelist and find out how many leaves it has. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4151
    MemPage *pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4152
    rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4153
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4154
    k = get4byte(&pTrunk->aData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4155
    if( k>=pBt->usableSize/4 - 8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4156
      /* The trunk is full.  Turn the page being freed into a new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4157
      ** trunk page with no leaves. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4158
      rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4159
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4160
        put4byte(pPage->aData, pTrunk->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4161
        put4byte(&pPage->aData[4], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4162
        put4byte(&pPage1->aData[32], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4163
        TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4164
                pPage->pgno, pTrunk->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4165
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4166
    }else if( k<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4167
      rc = SQLITE_CORRUPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4168
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4169
      /* Add the newly freed page as a leaf on the current trunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4170
      rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4171
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4172
        put4byte(&pTrunk->aData[4], k+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4173
        put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4174
#ifndef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4175
        sqlite3PagerDontWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4176
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4177
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4178
      TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4179
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4180
    releasePage(pTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4181
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4182
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4183
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4184
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4185
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4186
** Free any overflow pages associated with the given Cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4187
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4188
static int clearCell(MemPage *pPage, unsigned char *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4189
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4190
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4191
  Pgno ovflPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4192
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4193
  int nOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4194
  int ovflPageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4196
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4197
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4198
  if( info.iOverflow==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4199
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4200
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4201
  ovflPgno = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4202
  ovflPageSize = pBt->usableSize - 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4203
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4204
  assert( ovflPgno==0 || nOvfl>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4205
  while( nOvfl-- ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4206
    MemPage *pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4207
    if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4208
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4209
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4210
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4211
    rc = getOverflowPage(pBt, ovflPgno, &pOvfl, (nOvfl==0)?0:&ovflPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4212
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4213
    rc = freePage(pOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4214
    sqlite3PagerUnref(pOvfl->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4215
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4216
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4217
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4218
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4220
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4221
** Create the byte sequence used to represent a cell on page pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4222
** and write that byte sequence into pCell[].  Overflow pages are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4223
** allocated and filled in as necessary.  The calling procedure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4224
** is responsible for making sure sufficient space has been allocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4225
** for pCell[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4226
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4227
** Note that pCell does not necessary need to point to the pPage->aData
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4228
** area.  pCell might point to some temporary storage.  The cell will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4229
** be constructed in this temporary area then copied into pPage->aData
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4230
** later.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4231
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4232
static int fillInCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4233
  MemPage *pPage,                /* The page that contains the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4234
  unsigned char *pCell,          /* Complete text of the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4235
  const void *pKey, i64 nKey,    /* The key */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4236
  const void *pData,int nData,   /* The data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4237
  int nZero,                     /* Extra zero bytes to append to pData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4238
  int *pnSize                    /* Write cell size here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4239
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4240
  int nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4241
  const u8 *pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4242
  int nSrc, n, rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4243
  int spaceLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4244
  MemPage *pOvfl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4245
  MemPage *pToRelease = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4246
  unsigned char *pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4247
  unsigned char *pPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4248
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4249
  Pgno pgnoOvfl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4250
  int nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4251
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4252
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4253
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4254
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4255
  /* Fill in the header. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4256
  nHeader = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4257
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4258
    nHeader += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4259
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4260
  if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4261
    nHeader += putVarint(&pCell[nHeader], nData+nZero);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4262
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4263
    nData = nZero = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4265
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4266
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4267
  assert( info.nHeader==nHeader );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4268
  assert( info.nKey==nKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4269
  assert( info.nData==nData+nZero );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4270
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4271
  /* Fill in the payload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4272
  nPayload = nData + nZero;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4273
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4274
    pSrc = (const u8*)pData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4275
    nSrc = nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4276
    nData = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4277
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4278
    nPayload += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4279
    pSrc = (const u8*)pKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4280
    nSrc = nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4281
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4282
  *pnSize = info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4283
  spaceLeft = info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4284
  pPayload = &pCell[nHeader];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4285
  pPrior = &pCell[info.iOverflow];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4286
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4287
  while( nPayload>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4288
    if( spaceLeft==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4289
      int isExact = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4290
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4291
      Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4292
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4293
        do{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4294
          pgnoOvfl++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4295
        } while( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4296
          PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4297
        );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4298
        if( pgnoOvfl>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4299
          /* isExact = 1; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4300
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4301
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4302
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4303
      rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, isExact);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4304
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4305
      /* If the database supports auto-vacuum, and the second or subsequent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4306
      ** overflow page is being allocated, add an entry to the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4307
      ** for that page now. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4308
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4309
      ** If this is the first overflow page, then write a partial entry 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4310
      ** to the pointer-map. If we write nothing to this pointer-map slot,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4311
      ** then the optimistic overflow chain processing in clearCell()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4312
      ** may misinterpret the uninitialised values and delete the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4313
      ** wrong pages from the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4314
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4315
      if( pBt->autoVacuum && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4316
        u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4317
        rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4318
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4319
          releasePage(pOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4320
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4321
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4322
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4323
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4324
        releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4325
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4326
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4327
      put4byte(pPrior, pgnoOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4328
      releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4329
      pToRelease = pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4330
      pPrior = pOvfl->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4331
      put4byte(pPrior, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4332
      pPayload = &pOvfl->aData[4];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4333
      spaceLeft = pBt->usableSize - 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4334
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4335
    n = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4336
    if( n>spaceLeft ) n = spaceLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4337
    if( nSrc>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4338
      if( n>nSrc ) n = nSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4339
      assert( pSrc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4340
      memcpy(pPayload, pSrc, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4341
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4342
      memset(pPayload, 0, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4343
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4344
    nPayload -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4345
    pPayload += n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4346
    pSrc += n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4347
    nSrc -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4348
    spaceLeft -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4349
    if( nSrc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4350
      nSrc = nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4351
      pSrc = (u8*)pData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4352
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4353
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4354
  releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4355
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4356
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4357
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4358
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4359
** Change the MemPage.pParent pointer on the page whose number is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4360
** given in the second argument so that MemPage.pParent holds the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4361
** pointer in the third argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4362
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4363
static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4364
  MemPage *pThis;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4365
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4366
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4367
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4368
  assert( pNewParent!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4369
  if( pgno==0 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4370
  assert( pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4371
  pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4372
  if( pDbPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4373
    pThis = (MemPage *)sqlite3PagerGetExtra(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4374
    if( pThis->isInit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4375
      assert( pThis->aData==sqlite3PagerGetData(pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4376
      if( pThis->pParent!=pNewParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4377
        if( pThis->pParent ) sqlite3PagerUnref(pThis->pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4378
        pThis->pParent = pNewParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4379
        sqlite3PagerRef(pNewParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4380
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4381
      pThis->idxParent = idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4382
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4383
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4384
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4385
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4386
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4387
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4388
    return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4389
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4390
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4391
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4392
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4393
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4394
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4395
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4396
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4397
** Change the pParent pointer of all children of pPage to point back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4398
** to pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4399
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4400
** In other words, for every child of pPage, invoke reparentPage()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4401
** to make sure that each child knows that pPage is its parent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4402
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4403
** This routine gets called after you memcpy() one page into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4404
** another.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4405
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4406
static int reparentChildPages(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4407
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4408
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4409
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4410
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4411
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4412
  if( pPage->leaf ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4413
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4414
  for(i=0; i<pPage->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4415
    u8 *pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4416
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4417
      rc = reparentPage(pBt, get4byte(pCell), pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4418
      if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4419
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4420
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4421
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4422
    rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4423
       pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4424
    pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4425
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4426
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4427
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4428
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4429
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4430
** Remove the i-th cell from pPage.  This routine effects pPage only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4431
** The cell content is not freed or deallocated.  It is assumed that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4432
** the cell content has been copied someplace else.  This routine just
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4433
** removes the reference to the cell from pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4434
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4435
** "sz" must be the number of bytes in the cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4436
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4437
static void dropCell(MemPage *pPage, int idx, int sz){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4438
  int i;          /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4439
  int pc;         /* Offset to cell content of cell being deleted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4440
  u8 *data;       /* pPage->aData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4441
  u8 *ptr;        /* Used to move bytes around within data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4442
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4443
  assert( idx>=0 && idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4444
  assert( sz==cellSize(pPage, idx) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4445
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4446
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4447
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4448
  ptr = &data[pPage->cellOffset + 2*idx];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4449
  pc = get2byte(ptr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4450
  assert( pc>10 && pc+sz<=pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4451
  freeSpace(pPage, pc, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4452
  for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4453
    ptr[0] = ptr[2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4454
    ptr[1] = ptr[3];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4455
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4456
  pPage->nCell--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4457
  put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4458
  pPage->nFree += 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4459
  pPage->idxShift = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4460
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4461
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4462
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4463
** Insert a new cell on pPage at cell index "i".  pCell points to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4464
** content of the cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4465
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4466
** If the cell content will fit on the page, then put it there.  If it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4467
** will not fit, then make a copy of the cell content into pTemp if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4468
** pTemp is not null.  Regardless of pTemp, allocate a new entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4469
** in pPage->aOvfl[] and make it point to the cell content (either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4470
** in pTemp or the original pCell) and also record its index. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4471
** Allocating a new entry in pPage->aCell[] implies that 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4472
** pPage->nOverflow is incremented.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4473
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4474
** If nSkip is non-zero, then do not copy the first nSkip bytes of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4475
** cell. The caller will overwrite them after this function returns. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4476
** nSkip is non-zero, then pCell may not point to an invalid memory location 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4477
** (but pCell+nSkip is always valid).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4478
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4479
static int insertCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4480
  MemPage *pPage,   /* Page into which we are copying */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4481
  int i,            /* New cell becomes the i-th cell of the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4482
  u8 *pCell,        /* Content of the new cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4483
  int sz,           /* Bytes of content in pCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4484
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4485
  u8 nSkip          /* Do not write the first nSkip bytes of the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4486
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4487
  int idx;          /* Where to write new cell content in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4488
  int j;            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4489
  int top;          /* First byte of content for any cell in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4490
  int end;          /* First byte past the last cell pointer in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4491
  int ins;          /* Index in data[] where new cell pointer is inserted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4492
  int hdr;          /* Offset into data[] of the page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4493
  int cellOffset;   /* Address of first cell pointer in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4494
  u8 *data;         /* The content of the whole page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4495
  u8 *ptr;          /* Used for moving information around in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4496
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4497
  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4498
  assert( sz==cellSizePtr(pPage, pCell) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4499
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4500
  if( pPage->nOverflow || sz+2>pPage->nFree ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4501
    if( pTemp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4502
      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4503
      pCell = pTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4504
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4505
    j = pPage->nOverflow++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4506
    assert( j<sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4507
    pPage->aOvfl[j].pCell = pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4508
    pPage->aOvfl[j].idx = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4509
    pPage->nFree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4510
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4511
    int rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4512
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4513
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4514
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4515
    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4516
    data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4517
    hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4518
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4519
    cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4520
    end = cellOffset + 2*pPage->nCell + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4521
    ins = cellOffset + 2*i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4522
    if( end > top - sz ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4523
      rc = defragmentPage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4524
      if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4525
      top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4526
      assert( end + sz <= top );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4527
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4528
    idx = allocateSpace(pPage, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4529
    assert( idx>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4530
    assert( end <= get2byte(&data[hdr+5]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4531
    pPage->nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4532
    pPage->nFree -= 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4533
    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4534
    for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4535
      ptr[0] = ptr[-2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4536
      ptr[1] = ptr[-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4537
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4538
    put2byte(&data[ins], idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4539
    put2byte(&data[hdr+3], pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4540
    pPage->idxShift = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4541
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4542
    if( pPage->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4543
      /* The cell may contain a pointer to an overflow page. If so, write
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4544
      ** the entry for the overflow page into the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4545
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4546
      CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4547
      sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4548
      assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4549
      if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4550
        Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4551
        rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4552
        if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4553
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4554
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4555
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4556
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4557
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4558
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4559
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4560
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4561
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4562
** Add a list of cells to a page.  The page should be initially empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4563
** The cells are guaranteed to fit on the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4564
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4565
static void assemblePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4566
  MemPage *pPage,   /* The page to be assemblied */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4567
  int nCell,        /* The number of cells to add to this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4568
  u8 **apCell,      /* Pointers to cell bodies */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4569
  int *aSize        /* Sizes of the cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4570
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4571
  int i;            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4572
  int totalSize;    /* Total size of all cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4573
  int hdr;          /* Index of page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4574
  int cellptr;      /* Address of next cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4575
  int cellbody;     /* Address of next cell body */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4576
  u8 *data;         /* Data for the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4577
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4578
  assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4579
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4580
  totalSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4581
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4582
    totalSize += aSize[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4583
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4584
  assert( totalSize+2*nCell<=pPage->nFree );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4585
  assert( pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4586
  cellptr = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4587
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4588
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4589
  put2byte(&data[hdr+3], nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4590
  if( nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4591
    cellbody = allocateSpace(pPage, totalSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4592
    assert( cellbody>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4593
    assert( pPage->nFree >= 2*nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4594
    pPage->nFree -= 2*nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4595
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4596
      put2byte(&data[cellptr], cellbody);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4597
      memcpy(&data[cellbody], apCell[i], aSize[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4598
      cellptr += 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4599
      cellbody += aSize[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4600
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4601
    assert( cellbody==pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4602
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4603
  pPage->nCell = nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4604
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4605
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4606
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4607
** The following parameters determine how many adjacent pages get involved
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4608
** in a balancing operation.  NN is the number of neighbors on either side
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4609
** of the page that participate in the balancing operation.  NB is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4610
** total number of pages that participate, including the target page and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4611
** NN neighbors on either side.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4612
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4613
** The minimum value of NN is 1 (of course).  Increasing NN above 1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4614
** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4615
** in exchange for a larger degradation in INSERT and UPDATE performance.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4616
** The value of NN appears to give the best results overall.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4617
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4618
#define NN 1             /* Number of neighbors on either side of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4619
#define NB (NN*2+1)      /* Total pages involved in the balance */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4620
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4621
/* Forward reference */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4622
static int balance(MemPage*, int);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4623
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4624
#ifndef SQLITE_OMIT_QUICKBALANCE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4625
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4626
** This version of balance() handles the common special case where
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4627
** a new entry is being inserted on the extreme right-end of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4628
** tree, in other words, when the new entry will become the largest
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4629
** entry in the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4630
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4631
** Instead of trying balance the 3 right-most leaf pages, just add
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4632
** a new page to the right-hand side and put the one new entry in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4633
** that page.  This leaves the right side of the tree somewhat
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4634
** unbalanced.  But odds are that we will be inserting new entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4635
** at the end soon afterwards so the nearly empty page will quickly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4636
** fill up.  On average.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4637
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4638
** pPage is the leaf page which is the right-most page in the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4639
** pParent is its parent.  pPage must have a single overflow entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4640
** which is also the right-most entry on the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4641
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4642
static int balance_quick(MemPage *pPage, MemPage *pParent){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4643
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4644
  MemPage *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4645
  Pgno pgnoNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4646
  u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4647
  int szCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4648
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4649
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4650
  int parentIdx = pParent->nCell;   /* pParent new divider cell index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4651
  int parentSize;                   /* Size of new divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4652
  u8 parentCell[64];                /* Space for the new divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4653
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4654
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4656
  /* Allocate a new page. Insert the overflow cell from pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4657
  ** into it. Then remove the overflow cell from pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4658
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4659
  rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4660
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4661
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4662
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4663
  pCell = pPage->aOvfl[0].pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4664
  szCell = cellSizePtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4665
  zeroPage(pNew, pPage->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4666
  assemblePage(pNew, 1, &pCell, &szCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4667
  pPage->nOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4668
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4669
  /* Set the parent of the newly allocated page to pParent. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4670
  pNew->pParent = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4671
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4673
  /* pPage is currently the right-child of pParent. Change this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4674
  ** so that the right-child is the new page allocated above and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4675
  ** pPage is the next-to-right child. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4676
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4677
  assert( pPage->nCell>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4678
  pCell = findCell(pPage, pPage->nCell-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4679
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4680
  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4681
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4682
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4683
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4684
  assert( parentSize<64 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4685
  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4686
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4687
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4688
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4689
  put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4690
  put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4691
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4692
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4693
  /* If this is an auto-vacuum database, update the pointer map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4694
  ** with entries for the new page, and any pointer from the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4695
  ** cell on the page to an overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4696
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4697
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4698
    rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4699
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4700
      rc = ptrmapPutOvfl(pNew, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4701
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4702
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4703
      releasePage(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4704
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4705
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4706
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4707
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4708
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4709
  /* Release the reference to the new page and balance the parent page,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4710
  ** in case the divider cell inserted caused it to become overfull.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4711
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4712
  releasePage(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4713
  return balance(pParent, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4714
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4715
#endif /* SQLITE_OMIT_QUICKBALANCE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4716
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4717
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4718
** This routine redistributes Cells on pPage and up to NN*2 siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4719
** of pPage so that all pages have about the same amount of free space.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4720
** Usually NN siblings on either side of pPage is used in the balancing,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4721
** though more siblings might come from one side if pPage is the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4722
** or last child of its parent.  If pPage has fewer than 2*NN siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4723
** (something which can only happen if pPage is the root page or a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4724
** child of root) then all available siblings participate in the balancing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4725
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4726
** The number of siblings of pPage might be increased or decreased by one or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4727
** two in an effort to keep pages nearly full but not over full. The root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4728
** is special and is allowed to be nearly empty. If pPage is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4729
** the root page, then the depth of the tree might be increased
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4730
** or decreased by one, as necessary, to keep the root page from being
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4731
** overfull or completely empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4732
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4733
** Note that when this routine is called, some of the Cells on pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4734
** might not actually be stored in pPage->aData[].  This can happen
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4735
** if the page is overfull.  Part of the job of this routine is to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4736
** make sure all Cells for pPage once again fit in pPage->aData[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4737
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4738
** In the course of balancing the siblings of pPage, the parent of pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4739
** might become overfull or underfull.  If that happens, then this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4740
** is called recursively on the parent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4741
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4742
** If this routine fails for any reason, it might leave the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4743
** in a corrupted state.  So if this routine fails, the database should
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4744
** be rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4745
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4746
static int balance_nonroot(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4747
  MemPage *pParent;            /* The parent of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4748
  BtShared *pBt;               /* The whole database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4749
  int nCell = 0;               /* Number of cells in apCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4750
  int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4751
  int nOld;                    /* Number of pages in apOld[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4752
  int nNew;                    /* Number of pages in apNew[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4753
  int nDiv;                    /* Number of cells in apDiv[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4754
  int i, j, k;                 /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4755
  int idx;                     /* Index of pPage in pParent->aCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4756
  int nxDiv;                   /* Next divider slot in pParent->aCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4757
  int rc;                      /* The return code */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4758
  int leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4759
  int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4760
  int usableSpace;             /* Bytes in pPage beyond the header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4761
  int pageFlags;               /* Value of pPage->aData[0] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4762
  int subtotal;                /* Subtotal of bytes in cells on one page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4763
  int iSpace = 0;              /* First unused byte of aSpace[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4764
  MemPage *apOld[NB];          /* pPage and up to two siblings */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4765
  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4766
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4767
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4768
  Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4769
  u8 *apDiv[NB];               /* Divider cells in pParent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4770
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4771
  int szNew[NB+2];             /* Combined size of cells place on i-th page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4772
  u8 **apCell = 0;             /* All cells begin balanced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4773
  int *szCell;                 /* Local size of all cells in apCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4774
  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4775
  u8 *aSpace;                  /* Space to hold copies of dividers cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4776
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4777
  u8 *aFrom = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4778
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4779
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4780
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4781
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4782
  /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4783
  ** Find the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4784
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4785
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4786
  assert( sqlite3PagerIswriteable(pPage->pDbPage) || pPage->nOverflow==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4787
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4788
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4789
  assert( pParent );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4790
  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4791
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4792
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4793
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4795
#ifndef SQLITE_OMIT_QUICKBALANCE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4796
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4797
  ** A special case:  If a new entry has just been inserted into a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4798
  ** table (that is, a btree with integer keys and all data at the leaves)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4799
  ** and the new entry is the right-most entry in the tree (it has the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4800
  ** largest key) then use the special balance_quick() routine for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4801
  ** balancing.  balance_quick() is much faster and results in a tighter
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4802
  ** packing of data in the common case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4803
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4804
  if( pPage->leaf &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4805
      pPage->intKey &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4806
      pPage->leafData &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4807
      pPage->nOverflow==1 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4808
      pPage->aOvfl[0].idx==pPage->nCell &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4809
      pPage->pParent->pgno!=1 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4810
      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4811
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4812
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4813
    ** TODO: Check the siblings to the left of pPage. It may be that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4814
    ** they are not full and no new page is required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4815
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4816
    return balance_quick(pPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4817
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4818
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4819
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4820
  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4821
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4822
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4823
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4824
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4825
  ** Find the cell in the parent page whose left child points back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4826
  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4827
  ** is the rightmost child of pParent then set idx to pParent->nCell 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4828
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4829
  if( pParent->idxShift ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4830
    Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4831
    pgno = pPage->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4832
    assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4833
    for(idx=0; idx<pParent->nCell; idx++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4834
      if( get4byte(findCell(pParent, idx))==pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4835
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4836
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4837
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4838
    assert( idx<pParent->nCell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4839
             || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4840
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4841
    idx = pPage->idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4842
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4843
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4844
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4845
  ** Initialize variables so that it will be safe to jump
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4846
  ** directly to balance_cleanup at any moment.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4847
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4848
  nOld = nNew = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4849
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4850
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4851
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4852
  ** Find sibling pages to pPage and the cells in pParent that divide
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4853
  ** the siblings.  An attempt is made to find NN siblings on either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4854
  ** side of pPage.  More siblings are taken from one side, however, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4855
  ** pPage there are fewer than NN siblings on the other side.  If pParent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4856
  ** has NB or fewer children then all children of pParent are taken.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4857
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4858
  nxDiv = idx - NN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4859
  if( nxDiv + NB > pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4860
    nxDiv = pParent->nCell - NB + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4861
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4862
  if( nxDiv<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4863
    nxDiv = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4864
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4865
  nDiv = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4866
  for(i=0, k=nxDiv; i<NB; i++, k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4867
    if( k<pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4868
      apDiv[i] = findCell(pParent, k);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4869
      nDiv++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4870
      assert( !pParent->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4871
      pgnoOld[i] = get4byte(apDiv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4872
    }else if( k==pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4873
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4874
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4875
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4876
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4877
    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4878
    if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4879
    apOld[i]->idxParent = k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4880
    apCopy[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4881
    assert( i==nOld );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4882
    nOld++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4883
    nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4884
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4885
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4886
  /* Make nMaxCells a multiple of 2 in order to preserve 8-byte
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4887
  ** alignment */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4888
  nMaxCells = (nMaxCells + 1)&~1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4889
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4890
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4891
  ** Allocate space for memory structures
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4892
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4893
  apCell = (u8**)sqlite3_malloc( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4894
       nMaxCells*sizeof(u8*)                           /* apCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4895
     + nMaxCells*sizeof(int)                           /* szCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4896
     + ROUND8(sizeof(MemPage))*NB                      /* aCopy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4897
     + pBt->pageSize*(5+NB)                            /* aSpace */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4898
     + (ISAUTOVACUUM ? nMaxCells : 0)                  /* aFrom */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4899
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4900
  if( apCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4901
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4902
    goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4903
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4904
  szCell = (int*)&apCell[nMaxCells];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4905
  aCopy[0] = (u8*)&szCell[nMaxCells];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4906
  assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4907
  for(i=1; i<NB; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4908
    aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4909
    assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4910
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4911
  aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4912
  assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4913
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4914
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4915
    aFrom = &aSpace[5*pBt->pageSize];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4916
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4917
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4918
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4919
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4920
  ** Make copies of the content of pPage and its siblings into aOld[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4921
  ** The rest of this function will use data from the copies rather
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4922
  ** that the original pages since the original pages will be in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4923
  ** process of being overwritten.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4924
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4925
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4926
    MemPage *p = apCopy[i] = (MemPage*)aCopy[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4927
    memcpy(p, apOld[i], sizeof(MemPage));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4928
    p->aData = (u8*)(void*)&p[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4929
    memcpy(p->aData, apOld[i]->aData, pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4930
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4931
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4932
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4933
  ** Load pointers to all cells on sibling pages and the divider cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4934
  ** into the local apCell[] array.  Make copies of the divider cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4935
  ** into space obtained form aSpace[] and remove the the divider Cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4936
  ** from pParent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4937
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4938
  ** If the siblings are on leaf pages, then the child pointers of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4939
  ** divider cells are stripped from the cells before they are copied
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4940
  ** into aSpace[].  In this way, all cells in apCell[] are without
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4941
  ** child pointers.  If siblings are not leaves, then all cell in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4942
  ** apCell[] include child pointers.  Either way, all cells in apCell[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4943
  ** are alike.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4944
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4945
  ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4946
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4947
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4948
  nCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4949
  leafCorrection = pPage->leaf*4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4950
  leafData = pPage->leafData && pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4951
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4952
    MemPage *pOld = apCopy[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4953
    int limit = pOld->nCell+pOld->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4954
    for(j=0; j<limit; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4955
      assert( nCell<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4956
      apCell[nCell] = findOverflowCell(pOld, j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4957
      szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4958
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4959
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4960
        int a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4961
        aFrom[nCell] = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4962
        for(a=0; a<pOld->nOverflow; a++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4963
          if( pOld->aOvfl[a].pCell==apCell[nCell] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4964
            aFrom[nCell] = 0xFF;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4965
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4966
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4967
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4968
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4969
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4970
      nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4971
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4972
    if( i<nOld-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4973
      int sz = cellSizePtr(pParent, apDiv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4974
      if( leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4975
        /* With the LEAFDATA flag, pParent cells hold only INTKEYs that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4976
        ** are duplicates of keys on the child pages.  We need to remove
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4977
        ** the divider cells from pParent, but the dividers cells are not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4978
        ** added to apCell[] because they are duplicates of child cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4979
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4980
        dropCell(pParent, nxDiv, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4981
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4982
        u8 *pTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4983
        assert( nCell<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4984
        szCell[nCell] = sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4985
        pTemp = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4986
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4987
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4988
        memcpy(pTemp, apDiv[i], sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4989
        apCell[nCell] = pTemp+leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4990
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4991
        if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4992
          aFrom[nCell] = 0xFF;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4993
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4994
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4995
        dropCell(pParent, nxDiv, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4996
        szCell[nCell] -= leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4997
        assert( get4byte(pTemp)==pgnoOld[i] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4998
        if( !pOld->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4999
          assert( leafCorrection==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5000
          /* The right pointer of the child page pOld becomes the left
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5001
          ** pointer of the divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5002
          memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5003
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5004
          assert( leafCorrection==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5005
          if( szCell[nCell]<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5006
            /* Do not allow any cells smaller than 4 bytes. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5007
            szCell[nCell] = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5008
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5009
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5010
        nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5011
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5012
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5013
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5014
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5015
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5016
  ** Figure out the number of pages needed to hold all nCell cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5017
  ** Store this number in "k".  Also compute szNew[] which is the total
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5018
  ** size of all cells on the i-th page and cntNew[] which is the index
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5019
  ** in apCell[] of the cell that divides page i from page i+1.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5020
  ** cntNew[k] should equal nCell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5021
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5022
  ** Values computed by this block:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5023
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5024
  **           k: The total number of sibling pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5025
  **    szNew[i]: Spaced used on the i-th sibling page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5026
  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5027
  **              the right of the i-th sibling page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5028
  ** usableSpace: Number of bytes of space available on each sibling.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5029
  ** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5030
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5031
  usableSpace = pBt->usableSize - 12 + leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5032
  for(subtotal=k=i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5033
    assert( i<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5034
    subtotal += szCell[i] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5035
    if( subtotal > usableSpace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5036
      szNew[k] = subtotal - szCell[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5037
      cntNew[k] = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5038
      if( leafData ){ i--; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5039
      subtotal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5040
      k++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5041
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5042
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5043
  szNew[k] = subtotal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5044
  cntNew[k] = nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5045
  k++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5046
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5047
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5048
  ** The packing computed by the previous block is biased toward the siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5049
  ** on the left side.  The left siblings are always nearly full, while the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5050
  ** right-most sibling might be nearly empty.  This block of code attempts
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5051
  ** to adjust the packing of siblings to get a better balance.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5052
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5053
  ** This adjustment is more than an optimization.  The packing above might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5054
  ** be so out of balance as to be illegal.  For example, the right-most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5055
  ** sibling might be completely empty.  This adjustment is not optional.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5056
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5057
  for(i=k-1; i>0; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5058
    int szRight = szNew[i];  /* Size of sibling on the right */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5059
    int szLeft = szNew[i-1]; /* Size of sibling on the left */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5060
    int r;              /* Index of right-most cell in left sibling */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5061
    int d;              /* Index of first cell to the left of right sibling */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5062
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5063
    r = cntNew[i-1] - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5064
    d = r + 1 - leafData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5065
    assert( d<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5066
    assert( r<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5067
    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5068
      szRight += szCell[d] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5069
      szLeft -= szCell[r] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5070
      cntNew[i-1]--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5071
      r = cntNew[i-1] - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5072
      d = r + 1 - leafData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5073
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5074
    szNew[i] = szRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5075
    szNew[i-1] = szLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5076
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5077
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5078
  /* Either we found one or more cells (cntnew[0])>0) or we are the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5079
  ** a virtual root page.  A virtual root page is when the real root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5080
  ** page is page 1 and we are the only child of that page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5081
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5082
  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5083
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5084
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5085
  ** Allocate k new pages.  Reuse old pages where possible.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5086
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5087
  assert( pPage->pgno>1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5088
  pageFlags = pPage->aData[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5089
  for(i=0; i<k; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5090
    MemPage *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5091
    if( i<nOld ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5092
      pNew = apNew[i] = apOld[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5093
      pgnoNew[i] = pgnoOld[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5094
      apOld[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5095
      rc = sqlite3PagerWrite(pNew->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5096
      nNew++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5097
      if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5098
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5099
      assert( i>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5100
      rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5101
      if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5102
      apNew[i] = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5103
      nNew++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5104
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5105
    zeroPage(pNew, pageFlags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5106
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5107
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5108
  /* Free any old pages that were not reused as new pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5109
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5110
  while( i<nOld ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5111
    rc = freePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5112
    if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5113
    releasePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5114
    apOld[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5115
    i++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5116
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5118
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5119
  ** Put the new pages in accending order.  This helps to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5120
  ** keep entries in the disk file in order so that a scan
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5121
  ** of the table is a linear scan through the file.  That
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5122
  ** in turn helps the operating system to deliver pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5123
  ** from the disk more rapidly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5124
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5125
  ** An O(n^2) insertion sort algorithm is used, but since
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5126
  ** n is never more than NB (a small constant), that should
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5127
  ** not be a problem.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5128
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5129
  ** When NB==3, this one optimization makes the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5130
  ** about 25% faster for large insertions and deletions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5131
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5132
  for(i=0; i<k-1; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5133
    int minV = pgnoNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5134
    int minI = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5135
    for(j=i+1; j<k; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5136
      if( pgnoNew[j]<(unsigned)minV ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5137
        minI = j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5138
        minV = pgnoNew[j];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5139
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5140
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5141
    if( minI>i ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5142
      int t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5143
      MemPage *pT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5144
      t = pgnoNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5145
      pT = apNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5146
      pgnoNew[i] = pgnoNew[minI];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5147
      apNew[i] = apNew[minI];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5148
      pgnoNew[minI] = t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5149
      apNew[minI] = pT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5150
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5151
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5152
  TRACE(("BALANCE: old: %d %d %d  new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5153
    pgnoOld[0], 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5154
    nOld>=2 ? pgnoOld[1] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5155
    nOld>=3 ? pgnoOld[2] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5156
    pgnoNew[0], szNew[0],
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5157
    nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5158
    nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5159
    nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5160
    nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5161
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5162
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5163
  ** Evenly distribute the data in apCell[] across the new pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5164
  ** Insert divider cells into pParent as necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5165
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5166
  j = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5167
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5168
    /* Assemble the new sibling page. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5169
    MemPage *pNew = apNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5170
    assert( j<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5171
    assert( pNew->pgno==pgnoNew[i] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5172
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5173
    assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5174
    assert( pNew->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5175
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5176
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5177
    /* If this is an auto-vacuum database, update the pointer map entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5178
    ** that point to the siblings that were rearranged. These can be: left
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5179
    ** children of cells, the right-child of the page, or overflow pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5180
    ** pointed to by cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5181
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5182
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5183
      for(k=j; k<cntNew[i]; k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5184
        assert( k<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5185
        if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5186
          rc = ptrmapPutOvfl(pNew, k-j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5187
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5188
            goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5189
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5190
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5191
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5192
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5193
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5194
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5195
    j = cntNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5196
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5197
    /* If the sibling page assembled above was not the right-most sibling,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5198
    ** insert a divider cell into the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5199
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5200
    if( i<nNew-1 && j<nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5201
      u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5202
      u8 *pTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5203
      int sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5205
      assert( j<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5206
      pCell = apCell[j];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5207
      sz = szCell[j] + leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5208
      if( !pNew->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5209
        memcpy(&pNew->aData[8], pCell, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5210
        pTemp = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5211
      }else if( leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5212
        /* If the tree is a leaf-data tree, and the siblings are leaves, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5213
        ** then there is no divider cell in apCell[]. Instead, the divider 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5214
        ** cell consists of the integer key for the right-most cell of 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5215
        ** the sibling-page assembled above only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5216
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5217
        CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5218
        j--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5219
        sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5220
        pCell = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5221
        fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5222
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5223
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5224
        pTemp = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5225
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5226
        pCell -= 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5227
        pTemp = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5228
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5229
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5230
        /* Obscure case for non-leaf-data trees: If the cell at pCell was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5231
        ** previously stored on a leaf node, and its reported size was 4
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5232
        ** bytes, then it may actually be smaller than this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5233
        ** (see sqlite3BtreeParseCellPtr(), 4 bytes is the minimum size of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5234
        ** any cell). But it is important to pass the correct size to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5235
        ** insertCell(), so reparse the cell now.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5236
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5237
        ** Note that this can never happen in an SQLite data file, as all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5238
        ** cells are at least 4 bytes. It only happens in b-trees used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5239
        ** to evaluate "IN (SELECT ...)" and similar clauses.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5240
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5241
        if( szCell[j]==4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5242
          assert(leafCorrection==4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5243
          sz = cellSizePtr(pParent, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5244
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5245
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5246
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5247
      if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5248
      put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5249
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5250
      /* If this is an auto-vacuum database, and not a leaf-data tree,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5251
      ** then update the pointer map with an entry for the overflow page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5252
      ** that the cell just inserted points to (if any).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5253
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5254
      if( pBt->autoVacuum && !leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5255
        rc = ptrmapPutOvfl(pParent, nxDiv);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5256
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5257
          goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5258
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5259
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5260
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5261
      j++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5262
      nxDiv++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5263
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5265
  assert( j==nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5266
  assert( nOld>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5267
  assert( nNew>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5268
  if( (pageFlags & PTF_LEAF)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5269
    memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5270
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5271
  if( nxDiv==pParent->nCell+pParent->nOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5272
    /* Right-most sibling is the right-most child of pParent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5273
    put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5274
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5275
    /* Right-most sibling is the left child of the first entry in pParent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5276
    ** past the right-most divider entry */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5277
    put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5278
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5279
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5280
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5281
  ** Reparent children of all cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5282
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5283
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5284
    rc = reparentChildPages(apNew[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5285
    if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5286
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5287
  rc = reparentChildPages(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5288
  if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5289
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5290
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5291
  ** Balance the parent page.  Note that the current page (pPage) might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5292
  ** have been added to the freelist so it might no longer be initialized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5293
  ** But the parent page will always be initialized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5294
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5295
  assert( pParent->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5296
  rc = balance(pParent, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5297
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5298
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5299
  ** Cleanup before returning.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5300
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5301
balance_cleanup:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5302
  sqlite3_free(apCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5303
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5304
    releasePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5305
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5306
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5307
    releasePage(apNew[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5308
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5309
  releasePage(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5310
  TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5311
          pPage->pgno, nOld, nNew, nCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5312
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5313
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5316
** This routine is called for the root page of a btree when the root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5317
** page contains no cells.  This is an opportunity to make the tree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5318
** shallower by one level.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5319
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5320
static int balance_shallower(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5321
  MemPage *pChild;             /* The only child page of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5322
  Pgno pgnoChild;              /* Page number for pChild */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5323
  int rc = SQLITE_OK;          /* Return code from subprocedures */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5324
  BtShared *pBt;                  /* The main BTree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5325
  int mxCellPerPage;           /* Maximum number of cells per page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5326
  u8 **apCell;                 /* All cells from pages being balanced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5327
  int *szCell;                 /* Local size of all cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5328
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5329
  assert( pPage->pParent==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5330
  assert( pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5331
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5332
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5333
  mxCellPerPage = MX_CELL(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5334
  apCell = (u8**)sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5335
  if( apCell==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5336
  szCell = (int*)&apCell[mxCellPerPage];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5337
  if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5338
    /* The table is completely empty */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5339
    TRACE(("BALANCE: empty table %d\n", pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5340
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5341
    /* The root page is empty but has one child.  Transfer the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5342
    ** information from that one child into the root page if it 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5343
    ** will fit.  This reduces the depth of the tree by one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5344
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5345
    ** If the root page is page 1, it has less space available than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5346
    ** its child (due to the 100 byte header that occurs at the beginning
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5347
    ** of the database fle), so it might not be able to hold all of the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5348
    ** information currently contained in the child.  If this is the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5349
    ** case, then do not do the transfer.  Leave page 1 empty except
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5350
    ** for the right-pointer to the child page.  The child page becomes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5351
    ** the virtual root of the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5352
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5353
    pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5354
    assert( pgnoChild>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5355
    assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5356
    rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5357
    if( rc ) goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5358
    if( pPage->pgno==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5359
      rc = sqlite3BtreeInitPage(pChild, pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5360
      if( rc ) goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5361
      assert( pChild->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5362
      if( pChild->nFree>=100 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5363
        /* The child information will fit on the root page, so do the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5364
        ** copy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5365
        int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5366
        zeroPage(pPage, pChild->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5367
        for(i=0; i<pChild->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5368
          apCell[i] = findCell(pChild,i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5369
          szCell[i] = cellSizePtr(pChild, apCell[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5370
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5371
        assemblePage(pPage, pChild->nCell, apCell, szCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5372
        /* Copy the right-pointer of the child to the parent. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5373
        put4byte(&pPage->aData[pPage->hdrOffset+8], 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5374
            get4byte(&pChild->aData[pChild->hdrOffset+8]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5375
        freePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5376
        TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5377
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5378
        /* The child has more information that will fit on the root.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5379
        ** The tree is already balanced.  Do nothing. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5380
        TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5381
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5382
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5383
      memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5384
      pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5385
      pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5386
      rc = sqlite3BtreeInitPage(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5387
      assert( rc==SQLITE_OK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5388
      freePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5389
      TRACE(("BALANCE: transfer child %d into root %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5390
              pChild->pgno, pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5391
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5392
    rc = reparentChildPages(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5393
    assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5394
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5395
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5396
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5397
      for(i=0; i<pPage->nCell; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5398
        rc = ptrmapPutOvfl(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5399
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5400
          goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5401
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5402
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5403
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5404
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5405
    releasePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5406
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5407
end_shallow_balance:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5408
  sqlite3_free(apCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5409
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5410
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5411
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5412
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5413
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5414
** The root page is overfull
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5415
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5416
** When this happens, Create a new child page and copy the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5417
** contents of the root into the child.  Then make the root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5418
** page an empty page with rightChild pointing to the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5419
** child.   Finally, call balance_internal() on the new child
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5420
** to cause it to split.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5421
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5422
static int balance_deeper(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5423
  int rc;             /* Return value from subprocedures */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5424
  MemPage *pChild;    /* Pointer to a new child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5425
  Pgno pgnoChild;     /* Page number of the new child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5426
  BtShared *pBt;         /* The BTree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5427
  int usableSize;     /* Total usable size of a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5428
  u8 *data;           /* Content of the parent page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5429
  u8 *cdata;          /* Content of the child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5430
  int hdr;            /* Offset to page header in parent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5431
  int brk;            /* Offset to content of first cell in parent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5432
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5433
  assert( pPage->pParent==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5434
  assert( pPage->nOverflow>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5435
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5436
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5437
  rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5438
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5439
  assert( sqlite3PagerIswriteable(pChild->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5440
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5441
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5442
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5443
  brk = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5444
  cdata = pChild->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5445
  memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5446
  memcpy(&cdata[brk], &data[brk], usableSize-brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5447
  assert( pChild->isInit==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5448
  rc = sqlite3BtreeInitPage(pChild, pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5449
  if( rc ) goto balancedeeper_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5450
  memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5451
  pChild->nOverflow = pPage->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5452
  if( pChild->nOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5453
    pChild->nFree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5454
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5455
  assert( pChild->nCell==pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5456
  zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5457
  put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5458
  TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5459
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5460
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5461
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5462
    rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5463
    if( rc ) goto balancedeeper_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5464
    for(i=0; i<pChild->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5465
      rc = ptrmapPutOvfl(pChild, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5466
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5467
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5468
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5469
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5470
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5471
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5472
  rc = balance_nonroot(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5473
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5474
balancedeeper_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5475
  releasePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5476
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5477
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5478
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5479
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5480
** Decide if the page pPage needs to be balanced.  If balancing is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5481
** required, call the appropriate balancing routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5482
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5483
static int balance(MemPage *pPage, int insert){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5484
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5485
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5486
  if( pPage->pParent==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5487
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5488
    if( rc==SQLITE_OK && pPage->nOverflow>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5489
      rc = balance_deeper(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5490
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5491
    if( rc==SQLITE_OK && pPage->nCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5492
      rc = balance_shallower(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5493
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5494
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5495
    if( pPage->nOverflow>0 || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5496
        (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5497
      rc = balance_nonroot(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5498
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5499
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5500
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5501
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5502
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5503
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5504
** This routine checks all cursors that point to table pgnoRoot.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5505
** If any of those cursors were opened with wrFlag==0 in a different
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5506
** database connection (a database connection that shares the pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5507
** cache with the current connection) and that other connection 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5508
** is not in the ReadUncommmitted state, then this routine returns 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5509
** SQLITE_LOCKED.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5510
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5511
** In addition to checking for read-locks (where a read-lock 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5512
** means a cursor opened with wrFlag==0) this routine also moves
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5513
** all write cursors so that they are pointing to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5514
** first Cell on the root page.  This is necessary because an insert 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5515
** or delete might change the number of cells on a page or delete
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5516
** a page entirely and we do not want to leave any cursors 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5517
** pointing to non-existant pages or cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5518
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5519
static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5520
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5521
  BtShared *pBt = pBtree->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5522
  sqlite3 *db = pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5523
  assert( sqlite3BtreeHoldsMutex(pBtree) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5524
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5525
    if( p==pExclude ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5526
    if( p->eState!=CURSOR_VALID ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5527
    if( p->pgnoRoot!=pgnoRoot ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5528
    if( p->wrFlag==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5529
      sqlite3 *dbOther = p->pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5530
      if( dbOther==0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5531
         (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5532
        return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5533
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5534
    }else if( p->pPage->pgno!=p->pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5535
      moveToRoot(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5536
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5537
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5538
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5539
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5540
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5541
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5542
** Insert a new record into the BTree.  The key is given by (pKey,nKey)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5543
** and the data is given by (pData,nData).  The cursor is used only to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5544
** define what table the record should be inserted into.  The cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5545
** is left pointing at a random location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5546
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5547
** For an INTKEY table, only the nKey value of the key is used.  pKey is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5548
** ignored.  For a ZERODATA table, the pData and nData are both ignored.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5549
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5550
int sqlite3BtreeInsert(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5551
  BtCursor *pCur,                /* Insert data into the table of this cursor */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5552
  const void *pKey, i64 nKey,    /* The key of the new record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5553
  const void *pData, int nData,  /* The data of the new record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5554
  int nZero,                     /* Number of extra 0 bytes to append to data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5555
  int appendBias                 /* True if this is likely an append */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5556
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5557
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5558
  int loc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5559
  int szNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5560
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5561
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5562
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5563
  unsigned char *oldCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5564
  unsigned char *newCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5565
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5566
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5567
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5568
    /* Must start a transaction before doing an insert */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5569
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5570
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5571
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5572
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5573
  if( !pCur->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5574
    return SQLITE_PERM;   /* Cursor not open for writing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5575
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5576
  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5577
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5578
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5579
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5580
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5581
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5583
  /* Save the positions of any other cursors open on this table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5584
  clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5585
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5586
    SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5587
    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5588
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5589
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5590
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5591
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5592
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5593
  assert( pPage->intKey || nKey>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5594
  assert( pPage->leaf || !pPage->leafData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5595
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5596
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5597
          loc==0 ? "overwrite" : "new entry"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5598
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5599
  newCell = (unsigned char*)sqlite3_malloc( MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5600
  if( newCell==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5601
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5602
  if( rc ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5603
  assert( szNew==cellSizePtr(pPage, newCell) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5604
  assert( szNew<=MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5605
  if( loc==0 && CURSOR_VALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5606
    int szOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5607
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5608
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5609
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5610
      goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5611
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5612
    oldCell = findCell(pPage, pCur->idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5613
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5614
      memcpy(newCell, oldCell, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5615
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5616
    szOld = cellSizePtr(pPage, oldCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5617
    rc = clearCell(pPage, oldCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5618
    if( rc ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5619
    dropCell(pPage, pCur->idx, szOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5620
  }else if( loc<0 && pPage->nCell>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5621
    assert( pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5622
    pCur->idx++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5623
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5624
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5625
    assert( pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5626
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5627
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5628
  if( rc!=SQLITE_OK ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5629
  rc = balance(pPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5630
  /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5631
  /* fflush(stdout); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5632
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5633
    moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5634
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5635
end_insert:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5636
  sqlite3_free(newCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5637
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5638
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5639
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5640
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5641
** Delete the entry that the cursor is pointing to.  The cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5642
** is left pointing at a random location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5643
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5644
int sqlite3BtreeDelete(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5645
  MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5646
  unsigned char *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5647
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5648
  Pgno pgnoChild = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5649
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5650
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5651
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5652
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5653
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5654
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5655
    /* Must start a transaction before doing a delete */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5656
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5657
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5658
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5659
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5660
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5661
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5662
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5663
  if( pCur->idx >= pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5664
    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5665
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5666
  if( !pCur->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5667
    return SQLITE_PERM;   /* Did not open this cursor for writing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5668
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5669
  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5670
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5671
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5673
  /* Restore the current cursor position (a no-op if the cursor is not in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5674
  ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5675
  ** open on the same table. Then call sqlite3PagerWrite() on the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5676
  ** that the entry will be deleted from.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5677
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5678
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5679
    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5680
    (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5681
    (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5682
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5683
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5684
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5685
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5686
  /* Locate the cell within its page and leave pCell pointing to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5687
  ** data. The clearCell() call frees any overflow pages associated with the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5688
  ** cell. The cell itself is still intact.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5689
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5690
  pCell = findCell(pPage, pCur->idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5691
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5692
    pgnoChild = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5693
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5694
  rc = clearCell(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5695
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5696
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5698
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5699
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5700
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5701
    ** The entry we are about to delete is not a leaf so if we do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5702
    ** do something we will leave a hole on an internal page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5703
    ** We have to fill the hole by moving in a cell from a leaf.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5704
    ** next Cell after the one to be deleted is guaranteed to exist and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5705
    ** to be a leaf so we can use it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5706
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5707
    BtCursor leafCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5708
    unsigned char *pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5709
    int szNext;  /* The compiler warning is wrong: szNext is always 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5710
                 ** initialized before use.  Adding an extra initialization
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5711
                 ** to silence the compiler slows down the code. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5712
    int notUsed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5713
    unsigned char *tempCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5714
    assert( !pPage->leafData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5715
    sqlite3BtreeGetTempCursor(pCur, &leafCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5716
    rc = sqlite3BtreeNext(&leafCur, &notUsed);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5717
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5718
      rc = sqlite3PagerWrite(leafCur.pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5719
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5720
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5721
      TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5722
         pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5723
      dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5724
      pNext = findCell(leafCur.pPage, leafCur.idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5725
      szNext = cellSizePtr(leafCur.pPage, pNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5726
      assert( MX_CELL_SIZE(pBt)>=szNext+4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5727
      tempCell = (unsigned char*)sqlite3_malloc( MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5728
      if( tempCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5729
        rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5730
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5731
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5732
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5733
      rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5734
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5735
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5736
      put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5737
      rc = balance(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5738
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5739
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5740
      dropCell(leafCur.pPage, leafCur.idx, szNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5741
      rc = balance(leafCur.pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5742
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5743
    sqlite3_free(tempCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5744
    sqlite3BtreeReleaseTempCursor(&leafCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5745
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5746
    TRACE(("DELETE: table=%d delete from leaf %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5747
       pCur->pgnoRoot, pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5748
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5749
    rc = balance(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5750
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5751
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5752
    moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5753
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5754
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5755
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5756
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5757
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5758
** Create a new BTree table.  Write into *piTable the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5759
** number for the root page of the new table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5760
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5761
** The type of type is determined by the flags parameter.  Only the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5762
** following values of flags are currently in use.  Other values for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5763
** flags might not work:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5764
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5765
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5766
**     BTREE_ZERODATA                  Used for SQL indices
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5767
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5768
static int btreeCreateTable(Btree *p, int *piTable, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5769
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5770
  MemPage *pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5771
  Pgno pgnoRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5772
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5773
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5774
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5775
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5776
    /* Must start a transaction first */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5777
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5778
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5779
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5780
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5781
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5782
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5783
  rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5784
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5785
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5786
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5787
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5788
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5789
    Pgno pgnoMove;      /* Move a page here to make room for the root-page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5790
    MemPage *pPageMove; /* The page to move to. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5791
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5792
    /* Creating a new table may probably require moving an existing database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5793
    ** to make room for the new tables root page. In case this page turns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5794
    ** out to be an overflow page, delete all overflow page-map caches
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5795
    ** held by open cursors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5796
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5797
    invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5798
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5799
    /* Read the value of meta[3] from the database to determine where the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5800
    ** root page of the new table should go. meta[3] is the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5801
    ** created so far, so the new root-page is (meta[3]+1).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5802
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5803
    rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5804
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5805
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5806
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5807
    pgnoRoot++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5808
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5809
    /* The new root-page may not be allocated on a pointer-map page, or the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5810
    ** PENDING_BYTE page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5811
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5812
    if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5813
        pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5814
      pgnoRoot++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5815
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5816
    assert( pgnoRoot>=3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5817
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5818
    /* Allocate a page. The page that currently resides at pgnoRoot will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5819
    ** be moved to the allocated page (unless the allocated page happens
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5820
    ** to reside at pgnoRoot).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5821
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5822
    rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5823
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5824
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5825
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5826
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5827
    if( pgnoMove!=pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5828
      /* pgnoRoot is the page that will be used for the root-page of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5829
      ** the new table (assuming an error did not occur). But we were
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5830
      ** allocated pgnoMove. If required (i.e. if it was not allocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5831
      ** by extending the file), the current page at position pgnoMove
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5832
      ** is already journaled.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5833
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5834
      u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5835
      Pgno iPtrPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5836
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5837
      releasePage(pPageMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5838
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5839
      /* Move the page currently at pgnoRoot to pgnoMove. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5840
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5841
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5842
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5843
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5844
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5845
      if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5846
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5847
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5848
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5849
      assert( eType!=PTRMAP_ROOTPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5850
      assert( eType!=PTRMAP_FREEPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5851
      rc = sqlite3PagerWrite(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5852
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5853
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5854
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5855
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5856
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5857
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5859
      /* Obtain the page at pgnoRoot */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5860
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5861
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5862
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5863
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5864
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5865
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5866
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5867
      rc = sqlite3PagerWrite(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5868
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5869
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5870
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5871
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5872
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5873
      pRoot = pPageMove;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5874
    } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5875
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5876
    /* Update the pointer-map and meta-data with the new root-page number. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5877
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5878
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5879
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5880
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5881
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5882
    rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5883
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5884
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5885
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5886
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5887
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5888
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5889
    rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5890
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5891
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5892
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5893
  assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5894
  zeroPage(pRoot, flags | PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5895
  sqlite3PagerUnref(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5896
  *piTable = (int)pgnoRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5897
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5898
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5899
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5900
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5901
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5902
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5903
  rc = btreeCreateTable(p, piTable, flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5904
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5905
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5906
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5907
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5908
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5909
** Erase the given database page and all its children.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5910
** the page to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5911
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5912
static int clearDatabasePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5913
  BtShared *pBt,           /* The BTree that contains the table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5914
  Pgno pgno,            /* Page number to clear */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5915
  MemPage *pParent,     /* Parent page.  NULL for the root */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5916
  int freePageFlag      /* Deallocate page if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5917
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5918
  MemPage *pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5919
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5920
  unsigned char *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5921
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5922
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5923
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5924
  if( pgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5925
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5926
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5928
  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5929
  if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5930
  for(i=0; i<pPage->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5931
    pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5932
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5933
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5934
      if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5935
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5936
    rc = clearCell(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5937
    if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5938
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5939
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5940
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5941
    if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5942
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5943
  if( freePageFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5944
    rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5945
  }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5946
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5947
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5948
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5949
cleardatabasepage_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5950
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5951
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5952
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5953
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5954
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5955
** Delete all information from a single table in the database.  iTable is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5956
** the page number of the root of the table.  After this routine returns,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5957
** the root page is empty, but still exists.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5958
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5959
** This routine will fail with SQLITE_LOCKED if there are any open
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5960
** read cursors on the table.  Open write cursors are moved to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5961
** root of the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5962
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5963
int sqlite3BtreeClearTable(Btree *p, int iTable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5964
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5965
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5966
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5967
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5968
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5969
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5970
  }else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5971
    /* nothing to do */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5972
  }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5973
    /* nothing to do */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5974
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5975
    rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5976
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5977
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5978
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5979
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5980
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5981
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5982
** Erase all information in a table and add the root of the table to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5983
** the freelist.  Except, the root of the principle table (the one on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5984
** page 1) is never added to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5985
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5986
** This routine will fail with SQLITE_LOCKED if there are any open
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5987
** cursors on the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5988
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5989
** If AUTOVACUUM is enabled and the page at iTable is not the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5990
** root page in the database file, then the last root page 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5991
** in the database file is moved into the slot formerly occupied by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5992
** iTable and that last slot formerly occupied by the last root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5993
** is added to the freelist instead of iTable.  In this say, all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5994
** root pages are kept at the beginning of the database file, which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5995
** is necessary for AUTOVACUUM to work right.  *piMoved is set to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5996
** page number that used to be the last root page in the file before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5997
** the move.  If no page gets moved, *piMoved is set to 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5998
** The last root page is recorded in meta[3] and the value of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5999
** meta[3] is updated by this procedure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6000
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6001
static int btreeDropTable(Btree *p, int iTable, int *piMoved){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6002
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6003
  MemPage *pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6004
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6005
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6006
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6007
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6008
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6009
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6010
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6011
  /* It is illegal to drop a table if any cursors are open on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6012
  ** database. This is because in auto-vacuum mode the backend may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6013
  ** need to move another root-page to fill a gap left by the deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6014
  ** root page. If an open cursor was using this page a problem would 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6015
  ** occur.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6016
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6017
  if( pBt->pCursor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6018
    return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6019
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6020
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6021
  rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6022
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6023
  rc = sqlite3BtreeClearTable(p, iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6024
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6025
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6026
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6027
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6028
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6029
  *piMoved = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6030
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6031
  if( iTable>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6032
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6033
    rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6034
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6035
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6036
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6037
      Pgno maxRootPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6038
      rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6039
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6040
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6041
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6042
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6043
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6044
      if( iTable==maxRootPgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6045
        /* If the table being dropped is the table with the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6046
        ** number in the database, put the root page on the free list. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6047
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6048
        rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6049
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6050
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6051
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6052
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6053
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6054
        /* The table being dropped does not have the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6055
        ** number in the database. So move the page that does into the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6056
        ** gap left by the deleted root-page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6057
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6058
        MemPage *pMove;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6059
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6060
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6061
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6062
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6063
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6064
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6065
        releasePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6066
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6067
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6068
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6069
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6070
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6071
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6072
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6073
        rc = freePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6074
        releasePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6075
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6076
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6077
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6078
        *piMoved = maxRootPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6079
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6080
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6081
      /* Set the new 'max-root-page' value in the database header. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6082
      ** is the old value less one, less one more if that happens to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6083
      ** be a root-page number, less one again if that is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6084
      ** PENDING_BYTE_PAGE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6085
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6086
      maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6087
      if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6088
        maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6089
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6090
      if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6091
        maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6092
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6093
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6094
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6095
      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6096
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6097
      rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6098
      releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6099
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6100
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6101
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6102
    /* If sqlite3BtreeDropTable was called on page 1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6103
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6104
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6105
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6106
  return rc;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6107
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6108
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6109
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6110
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6111
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6112
  rc = btreeDropTable(p, iTable, piMoved);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6113
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6114
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6115
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6116
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6118
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6119
** Read the meta-information out of a database file.  Meta[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6120
** is the number of free pages currently in the database.  Meta[1]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6121
** through meta[15] are available for use by higher layers.  Meta[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6122
** is read-only, the others are read/write.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6123
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6124
** The schema layer numbers meta values differently.  At the schema
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6125
** layer (and the SetCookie and ReadCookie opcodes) the number of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6126
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6127
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6128
int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6129
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6130
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6131
  unsigned char *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6132
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6134
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6135
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6136
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6137
  /* Reading a meta-data value requires a read-lock on page 1 (and hence
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6138
  ** the sqlite_master table. We grab this lock regardless of whether or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6139
  ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6140
  ** 1 is treated as a special case by queryTableLock() and lockTable()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6141
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6142
  rc = queryTableLock(p, 1, READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6143
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6144
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6145
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6146
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6147
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6148
  assert( idx>=0 && idx<=15 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6149
  rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6150
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6151
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6152
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6153
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6154
  pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6155
  *pMeta = get4byte(&pP1[36 + idx*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6156
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6157
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6158
  /* If autovacuumed is disabled in this build but we are trying to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6159
  ** access an autovacuumed database, then make the database readonly. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6160
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6161
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6162
  if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6163
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6164
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6165
  /* Grab the read-lock on page 1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6166
  rc = lockTable(p, 1, READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6167
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6168
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6169
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6170
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6171
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6172
** Write meta-information back into the database.  Meta[0] is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6173
** read-only and may not be written.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6174
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6175
int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6176
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6177
  unsigned char *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6178
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6179
  assert( idx>=1 && idx<=15 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6180
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6181
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6182
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6183
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6184
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6185
    assert( pBt->pPage1!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6186
    pP1 = pBt->pPage1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6187
    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6188
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6189
      put4byte(&pP1[36 + idx*4], iMeta);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6190
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6191
      if( idx==7 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6192
        assert( pBt->autoVacuum || iMeta==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6193
        assert( iMeta==0 || iMeta==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6194
        pBt->incrVacuum = iMeta;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6195
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6196
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6197
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6198
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6199
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6200
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6201
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6202
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6203
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6204
** Return the flag byte at the beginning of the page that the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6205
** is currently pointing to.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6206
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6207
int sqlite3BtreeFlags(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6208
  /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6209
  ** restoreOrClearCursorPosition() here.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6210
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6211
  MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6212
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6213
  assert( pPage->pBt==pCur->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6214
  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6215
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6216
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6217
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6218
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6219
** Return the pager associated with a BTree.  This routine is used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6220
** testing and debugging only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6221
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6222
Pager *sqlite3BtreePager(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6223
  return p->pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6224
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6225
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6226
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6227
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6228
** Append a message to the error message string.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6229
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6230
static void checkAppendMsg(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6231
  IntegrityCk *pCheck,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6232
  char *zMsg1,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6233
  const char *zFormat,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6234
  ...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6235
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6236
  va_list ap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6237
  char *zMsg2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6238
  if( !pCheck->mxErr ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6239
  pCheck->mxErr--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6240
  pCheck->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6241
  va_start(ap, zFormat);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6242
  zMsg2 = sqlite3VMPrintf(0, zFormat, ap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6243
  va_end(ap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6244
  if( zMsg1==0 ) zMsg1 = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6245
  if( pCheck->zErrMsg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6246
    char *zOld = pCheck->zErrMsg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6247
    pCheck->zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6248
    sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6249
    sqlite3_free(zOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6250
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6251
    sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6252
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6253
  sqlite3_free(zMsg2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6254
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6255
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6256
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6257
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6258
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6259
** Add 1 to the reference count for page iPage.  If this is the second
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6260
** reference to the page, add an error message to pCheck->zErrMsg.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6261
** Return 1 if there are 2 ore more references to the page and 0 if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6262
** if this is the first reference to the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6263
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6264
** Also check that the page number is in bounds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6265
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6266
static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6267
  if( iPage==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6268
  if( iPage>pCheck->nPage || iPage<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6269
    checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6270
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6271
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6272
  if( pCheck->anRef[iPage]==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6273
    checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6274
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6275
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6276
  return  (pCheck->anRef[iPage]++)>1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6277
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6278
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6279
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6280
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6281
** Check that the entry in the pointer-map for page iChild maps to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6282
** page iParent, pointer type ptrType. If not, append an error message
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6283
** to pCheck.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6284
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6285
static void checkPtrmap(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6286
  IntegrityCk *pCheck,   /* Integrity check context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6287
  Pgno iChild,           /* Child page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6288
  u8 eType,              /* Expected pointer map type */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6289
  Pgno iParent,          /* Expected pointer map parent page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6290
  char *zContext         /* Context description (used for error msg) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6291
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6292
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6293
  u8 ePtrmapType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6294
  Pgno iPtrmapParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6296
  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6297
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6298
    checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6299
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6300
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6301
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6302
  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6303
    checkAppendMsg(pCheck, zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6304
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6305
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6306
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6307
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6308
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6309
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6310
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6311
** Check the integrity of the freelist or of an overflow page list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6312
** Verify that the number of pages on the list is N.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6313
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6314
static void checkList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6315
  IntegrityCk *pCheck,  /* Integrity checking context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6316
  int isFreeList,       /* True for a freelist.  False for overflow page list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6317
  int iPage,            /* Page number for first page in the list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6318
  int N,                /* Expected number of pages in the list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6319
  char *zContext        /* Context for error messages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6320
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6321
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6322
  int expected = N;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6323
  int iFirst = iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6324
  while( N-- > 0 && pCheck->mxErr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6325
    DbPage *pOvflPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6326
    unsigned char *pOvflData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6327
    if( iPage<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6328
      checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6329
         "%d of %d pages missing from overflow list starting at %d",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6330
          N+1, expected, iFirst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6331
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6332
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6333
    if( checkRef(pCheck, iPage, zContext) ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6334
    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6335
      checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6336
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6337
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6338
    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6339
    if( isFreeList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6340
      int n = get4byte(&pOvflData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6341
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6342
      if( pCheck->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6343
        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6344
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6345
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6346
      if( n>pCheck->pBt->usableSize/4-8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6347
        checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6348
           "freelist leaf count too big on page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6349
        N--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6350
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6351
        for(i=0; i<n; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6352
          Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6353
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6354
          if( pCheck->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6355
            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6356
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6357
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6358
          checkRef(pCheck, iFreePage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6359
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6360
        N -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6361
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6362
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6363
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6364
    else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6365
      /* If this database supports auto-vacuum and iPage is not the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6366
      ** page in this overflow list, check that the pointer-map entry for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6367
      ** the following page matches iPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6368
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6369
      if( pCheck->pBt->autoVacuum && N>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6370
        i = get4byte(pOvflData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6371
        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6372
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6373
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6374
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6375
    iPage = get4byte(pOvflData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6376
    sqlite3PagerUnref(pOvflPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6377
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6378
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6379
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6380
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6381
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6382
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6383
** Do various sanity checks on a single page of a tree.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6384
** the tree depth.  Root pages return 0.  Parents of root pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6385
** return 1, and so forth.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6386
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6387
** These checks are done:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6388
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6389
**      1.  Make sure that cells and freeblocks do not overlap
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6390
**          but combine to completely cover the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6391
**  NO  2.  Make sure cell keys are in order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6392
**  NO  3.  Make sure no key is less than or equal to zLowerBound.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6393
**  NO  4.  Make sure no key is greater than or equal to zUpperBound.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6394
**      5.  Check the integrity of overflow pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6395
**      6.  Recursively call checkTreePage on all children.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6396
**      7.  Verify that the depth of all children is the same.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6397
**      8.  Make sure this page is at least 33% full or else it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6398
**          the root of the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6399
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6400
static int checkTreePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6401
  IntegrityCk *pCheck,  /* Context for the sanity check */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6402
  int iPage,            /* Page number of the page to check */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6403
  MemPage *pParent,     /* Parent page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6404
  char *zParentContext  /* Parent context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6405
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6406
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6407
  int i, rc, depth, d2, pgno, cnt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6408
  int hdr, cellStart;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6409
  int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6410
  u8 *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6411
  BtShared *pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6412
  int usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6413
  char zContext[100];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6414
  char *hit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6415
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6416
  sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6417
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6418
  /* Check that the page exists
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6419
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6420
  pBt = pCheck->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6421
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6422
  if( iPage==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6423
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6424
  if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6425
    checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6426
       "unable to get the page. error code=%d", rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6427
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6428
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6429
  if( (rc = sqlite3BtreeInitPage(pPage, pParent))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6430
    checkAppendMsg(pCheck, zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6431
                   "sqlite3BtreeInitPage() returns error code %d", rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6432
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6433
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6434
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6435
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6436
  /* Check out all the cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6437
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6438
  depth = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6439
  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6440
    u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6441
    int sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6442
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6443
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6444
    /* Check payload overflow pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6445
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6446
    sqlite3_snprintf(sizeof(zContext), zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6447
             "On tree page %d cell %d: ", iPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6448
    pCell = findCell(pPage,i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6449
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6450
    sz = info.nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6451
    if( !pPage->intKey ) sz += info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6452
    assert( sz==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6453
    if( sz>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6454
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6455
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6456
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6457
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6458
        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6459
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6460
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6461
      checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6462
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6463
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6464
    /* Check sanity of left child page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6465
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6466
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6467
      pgno = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6468
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6469
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6470
        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6471
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6472
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6473
      d2 = checkTreePage(pCheck,pgno,pPage,zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6474
      if( i>0 && d2!=depth ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6475
        checkAppendMsg(pCheck, zContext, "Child page depth differs");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6476
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6477
      depth = d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6478
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6479
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6480
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6481
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6482
    sqlite3_snprintf(sizeof(zContext), zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6483
                     "On page %d at right child: ", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6484
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6485
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6486
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6487
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6488
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6489
    checkTreePage(pCheck, pgno, pPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6490
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6491
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6492
  /* Check for complete coverage of the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6493
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6494
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6495
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6496
  hit = (char*)sqlite3MallocZero( usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6497
  if( hit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6498
    memset(hit, 1, get2byte(&data[hdr+5]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6499
    nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6500
    cellStart = hdr + 12 - 4*pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6501
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6502
      int pc = get2byte(&data[cellStart+i*2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6503
      int size = cellSizePtr(pPage, &data[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6504
      int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6505
      if( (pc+size-1)>=usableSize || pc<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6506
        checkAppendMsg(pCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6507
            "Corruption detected in cell %d on page %d",i,iPage,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6508
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6509
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6510
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6511
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6512
    for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i<usableSize && cnt<10000; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6513
           cnt++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6514
      int size = get2byte(&data[i+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6515
      int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6516
      if( (i+size-1)>=usableSize || i<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6517
        checkAppendMsg(pCheck, 0,  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6518
            "Corruption detected in cell %d on page %d",i,iPage,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6519
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6520
        for(j=i+size-1; j>=i; j--) hit[j]++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6521
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6522
      i = get2byte(&data[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6523
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6524
    for(i=cnt=0; i<usableSize; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6525
      if( hit[i]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6526
        cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6527
      }else if( hit[i]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6528
        checkAppendMsg(pCheck, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6529
          "Multiple uses for byte %d of page %d", i, iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6530
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6531
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6532
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6533
    if( cnt!=data[hdr+7] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6534
      checkAppendMsg(pCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6535
          "Fragmented space is %d byte reported as %d on page %d",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6536
          cnt, data[hdr+7], iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6537
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6538
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6539
  sqlite3_free(hit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6540
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6541
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6542
  return depth+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6543
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6544
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6545
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6546
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6547
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6548
** This routine does a complete check of the given BTree file.  aRoot[] is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6549
** an array of pages numbers were each page number is the root page of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6550
** a table.  nRoot is the number of entries in aRoot.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6552
** If everything checks out, this routine returns NULL.  If something is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6553
** amiss, an error message is written into memory obtained from malloc()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6554
** and a pointer to that error message is returned.  The calling function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6555
** is responsible for freeing the error message when it is done.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6556
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6557
char *sqlite3BtreeIntegrityCheck(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6558
  Btree *p,     /* The btree to be checked */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6559
  int *aRoot,   /* An array of root pages numbers for individual trees */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6560
  int nRoot,    /* Number of entries in aRoot[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6561
  int mxErr,    /* Stop reporting errors after this many */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6562
  int *pnErr    /* Write number of errors seen to this variable */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6563
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6564
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6565
  int nRef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6566
  IntegrityCk sCheck;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6567
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6568
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6569
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6570
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6571
  nRef = sqlite3PagerRefcount(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6572
  if( lockBtreeWithRetry(p)!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6573
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6574
    return sqlite3StrDup("Unable to acquire a read lock on the database");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6575
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6576
  sCheck.pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6577
  sCheck.pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6578
  sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6579
  sCheck.mxErr = mxErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6580
  sCheck.nErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6581
  *pnErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6582
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6583
  if( pBt->nTrunc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6584
    sCheck.nPage = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6585
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6586
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6587
  if( sCheck.nPage==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6588
    unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6589
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6590
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6591
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6592
  sCheck.anRef = (int*)sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6593
  if( !sCheck.anRef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6594
    unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6595
    *pnErr = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6596
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6597
    return sqlite3MPrintf(p->db, "Unable to malloc %d bytes", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6598
        (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6599
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6600
  for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6601
  i = PENDING_BYTE_PAGE(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6602
  if( i<=sCheck.nPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6603
    sCheck.anRef[i] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6604
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6605
  sCheck.zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6606
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6607
  /* Check the integrity of the freelist
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6608
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6609
  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6610
            get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6611
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6612
  /* Check all the tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6613
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6614
  for(i=0; i<nRoot && sCheck.mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6615
    if( aRoot[i]==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6616
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6617
    if( pBt->autoVacuum && aRoot[i]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6618
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6619
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6620
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6621
    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6622
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6623
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6624
  /* Make sure every page in the file is referenced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6625
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6626
  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6627
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6628
    if( sCheck.anRef[i]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6629
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6630
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6631
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6632
    /* If the database supports auto-vacuum, make sure no tables contain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6633
    ** references to pointer-map pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6634
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6635
    if( sCheck.anRef[i]==0 && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6636
       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6637
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6638
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6639
    if( sCheck.anRef[i]!=0 && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6640
       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6641
      checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6642
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6643
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6644
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6645
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6646
  /* Make sure this analysis did not leave any unref() pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6647
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6648
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6649
  if( nRef != sqlite3PagerRefcount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6650
    checkAppendMsg(&sCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6651
      "Outstanding page count goes from %d to %d during this analysis",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6652
      nRef, sqlite3PagerRefcount(pBt->pPager)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6653
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6654
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6656
  /* Clean  up and report errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6657
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6658
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6659
  sqlite3_free(sCheck.anRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6660
  *pnErr = sCheck.nErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6661
  return sCheck.zErrMsg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6662
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6663
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6664
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6665
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6666
** Return the full pathname of the underlying database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6667
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6668
** The pager filename is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6669
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6670
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6671
const char *sqlite3BtreeGetFilename(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6672
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6673
  return sqlite3PagerFilename(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6674
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6675
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6676
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6677
** Return the pathname of the directory that contains the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6678
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6679
** The pager directory name is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6680
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6681
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6682
const char *sqlite3BtreeGetDirname(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6683
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6684
  return sqlite3PagerDirname(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6685
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6686
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6687
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6688
** Return the pathname of the journal file for this database. The return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6689
** value of this routine is the same regardless of whether the journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6690
** has been created or not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6691
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6692
** The pager journal filename is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6693
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6694
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6695
const char *sqlite3BtreeGetJournalname(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6696
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6697
  return sqlite3PagerJournalname(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6698
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6699
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6700
#ifndef SQLITE_OMIT_VACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6701
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6702
** Copy the complete content of pBtFrom into pBtTo.  A transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6703
** must be active for both files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6704
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6705
** The size of file pBtFrom may be reduced by this operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6706
** If anything goes wrong, the transaction on pBtFrom is rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6707
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6708
static int btreeCopyFile(Btree *pTo, Btree *pFrom){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6709
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6710
  Pgno i, nPage, nToPage, iSkip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6711
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6712
  BtShared *pBtTo = pTo->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6713
  BtShared *pBtFrom = pFrom->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6714
  pBtTo->db = pTo->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6715
  pBtFrom->db = pFrom->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6716
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6717
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6718
  if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6719
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6720
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6721
  if( pBtTo->pCursor ) return SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6722
  nToPage = sqlite3PagerPagecount(pBtTo->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6723
  nPage = sqlite3PagerPagecount(pBtFrom->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6724
  iSkip = PENDING_BYTE_PAGE(pBtTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6725
  for(i=1; rc==SQLITE_OK && i<=nPage; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6726
    DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6727
    if( i==iSkip ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6728
    rc = sqlite3PagerGet(pBtFrom->pPager, i, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6729
    if( rc ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6730
    rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6731
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6732
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6733
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6734
  /* If the file is shrinking, journal the pages that are being truncated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6735
  ** so that they can be rolled back if the commit fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6736
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6737
  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6738
    DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6739
    if( i==iSkip ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6740
    rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6741
    if( rc ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6742
    rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6743
    sqlite3PagerDontWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6744
    /* Yeah.  It seems wierd to call DontWrite() right after Write().  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6745
    ** that is because the names of those procedures do not exactly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6746
    ** represent what they do.  Write() really means "put this page in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6747
    ** rollback journal and mark it as dirty so that it will be written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6748
    ** to the database file later."  DontWrite() undoes the second part of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6749
    ** that and prevents the page from being written to the database.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6750
    ** page is still on the rollback journal, though.  And that is the whole
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6751
    ** point of this loop: to put pages on the rollback journal. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6752
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6753
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6754
  if( !rc && nPage<nToPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6755
    rc = sqlite3PagerTruncate(pBtTo->pPager, nPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6756
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6757
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6758
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6759
    sqlite3BtreeRollback(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6760
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6761
  return rc;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6762
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6763
int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6764
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6765
  sqlite3BtreeEnter(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6766
  sqlite3BtreeEnter(pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6767
  rc = btreeCopyFile(pTo, pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6768
  sqlite3BtreeLeave(pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6769
  sqlite3BtreeLeave(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6770
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6771
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6772
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6773
#endif /* SQLITE_OMIT_VACUUM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6774
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6775
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6776
** Return non-zero if a transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6777
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6778
int sqlite3BtreeIsInTrans(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6779
  assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6780
  return (p && (p->inTrans==TRANS_WRITE));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6781
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6782
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6783
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6784
** Return non-zero if a statement transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6785
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6786
int sqlite3BtreeIsInStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6787
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6788
  return (p->pBt && p->pBt->inStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6789
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6790
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6791
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6792
** Return non-zero if a read (or write) transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6793
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6794
int sqlite3BtreeIsInReadTrans(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6795
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6796
  return (p && (p->inTrans!=TRANS_NONE));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6797
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6798
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6799
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6800
** This function returns a pointer to a blob of memory associated with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6801
** a single shared-btree. The memory is used by client code for its own
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6802
** purposes (for example, to store a high-level schema associated with 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6803
** the shared-btree). The btree layer manages reference counting issues.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6804
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6805
** The first time this is called on a shared-btree, nBytes bytes of memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6806
** are allocated, zeroed, and returned to the caller. For each subsequent 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6807
** call the nBytes parameter is ignored and a pointer to the same blob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6808
** of memory returned. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6809
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6810
** Just before the shared-btree is closed, the function passed as the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6811
** xFree argument when the memory allocation was made is invoked on the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6812
** blob of allocated memory. This function should not call sqlite3_free()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6813
** on the memory, the btree layer does that.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6814
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6815
void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6816
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6817
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6818
  if( !pBt->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6819
    pBt->pSchema = sqlite3MallocZero(nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6820
    pBt->xFreeSchema = xFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6821
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6822
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6823
  return pBt->pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6824
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6825
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6826
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6827
** Return true if another user of the same shared btree as the argument
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6828
** handle holds an exclusive lock on the sqlite_master table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6829
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6830
int sqlite3BtreeSchemaLocked(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6831
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6832
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6833
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6834
  rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6835
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6836
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6837
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6838
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6839
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6840
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6841
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6842
** Obtain a lock on the table whose root page is iTab.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6843
** lock is a write lock if isWritelock is true or a read lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6844
** if it is false.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6845
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6846
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6847
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6848
  u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6849
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6850
  rc = queryTableLock(p, iTab, lockType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6851
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6852
    rc = lockTable(p, iTab, lockType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6853
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6854
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6855
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6856
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6857
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6859
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6860
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6861
** Argument pCsr must be a cursor opened for writing on an 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6862
** INTKEY table currently pointing at a valid table entry. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6863
** This function modifies the data stored as part of that entry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6864
** Only the data content may only be modified, it is not possible
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6865
** to change the length of the data stored.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6866
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6867
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6868
  assert( cursorHoldsMutex(pCsr) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6869
  assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6870
  assert(pCsr->isIncrblobHandle);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6871
  if( pCsr->eState>=CURSOR_REQUIRESEEK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6872
    if( pCsr->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6873
      return pCsr->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6874
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6875
      return SQLITE_ABORT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6876
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6877
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6879
  /* Check some preconditions: 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6880
  **   (a) the cursor is open for writing,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6881
  **   (b) there is no read-lock on the table being modified and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6882
  **   (c) the cursor points at a valid row of an intKey table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6883
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6884
  if( !pCsr->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6885
    return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6886
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6887
  assert( !pCsr->pBt->readOnly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6888
          && pCsr->pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6889
  if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6890
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6891
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6892
  if( pCsr->eState==CURSOR_INVALID || !pCsr->pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6893
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6894
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6895
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6896
  return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6897
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6898
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6899
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6900
** Set a flag on this cursor to cache the locations of pages from the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6901
** overflow list for the current row. This is used by cursors opened
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6902
** for incremental blob IO only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6903
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6904
** This function sets a flag only. The actual page location cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6905
** (stored in BtCursor.aOverflow[]) is allocated and used by function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6906
** accessPayload() (the worker function for sqlite3BtreeData() and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6907
** sqlite3BtreePutData()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6908
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6909
void sqlite3BtreeCacheOverflow(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6910
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6911
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6912
  assert(!pCur->isIncrblobHandle);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6913
  assert(!pCur->aOverflow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6914
  pCur->isIncrblobHandle = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6915
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6916
#endif