engine/sqlite/src/mem3.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
** 2007 October 14
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
** This file contains the C functions that implement a memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** allocation subsystem for use by SQLite. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** This version of the memory allocation subsystem omits all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** use of malloc().  All dynamically allocatable memory is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
** contained in a static array, mem.aPool[].  The size of this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
** fixed memory pool is SQLITE_MEMORY_SIZE bytes.
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
** This version of the memory allocation subsystem is used if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** and only if SQLITE_MEMORY_SIZE is defined.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
** $Id: mem3.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
*/
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
** This version of the memory allocator is used only when 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** SQLITE_MEMORY_SIZE is defined.
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 defined(SQLITE_MEMORY_SIZE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
#ifdef SQLITE_MEMDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
# error  cannot define both SQLITE_MEMDEBUG and SQLITE_MEMORY_SIZE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
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
** Maximum size (in Mem3Blocks) of a "small" chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
#define MX_SMALL 10
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
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
** Number of freelist hash slots
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
#define N_HASH  61
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
** A memory allocation (also called a "chunk") consists of two or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
** more blocks where each block is 8 bytes.  The first 8 bytes are 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
** a header that is not returned to the user.
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
** A chunk is two or more blocks that is either checked out or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
** free.  The first block has format u.hdr.  u.hdr.size is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
** size of the allocation in blocks if the allocation is free.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
** If the allocation is checked out, u.hdr.size is the negative
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
** of the size.  Similarly, u.hdr.prevSize is the size of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
** immediately previous allocation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
** We often identify a chunk by its index in mem.aPool[].  When
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
** this is done, the chunk index refers to the second block of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
** the chunk.  In this way, the first chunk has an index of 1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
** A chunk index of 0 means "no such chunk" and is the equivalent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
** of a NULL pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
** The second block of free chunks is of the form u.list.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
** two fields form a double-linked list of chunks of related sizes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
** Pointers to the head of the list are stored in mem.aiSmall[] 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
** for smaller chunks and mem.aiHash[] for larger chunks.
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
** The second block of a chunk is user data if the chunk is checked 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
** out.
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
typedef struct Mem3Block Mem3Block;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
struct Mem3Block {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  union {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
    struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
      int prevSize;   /* Size of previous chunk in Mem3Block elements */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
      int size;       /* Size of current chunk in Mem3Block elements */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
    } hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
    struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
      int next;       /* Index in mem.aPool[] of next free chunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
      int prev;       /* Index in mem.aPool[] of previous free chunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
    } list;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  } u;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
};
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
** All of the static variables used by this module are collected
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
** into a single structure named "mem".  This is to keep the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
** static variables organized and to reduce namespace pollution
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** when this module is combined with other in the amalgamation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
static struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  ** True if we are evaluating an out-of-memory callback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
  int alarmBusy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
  
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
  ** Mutex to control access to the memory allocation subsystem.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
  sqlite3_mutex *mutex;
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
  ** The minimum amount of free space that we have seen.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
  int mnMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
  ** iMaster is the index of the master chunk.  Most new allocations
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  ** occur off of this chunk.  szMaster is the size (in Mem3Blocks)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  ** of the current master.  iMaster is 0 if there is not master chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
  ** The master chunk is not in either the aiHash[] or aiSmall[].
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
  int iMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  int szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
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
  ** Array of lists of free blocks according to the block size 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
  ** for smaller chunks, or a hash on the block size for larger
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
  ** chunks.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
  int aiSmall[MX_SMALL-1];   /* For sizes 2 through MX_SMALL, inclusive */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  int aiHash[N_HASH];        /* For sizes MX_SMALL+1 and larger */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
  ** Memory available for allocation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
  Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
} mem;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
** Unlink the chunk at mem.aPool[i] from list it is currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
** on.  *pRoot is the list that i is a member of.
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
static void memsys3UnlinkFromList(int i, int *pRoot){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
  int next = mem.aPool[i].u.list.next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
  int prev = mem.aPool[i].u.list.prev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
  if( prev==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
    *pRoot = next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
    mem.aPool[prev].u.list.next = next;
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
  if( next ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
    mem.aPool[next].u.list.prev = prev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  mem.aPool[i].u.list.next = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
  mem.aPool[i].u.list.prev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
** Unlink the chunk at index i from 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
** whatever list is currently a member of.
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
static void memsys3Unlink(int i){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
  int size, hash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
  size = mem.aPool[i-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  assert( size>=2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
  if( size <= MX_SMALL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
    memsys3UnlinkFromList(i, &mem.aiSmall[size-2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
    hash = size % N_HASH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
    memsys3UnlinkFromList(i, &mem.aiHash[hash]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
** Link the chunk at mem.aPool[i] so that is on the list rooted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
** at *pRoot.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
static void memsys3LinkIntoList(int i, int *pRoot){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
  mem.aPool[i].u.list.next = *pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
  mem.aPool[i].u.list.prev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
  if( *pRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
    mem.aPool[*pRoot].u.list.prev = i;
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
  *pRoot = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
** Link the chunk at index i into either the appropriate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
** small chunk list, or into the large chunk hash table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
static void memsys3Link(int i){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
  int size, hash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
  size = mem.aPool[i-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
  assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
  assert( size>=2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
  if( size <= MX_SMALL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
    memsys3LinkIntoList(i, &mem.aiSmall[size-2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    hash = size % N_HASH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
    memsys3LinkIntoList(i, &mem.aiHash[hash]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
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
** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
** Also:  Initialize the memory allocation subsystem the first time
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
** this routine is called.
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
static void memsys3Enter(void){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  if( mem.mutex==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    mem.aPool[0].u.hdr.size = SQLITE_MEMORY_SIZE/8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
    mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
    mem.iMaster = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
    mem.szMaster = SQLITE_MEMORY_SIZE/8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
    mem.mnMaster = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
  sqlite3_mutex_enter(mem.mutex);
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
** Return the amount of memory currently checked out.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
sqlite3_int64 sqlite3_memory_used(void){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  sqlite3_int64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  memsys3Enter();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
  n = SQLITE_MEMORY_SIZE - mem.szMaster*8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  sqlite3_mutex_leave(mem.mutex);  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
** Return the maximum amount of memory that has ever been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
** checked out since either the beginning of this process
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
** or since the most recent reset.
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
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  sqlite3_int64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  memsys3Enter();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
  n = SQLITE_MEMORY_SIZE - mem.mnMaster*8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
  if( resetFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
    mem.mnMaster = mem.szMaster;
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
  sqlite3_mutex_leave(mem.mutex);  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
** Change the alarm callback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
** This is a no-op for the static memory allocator.  The purpose
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
** of the memory alarm is to support sqlite3_soft_heap_limit().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
** But with this memory allocator, the soft_heap_limit is really
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
** a hard limit that is fixed at SQLITE_MEMORY_SIZE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
int sqlite3_memory_alarm(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
  void *pArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  sqlite3_int64 iThreshold
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
}
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
** Called when we are unable to satisfy an allocation of nBytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
static void memsys3OutOfMemory(int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
  if( !mem.alarmBusy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
    mem.alarmBusy = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
    assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
    sqlite3_mutex_leave(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
    sqlite3_release_memory(nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
    sqlite3_mutex_enter(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
    mem.alarmBusy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
** Return the size of an outstanding allocation, in bytes.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
** size returned omits the 8-byte header overhead.  This only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
** works for chunks that are currently checked out.
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
static int memsys3Size(void *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  Mem3Block *pBlock = (Mem3Block*)p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  assert( pBlock[-1].u.hdr.size<0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  return (-1-pBlock[-1].u.hdr.size)*8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
** Chunk i is a free chunk that has been unlinked.  Adjust its 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
** size parameters for check-out and return a pointer to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
** user portion of the chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
static void *memsys3Checkout(int i, int nBlock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  assert( mem.aPool[i-1].u.hdr.size==nBlock );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
  assert( mem.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
  mem.aPool[i-1].u.hdr.size = -nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
  mem.aPool[i+nBlock-1].u.hdr.prevSize = -nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
  return &mem.aPool[i];
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
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
** Carve a piece off of the end of the mem.iMaster free chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
** Return a pointer to the new allocation.  Or, if the master chunk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
** is not large enough, return 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
static void *memsys3FromMaster(int nBlock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  assert( mem.szMaster>=nBlock );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  if( nBlock>=mem.szMaster-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
    /* Use the entire master */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
    void *p = memsys3Checkout(mem.iMaster, mem.szMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
    mem.iMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
    mem.szMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
    mem.mnMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
    return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
    /* Split the master block.  Return the tail. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
    int newi;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
    newi = mem.iMaster + mem.szMaster - nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
    assert( newi > mem.iMaster+1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
    mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = -nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
    mem.aPool[newi-1].u.hdr.size = -nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
    mem.szMaster -= nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
    mem.aPool[newi-1].u.hdr.prevSize = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
    mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
    if( mem.szMaster < mem.mnMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
      mem.mnMaster = mem.szMaster;
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
    return (void*)&mem.aPool[newi];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  }
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
** *pRoot is the head of a list of free chunks of the same size
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
** or same size hash.  In other words, *pRoot is an entry in either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
** mem.aiSmall[] or mem.aiHash[].  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
** This routine examines all entries on the given list and tries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
** to coalesce each entries with adjacent free chunks.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
** If it sees a chunk that is larger than mem.iMaster, it replaces 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
** the current mem.iMaster with the new larger chunk.  In order for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
** this mem.iMaster replacement to work, the master chunk must be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
** linked into the hash tables.  That is not the normal state of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
** affairs, of course.  The calling routine must link the master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
** chunk before invoking this routine, then must unlink the (possibly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
** changed) master chunk once this routine has finished.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
static void memsys3Merge(int *pRoot){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  int iNext, prev, size, i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
  for(i=*pRoot; i>0; i=iNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
    iNext = mem.aPool[i].u.list.next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
    size = mem.aPool[i-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
    assert( size>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
    if( mem.aPool[i-1].u.hdr.prevSize>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
      memsys3UnlinkFromList(i, pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
      prev = i - mem.aPool[i-1].u.hdr.prevSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
      assert( prev>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
      if( prev==iNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
        iNext = mem.aPool[prev].u.list.next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
      memsys3Unlink(prev);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
      size = i + size - prev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
      mem.aPool[prev-1].u.hdr.size = size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
      mem.aPool[prev+size-1].u.hdr.prevSize = size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
      memsys3Link(prev);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
      i = prev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
    if( size>mem.szMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
      mem.iMaster = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
      mem.szMaster = size;
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
** Return a block of memory of at least nBytes in size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
** Return NULL if unable.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
static void *memsys3Malloc(int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
  int nBlock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
  int toFree;
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
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  assert( sizeof(Mem3Block)==8 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  if( nByte<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
    nBlock = 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
    nBlock = (nByte + 15)/8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
  assert( nBlock >= 2 );
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
  /* STEP 1:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
  ** Look for an entry of the correct size in either the small
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
  ** chunk table or in the large chunk hash table.  This is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
  ** successful most of the time (about 9 times out of 10).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  if( nBlock <= MX_SMALL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
    i = mem.aiSmall[nBlock-2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
    if( i>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
      memsys3UnlinkFromList(i, &mem.aiSmall[nBlock-2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
      return memsys3Checkout(i, nBlock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
    int hash = nBlock % N_HASH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
    for(i=mem.aiHash[hash]; i>0; i=mem.aPool[i].u.list.next){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
      if( mem.aPool[i-1].u.hdr.size==nBlock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
        memsys3UnlinkFromList(i, &mem.aiHash[hash]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
        return memsys3Checkout(i, nBlock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
  }
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
  /* STEP 2:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
  ** Try to satisfy the allocation by carving a piece off of the end
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
  ** of the master chunk.  This step usually works if step 1 fails.
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
  if( mem.szMaster>=nBlock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
    return memsys3FromMaster(nBlock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
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
  /* STEP 3:  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
  ** Loop through the entire memory pool.  Coalesce adjacent free
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
  ** chunks.  Recompute the master chunk as the largest free chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
  ** Then try again to satisfy the allocation by carving a piece off
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
  ** of the end of the master chunk.  This step happens very
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
  ** rarely (we hope!)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
  for(toFree=nBlock*16; toFree<SQLITE_MEMORY_SIZE*2; toFree *= 2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
    memsys3OutOfMemory(toFree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
    if( mem.iMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
      memsys3Link(mem.iMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
      mem.iMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
      mem.szMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
    for(i=0; i<N_HASH; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
      memsys3Merge(&mem.aiHash[i]);
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
    for(i=0; i<MX_SMALL-1; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
      memsys3Merge(&mem.aiSmall[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
    if( mem.szMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
      memsys3Unlink(mem.iMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
      if( mem.szMaster>=nBlock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
        return memsys3FromMaster(nBlock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
  /* If none of the above worked, then we fail. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
** Free an outstanding memory allocation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
void memsys3Free(void *pOld){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  Mem3Block *p = (Mem3Block*)pOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  int size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
  assert( sqlite3_mutex_held(mem.mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  i = p - mem.aPool;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  size = -mem.aPool[i-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
  assert( size>=2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  assert( mem.aPool[i+size-1].u.hdr.prevSize==-size );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
  mem.aPool[i-1].u.hdr.size = size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
  mem.aPool[i+size-1].u.hdr.prevSize = size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
  memsys3Link(i);
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
  /* Try to expand the master using the newly freed chunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
  if( mem.iMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
    while( mem.aPool[mem.iMaster-1].u.hdr.prevSize>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
      size = mem.aPool[mem.iMaster-1].u.hdr.prevSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
      mem.iMaster -= size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
      mem.szMaster += size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
      memsys3Unlink(mem.iMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
      mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
    while( mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
      memsys3Unlink(mem.iMaster+mem.szMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
      mem.szMaster += mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
      mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
    }
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
}
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
** Allocate nBytes of memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
void *sqlite3_malloc(int nBytes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
  sqlite3_int64 *p = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  if( nBytes>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
    memsys3Enter();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
    p = memsys3Malloc(nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
    sqlite3_mutex_leave(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
  return (void*)p; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
** Free memory.
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
void sqlite3_free(void *pPrior){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
  if( pPrior==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
  assert( mem.mutex!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
  sqlite3_mutex_enter(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
  memsys3Free(pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
  sqlite3_mutex_leave(mem.mutex);  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
** Change the size of an existing memory allocation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
void *sqlite3_realloc(void *pPrior, int nBytes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
  int nOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
  void *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  if( pPrior==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
    return sqlite3_malloc(nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
  if( nBytes<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
    sqlite3_free(pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
    return 0;
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( mem.mutex!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
  nOld = memsys3Size(pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
  if( nBytes<=nOld && nBytes>=nOld-128 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
    return pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  sqlite3_mutex_enter(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
  p = memsys3Malloc(nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
    if( nOld<nBytes ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
      memcpy(p, pPrior, nOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
      memcpy(p, pPrior, nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    memsys3Free(pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
  sqlite3_mutex_leave(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
  return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
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
** Open the file indicated and write a log of all unfreed memory 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
** allocations into that log.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
void sqlite3_memdebug_dump(const char *zFilename){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
  FILE *out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
  int i, j, size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  if( zFilename==0 || zFilename[0]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
    out = stdout;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
    out = fopen(zFilename, "w");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
    if( out==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
                      zFilename);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
  memsys3Enter();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
  fprintf(out, "CHUNKS:\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
  for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
    size = mem.aPool[i-1].u.hdr.size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    if( size>=-1 && size<=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
      fprintf(out, "%p size error\n", &mem.aPool[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
      assert( 0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    if( mem.aPool[i+(size<0?-size:size)-1].u.hdr.prevSize!=size ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
      fprintf(out, "%p tail size does not match\n", &mem.aPool[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
      assert( 0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
    if( size<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
      size = -size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
      fprintf(out, "%p %6d bytes checked out\n", &mem.aPool[i], size*8-8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
      fprintf(out, "%p %6d bytes free%s\n", &mem.aPool[i], size*8-8,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
                  i==mem.iMaster ? " **master**" : "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
    }
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
  for(i=0; i<MX_SMALL-1; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
    if( mem.aiSmall[i]==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
    fprintf(out, "small(%2d):", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
    for(j = mem.aiSmall[i]; j>0; j=mem.aPool[j].u.list.next){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
      fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
    fprintf(out, "\n"); 
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
  for(i=0; i<N_HASH; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
    if( mem.aiHash[i]==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
    fprintf(out, "hash(%2d):", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
    for(j = mem.aiHash[i]; j>0; j=mem.aPool[j].u.list.next){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
      fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
    fprintf(out, "\n"); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
  fprintf(out, "master=%d\n", mem.iMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
  fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem.szMaster*8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
  fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem.mnMaster*8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
  sqlite3_mutex_leave(mem.mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  if( out==stdout ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
    fflush(stdout);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
    fclose(out);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
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
#endif /* !SQLITE_MEMORY_SIZE */