engine/sqlite/src/mem3.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 97 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
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 */