/ Hex Artifact Content
Login

Artifact 5253fd4335a8d9c64e5df25cb9da6329af5242c7:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4f 63 74 6f 62  /*.** 2008 Octob
0010: 65 72 20 37 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  er 7.**.** The a
0020: 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20  uthor disclaims 
0030: 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69  copyright to thi
0040: 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20  s source code.  
0050: 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61  In place of.** a
0060: 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68   legal notice, h
0070: 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e  ere is a blessin
0080: 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20  g:.**.**    May 
0090: 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20  you do good and 
00a0: 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20  not evil..**    
00b0: 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72  May you find for
00c0: 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75  giveness for you
00d0: 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76  rself and forgiv
00e0: 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20  e others..**    
00f0: 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72  May you share fr
0100: 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69  eely, never taki
0110: 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75  ng more than you
0120: 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a   give..**.******
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66  ***.**.** This f
0180: 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64  ile contains cod
0190: 65 20 75 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65  e use to impleme
01a0: 6e 74 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  nt an in-memory 
01b0: 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75 72 6e 61 6c  rollback journal
01c0: 2e 0a 2a 2a 20 54 68 65 20 69 6e 2d 6d 65 6d 6f  ..** The in-memo
01d0: 72 79 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75 72  ry rollback jour
01e0: 6e 61 6c 20 69 73 20 75 73 65 64 20 74 6f 20 6a  nal is used to j
01f0: 6f 75 72 6e 61 6c 20 74 72 61 6e 73 61 63 74 69  ournal transacti
0200: 6f 6e 73 20 66 6f 72 0a 2a 2a 20 22 3a 6d 65 6d  ons for.** ":mem
0210: 6f 72 79 3a 22 20 64 61 74 61 62 61 73 65 73 20  ory:" databases 
0220: 61 6e 64 20 77 68 65 6e 20 74 68 65 20 6a 6f 75  and when the jou
0230: 72 6e 61 6c 5f 6d 6f 64 65 3d 4d 45 4d 4f 52 59  rnal_mode=MEMORY
0240: 20 70 72 61 67 6d 61 20 69 73 20 75 73 65 64 2e   pragma is used.
0250: 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .*/.#include "sq
0260: 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 2f 2a 20 46  liteInt.h"../* F
0270: 6f 72 77 61 72 64 20 72 65 66 65 72 65 6e 63 65  orward reference
0280: 73 20 74 6f 20 69 6e 74 65 72 6e 61 6c 20 73 74  s to internal st
0290: 72 75 63 74 75 72 65 73 20 2a 2f 0a 74 79 70 65  ructures */.type
02a0: 64 65 66 20 73 74 72 75 63 74 20 4d 65 6d 4a 6f  def struct MemJo
02b0: 75 72 6e 61 6c 20 4d 65 6d 4a 6f 75 72 6e 61 6c  urnal MemJournal
02c0: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
02d0: 20 46 69 6c 65 50 6f 69 6e 74 20 46 69 6c 65 50   FilePoint FileP
02e0: 6f 69 6e 74 3b 0a 74 79 70 65 64 65 66 20 73 74  oint;.typedef st
02f0: 72 75 63 74 20 46 69 6c 65 43 68 75 6e 6b 20 46  ruct FileChunk F
0300: 69 6c 65 43 68 75 6e 6b 3b 0a 0a 2f 2a 0a 2a 2a  ileChunk;../*.**
0310: 20 54 68 65 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f   The rollback jo
0320: 75 72 6e 61 6c 20 69 73 20 63 6f 6d 70 6f 73 65  urnal is compose
0330: 64 20 6f 66 20 61 20 6c 69 6e 6b 65 64 20 6c 69  d of a linked li
0340: 73 74 20 6f 66 20 74 68 65 73 65 20 73 74 72 75  st of these stru
0350: 63 74 75 72 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68  ctures..**.** Th
0360: 65 20 7a 43 68 75 6e 6b 20 61 72 72 61 79 20 69  e zChunk array i
0370: 73 20 61 6c 77 61 79 73 20 61 74 20 6c 65 61 73  s always at leas
0380: 74 20 38 20 62 79 74 65 73 20 69 6e 20 73 69 7a  t 8 bytes in siz
0390: 65 20 2d 20 75 73 75 61 6c 6c 79 20 6d 75 63 68  e - usually much
03a0: 20 6d 6f 72 65 2e 0a 2a 2a 20 49 74 73 20 61 63   more..** Its ac
03b0: 74 75 61 6c 20 73 69 7a 65 20 69 73 20 73 74 6f  tual size is sto
03c0: 72 65 64 20 69 6e 20 74 68 65 20 4d 65 6d 4a 6f  red in the MemJo
03d0: 75 72 6e 61 6c 2e 6e 43 68 75 6e 6b 53 69 7a 65  urnal.nChunkSize
03e0: 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 73 74   variable..*/.st
03f0: 72 75 63 74 20 46 69 6c 65 43 68 75 6e 6b 20 7b  ruct FileChunk {
0400: 0a 20 20 46 69 6c 65 43 68 75 6e 6b 20 2a 70 4e  .  FileChunk *pN
0410: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ext;            
0420: 20 20 20 2f 2a 20 4e 65 78 74 20 63 68 75 6e 6b     /* Next chunk
0430: 20 69 6e 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20   in the journal 
0440: 2a 2f 0a 20 20 75 38 20 7a 43 68 75 6e 6b 5b 38  */.  u8 zChunk[8
0450: 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ];              
0460: 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20       /* Content 
0470: 6f 66 20 74 68 69 73 20 63 68 75 6e 6b 20 2a 2f  of this chunk */
0480: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 42 79 20 64 65  .};../*.** By de
0490: 66 61 75 6c 74 2c 20 61 6c 6c 6f 63 61 74 65 20  fault, allocate 
04a0: 74 68 69 73 20 6d 61 6e 79 20 62 79 74 65 73 20  this many bytes 
04b0: 6f 66 20 6d 65 6d 6f 72 79 20 66 6f 72 20 65 61  of memory for ea
04c0: 63 68 20 46 69 6c 65 43 68 75 6e 6b 20 6f 62 6a  ch FileChunk obj
04d0: 65 63 74 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ect..*/.#define 
04e0: 4d 45 4d 4a 4f 55 52 4e 41 4c 5f 44 46 4c 54 5f  MEMJOURNAL_DFLT_
04f0: 46 49 4c 45 43 48 55 4e 4b 53 49 5a 45 20 31 30  FILECHUNKSIZE 10
0500: 32 34 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 63 68  24../*.** For ch
0510: 75 6e 6b 20 73 69 7a 65 20 6e 43 68 75 6e 6b 53  unk size nChunkS
0520: 69 7a 65 2c 20 72 65 74 75 72 6e 20 74 68 65 20  ize, return the 
0530: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
0540: 74 68 61 74 20 73 68 6f 75 6c 64 0a 2a 2a 20 62  that should.** b
0550: 65 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  e allocated for 
0560: 65 61 63 68 20 46 69 6c 65 43 68 75 6e 6b 20 73  each FileChunk s
0570: 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 23 64 65  tructure..*/.#de
0580: 66 69 6e 65 20 66 69 6c 65 43 68 75 6e 6b 53 69  fine fileChunkSi
0590: 7a 65 28 6e 43 68 75 6e 6b 53 69 7a 65 29 20 28  ze(nChunkSize) (
05a0: 73 69 7a 65 6f 66 28 46 69 6c 65 43 68 75 6e 6b  sizeof(FileChunk
05b0: 29 20 2b 20 28 28 6e 43 68 75 6e 6b 53 69 7a 65  ) + ((nChunkSize
05c0: 29 2d 38 29 29 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  )-8))../*.** An 
05d0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
05e0: 20 6f 62 6a 65 63 74 20 73 65 72 76 65 73 20 61   object serves a
05f0: 73 20 61 20 63 75 72 73 6f 72 20 69 6e 74 6f 20  s a cursor into 
0600: 74 68 65 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75  the rollback jou
0610: 72 6e 61 6c 2e 0a 2a 2a 20 54 68 65 20 63 75 72  rnal..** The cur
0620: 73 6f 72 20 63 61 6e 20 62 65 20 65 69 74 68 65  sor can be eithe
0630: 72 20 66 6f 72 20 72 65 61 64 69 6e 67 20 6f 72  r for reading or
0640: 20 77 72 69 74 69 6e 67 2e 0a 2a 2f 0a 73 74 72   writing..*/.str
0650: 75 63 74 20 46 69 6c 65 50 6f 69 6e 74 20 7b 0a  uct FilePoint {.
0660: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
0670: 69 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20 20  iOffset;        
0680: 20 20 2f 2a 20 4f 66 66 73 65 74 20 66 72 6f 6d    /* Offset from
0690: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f   the beginning o
06a0: 66 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a 20 20  f the file */.  
06b0: 46 69 6c 65 43 68 75 6e 6b 20 2a 70 43 68 75 6e  FileChunk *pChun
06c0: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
06d0: 2f 2a 20 53 70 65 63 69 66 69 63 20 63 68 75 6e  /* Specific chun
06e0: 6b 20 69 6e 74 6f 20 77 68 69 63 68 20 63 75 72  k into which cur
06f0: 73 6f 72 20 70 6f 69 6e 74 73 20 2a 2f 0a 7d 3b  sor points */.};
0700: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 73 74 72  ../*.** This str
0710: 75 63 74 75 72 65 20 69 73 20 61 20 73 75 62 63  ucture is a subc
0720: 6c 61 73 73 20 6f 66 20 73 71 6c 69 74 65 33 5f  lass of sqlite3_
0730: 66 69 6c 65 2e 20 45 61 63 68 20 6f 70 65 6e 20  file. Each open 
0740: 6d 65 6d 6f 72 79 2d 6a 6f 75 72 6e 61 6c 0a 2a  memory-journal.*
0750: 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  * is an instance
0760: 20 6f 66 20 74 68 69 73 20 63 6c 61 73 73 2e 0a   of this class..
0770: 2a 2f 0a 73 74 72 75 63 74 20 4d 65 6d 4a 6f 75  */.struct MemJou
0780: 72 6e 61 6c 20 7b 0a 20 20 63 6f 6e 73 74 20 73  rnal {.  const s
0790: 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64  qlite3_io_method
07a0: 73 20 2a 70 4d 65 74 68 6f 64 3b 20 2f 2a 20 50  s *pMethod; /* P
07b0: 61 72 65 6e 74 20 63 6c 61 73 73 2e 20 4d 55 53  arent class. MUS
07c0: 54 20 42 45 20 46 49 52 53 54 20 2a 2f 0a 20 20  T BE FIRST */.  
07d0: 69 6e 74 20 6e 43 68 75 6e 6b 53 69 7a 65 3b 20  int nChunkSize; 
07e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07f0: 2f 2a 20 49 6e 2d 6d 65 6d 6f 72 79 20 63 68 75  /* In-memory chu
0800: 6e 6b 2d 73 69 7a 65 20 2a 2f 0a 0a 20 20 69 6e  nk-size */..  in
0810: 74 20 6e 53 70 69 6c 6c 3b 20 20 20 20 20 20 20  t nSpill;       
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0830: 20 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 62   Bytes of data b
0840: 65 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 20 2a  efore flushing *
0850: 2f 0a 20 20 69 6e 74 20 6e 53 69 7a 65 3b 20 20  /.  int nSize;  
0860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0870: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
0880: 64 61 74 61 20 63 75 72 72 65 6e 74 6c 79 20 69  data currently i
0890: 6e 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 46 69  n memory */.  Fi
08a0: 6c 65 43 68 75 6e 6b 20 2a 70 46 69 72 73 74 3b  leChunk *pFirst;
08b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
08c0: 20 48 65 61 64 20 6f 66 20 69 6e 2d 6d 65 6d 6f   Head of in-memo
08d0: 72 79 20 63 68 75 6e 6b 2d 6c 69 73 74 20 2a 2f  ry chunk-list */
08e0: 0a 20 20 46 69 6c 65 50 6f 69 6e 74 20 65 6e 64  .  FilePoint end
08f0: 70 6f 69 6e 74 3b 20 20 20 20 20 20 20 20 20 20  point;          
0900: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
0910: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
0920: 66 69 6c 65 20 2a 2f 0a 20 20 46 69 6c 65 50 6f  file */.  FilePo
0930: 69 6e 74 20 72 65 61 64 70 6f 69 6e 74 3b 20 20  int readpoint;  
0940: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
0950: 6e 74 65 72 20 74 6f 20 74 68 65 20 65 6e 64 20  nter to the end 
0960: 6f 66 20 74 68 65 20 6c 61 73 74 20 78 52 65 61  of the last xRea
0970: 64 28 29 20 2a 2f 0a 0a 20 20 69 6e 74 20 66 6c  d() */..  int fl
0980: 61 67 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  ags;            
0990: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70            /* xOp
09a0: 65 6e 20 66 6c 61 67 73 20 2a 2f 0a 20 20 73 71  en flags */.  sq
09b0: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b  lite3_vfs *pVfs;
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
09d0: 20 54 68 65 20 22 72 65 61 6c 22 20 75 6e 64 65   The "real" unde
09e0: 72 6c 79 69 6e 67 20 56 46 53 20 2a 2f 0a 20 20  rlying VFS */.  
09f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4a 6f 75  const char *zJou
0a00: 72 6e 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20  rnal;           
0a10: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 6a  /* Name of the j
0a20: 6f 75 72 6e 61 6c 20 66 69 6c 65 20 2a 2f 0a 7d  ournal file */.}
0a30: 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61  ;../*.** Read da
0a40: 74 61 20 66 72 6f 6d 20 74 68 65 20 69 6e 2d 6d  ta from the in-m
0a50: 65 6d 6f 72 79 20 6a 6f 75 72 6e 61 6c 20 66 69  emory journal fi
0a60: 6c 65 2e 20 20 54 68 69 73 20 69 73 20 74 68 65  le.  This is the
0a70: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 0a   implementation.
0a80: 2a 2a 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  ** of the sqlite
0a90: 33 5f 76 66 73 2e 78 52 65 61 64 20 6d 65 74 68  3_vfs.xRead meth
0aa0: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
0ab0: 74 20 6d 65 6d 6a 72 6e 6c 52 65 61 64 28 0a 20  t memjrnlRead(. 
0ac0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
0ad0: 4a 66 64 2c 20 20 20 20 2f 2a 20 54 68 65 20 6a  Jfd,    /* The j
0ae0: 6f 75 72 6e 61 6c 20 66 69 6c 65 20 66 72 6f 6d  ournal file from
0af0: 20 77 68 69 63 68 20 74 6f 20 72 65 61 64 20 2a   which to read *
0b00: 2f 0a 20 20 76 6f 69 64 20 2a 7a 42 75 66 2c 20  /.  void *zBuf, 
0b10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 75             /* Pu
0b20: 74 20 74 68 65 20 72 65 73 75 6c 74 73 20 68 65  t the results he
0b30: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 69 41 6d 74  re */.  int iAmt
0b40: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
0b50: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
0b60: 73 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 73  s to read */.  s
0b70: 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 4f 66 73  qlite_int64 iOfs
0b80: 74 20 20 20 20 20 2f 2a 20 42 65 67 69 6e 20 72  t     /* Begin r
0b90: 65 61 64 69 6e 67 20 61 74 20 74 68 69 73 20 6f  eading at this o
0ba0: 66 66 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 4d 65  ffset */.){.  Me
0bb0: 6d 4a 6f 75 72 6e 61 6c 20 2a 70 20 3d 20 28 4d  mJournal *p = (M
0bc0: 65 6d 4a 6f 75 72 6e 61 6c 20 2a 29 70 4a 66 64  emJournal *)pJfd
0bd0: 3b 0a 20 20 75 38 20 2a 7a 4f 75 74 20 3d 20 7a  ;.  u8 *zOut = z
0be0: 42 75 66 3b 0a 20 20 69 6e 74 20 6e 52 65 61 64  Buf;.  int nRead
0bf0: 20 3d 20 69 41 6d 74 3b 0a 20 20 69 6e 74 20 69   = iAmt;.  int i
0c00: 43 68 75 6e 6b 4f 66 66 73 65 74 3b 0a 20 20 46  ChunkOffset;.  F
0c10: 69 6c 65 43 68 75 6e 6b 20 2a 70 43 68 75 6e 6b  ileChunk *pChunk
0c20: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
0c30: 5f 45 4e 41 42 4c 45 5f 41 54 4f 4d 49 43 5f 57  _ENABLE_ATOMIC_W
0c40: 52 49 54 45 0a 20 20 69 66 28 20 28 69 41 6d 74  RITE.  if( (iAmt
0c50: 2b 69 4f 66 73 74 29 3e 70 2d 3e 65 6e 64 70 6f  +iOfst)>p->endpo
0c60: 69 6e 74 2e 69 4f 66 66 73 65 74 20 29 7b 0a 20  int.iOffset ){. 
0c70: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
0c80: 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41  _IOERR_SHORT_REA
0c90: 44 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  D;.  }.#endif.. 
0ca0: 20 61 73 73 65 72 74 28 20 28 69 41 6d 74 2b 69   assert( (iAmt+i
0cb0: 4f 66 73 74 29 3c 3d 70 2d 3e 65 6e 64 70 6f 69  Ofst)<=p->endpoi
0cc0: 6e 74 2e 69 4f 66 66 73 65 74 20 29 3b 0a 20 20  nt.iOffset );.  
0cd0: 69 66 28 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74  if( p->readpoint
0ce0: 2e 69 4f 66 66 73 65 74 21 3d 69 4f 66 73 74 20  .iOffset!=iOfst 
0cf0: 7c 7c 20 69 4f 66 73 74 3d 3d 30 20 29 7b 0a 20  || iOfst==0 ){. 
0d00: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
0d10: 20 69 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 66   iOff = 0;.    f
0d20: 6f 72 28 70 43 68 75 6e 6b 3d 70 2d 3e 70 46 69  or(pChunk=p->pFi
0d30: 72 73 74 3b 20 0a 20 20 20 20 20 20 20 20 41 4c  rst; .        AL
0d40: 57 41 59 53 28 70 43 68 75 6e 6b 29 20 26 26 20  WAYS(pChunk) && 
0d50: 28 69 4f 66 66 2b 70 2d 3e 6e 43 68 75 6e 6b 53  (iOff+p->nChunkS
0d60: 69 7a 65 29 3c 3d 69 4f 66 73 74 3b 0a 20 20 20  ize)<=iOfst;.   
0d70: 20 20 20 20 20 70 43 68 75 6e 6b 3d 70 43 68 75       pChunk=pChu
0d80: 6e 6b 2d 3e 70 4e 65 78 74 0a 20 20 20 20 29 7b  nk->pNext.    ){
0d90: 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d 20 70  .      iOff += p
0da0: 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 3b 0a 20 20  ->nChunkSize;.  
0db0: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
0dc0: 20 70 43 68 75 6e 6b 20 3d 20 70 2d 3e 72 65 61   pChunk = p->rea
0dd0: 64 70 6f 69 6e 74 2e 70 43 68 75 6e 6b 3b 0a 20  dpoint.pChunk;. 
0de0: 20 7d 0a 0a 20 20 69 43 68 75 6e 6b 4f 66 66 73   }..  iChunkOffs
0df0: 65 74 20 3d 20 28 69 6e 74 29 28 69 4f 66 73 74  et = (int)(iOfst
0e00: 25 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 29 3b  %p->nChunkSize);
0e10: 0a 20 20 64 6f 20 7b 0a 20 20 20 20 69 6e 74 20  .  do {.    int 
0e20: 69 53 70 61 63 65 20 3d 20 70 2d 3e 6e 43 68 75  iSpace = p->nChu
0e30: 6e 6b 53 69 7a 65 20 2d 20 69 43 68 75 6e 6b 4f  nkSize - iChunkO
0e40: 66 66 73 65 74 3b 0a 20 20 20 20 69 6e 74 20 6e  ffset;.    int n
0e50: 43 6f 70 79 20 3d 20 4d 49 4e 28 6e 52 65 61 64  Copy = MIN(nRead
0e60: 2c 20 28 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65  , (p->nChunkSize
0e70: 20 2d 20 69 43 68 75 6e 6b 4f 66 66 73 65 74 29   - iChunkOffset)
0e80: 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 7a 4f  );.    memcpy(zO
0e90: 75 74 2c 20 28 75 38 2a 29 70 43 68 75 6e 6b 2d  ut, (u8*)pChunk-
0ea0: 3e 7a 43 68 75 6e 6b 20 2b 20 69 43 68 75 6e 6b  >zChunk + iChunk
0eb0: 4f 66 66 73 65 74 2c 20 6e 43 6f 70 79 29 3b 0a  Offset, nCopy);.
0ec0: 20 20 20 20 7a 4f 75 74 20 2b 3d 20 6e 43 6f 70      zOut += nCop
0ed0: 79 3b 0a 20 20 20 20 6e 52 65 61 64 20 2d 3d 20  y;.    nRead -= 
0ee0: 69 53 70 61 63 65 3b 0a 20 20 20 20 69 43 68 75  iSpace;.    iChu
0ef0: 6e 6b 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20  nkOffset = 0;.  
0f00: 7d 20 77 68 69 6c 65 28 20 6e 52 65 61 64 3e 3d  } while( nRead>=
0f10: 30 20 26 26 20 28 70 43 68 75 6e 6b 3d 70 43 68  0 && (pChunk=pCh
0f20: 75 6e 6b 2d 3e 70 4e 65 78 74 29 21 3d 30 20 26  unk->pNext)!=0 &
0f30: 26 20 6e 52 65 61 64 3e 30 20 29 3b 0a 20 20 70  & nRead>0 );.  p
0f40: 2d 3e 72 65 61 64 70 6f 69 6e 74 2e 69 4f 66 66  ->readpoint.iOff
0f50: 73 65 74 20 3d 20 69 4f 66 73 74 2b 69 41 6d 74  set = iOfst+iAmt
0f60: 3b 0a 20 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74  ;.  p->readpoint
0f70: 2e 70 43 68 75 6e 6b 20 3d 20 70 43 68 75 6e 6b  .pChunk = pChunk
0f80: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  ;..  return SQLI
0f90: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
0fa0: 46 72 65 65 20 74 68 65 20 6c 69 73 74 20 6f 66  Free the list of
0fb0: 20 46 69 6c 65 43 68 75 6e 6b 20 73 74 72 75 63   FileChunk struc
0fc0: 74 75 72 65 73 20 68 65 61 64 65 64 20 61 74 20  tures headed at 
0fd0: 4d 65 6d 4a 6f 75 72 6e 61 6c 2e 70 46 69 72 73  MemJournal.pFirs
0fe0: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
0ff0: 64 20 6d 65 6d 6a 72 6e 6c 46 72 65 65 43 68 75  d memjrnlFreeChu
1000: 6e 6b 73 28 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a  nks(MemJournal *
1010: 70 29 7b 0a 20 20 46 69 6c 65 43 68 75 6e 6b 20  p){.  FileChunk 
1020: 2a 70 49 74 65 72 3b 0a 20 20 46 69 6c 65 43 68  *pIter;.  FileCh
1030: 75 6e 6b 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f  unk *pNext;.  fo
1040: 72 28 70 49 74 65 72 3d 70 2d 3e 70 46 69 72 73  r(pIter=p->pFirs
1050: 74 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d  t; pIter; pIter=
1060: 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78  pNext){.    pNex
1070: 74 20 3d 20 70 49 74 65 72 2d 3e 70 4e 65 78 74  t = pIter->pNext
1080: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
1090: 65 65 28 70 49 74 65 72 29 3b 0a 20 20 7d 20 0a  ee(pIter);.  } .
10a0: 20 20 70 2d 3e 70 46 69 72 73 74 20 3d 20 30 3b    p->pFirst = 0;
10b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20  .}../*.** Flush 
10c0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
10d0: 6d 65 6d 6f 72 79 20 74 6f 20 61 20 72 65 61 6c  memory to a real
10e0: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2e 0a 2a   file on disk..*
10f0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d  /.static int mem
1100: 6a 72 6e 6c 43 72 65 61 74 65 46 69 6c 65 28 4d  jrnlCreateFile(M
1110: 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70 29 7b 0a 20  emJournal *p){. 
1120: 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74   int rc;.  sqlit
1130: 65 33 5f 66 69 6c 65 20 2a 70 52 65 61 6c 20 3d  e3_file *pReal =
1140: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29   (sqlite3_file*)
1150: 70 3b 0a 20 20 4d 65 6d 4a 6f 75 72 6e 61 6c 20  p;.  MemJournal 
1160: 63 6f 70 79 20 3d 20 2a 70 3b 0a 0a 20 20 6d 65  copy = *p;..  me
1170: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
1180: 66 28 4d 65 6d 4a 6f 75 72 6e 61 6c 29 29 3b 0a  f(MemJournal));.
1190: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
11a0: 4f 70 65 6e 28 63 6f 70 79 2e 70 56 66 73 2c 20  Open(copy.pVfs, 
11b0: 63 6f 70 79 2e 7a 4a 6f 75 72 6e 61 6c 2c 20 70  copy.zJournal, p
11c0: 52 65 61 6c 2c 20 63 6f 70 79 2e 66 6c 61 67 73  Real, copy.flags
11d0: 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  , 0);.  if( rc==
11e0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11f0: 20 69 6e 74 20 6e 43 68 75 6e 6b 20 3d 20 63 6f   int nChunk = co
1200: 70 79 2e 6e 43 68 75 6e 6b 53 69 7a 65 3b 0a 20  py.nChunkSize;. 
1210: 20 20 20 69 36 34 20 69 4f 66 66 20 3d 20 30 3b     i64 iOff = 0;
1220: 0a 20 20 20 20 46 69 6c 65 43 68 75 6e 6b 20 2a  .    FileChunk *
1230: 70 49 74 65 72 3b 0a 20 20 20 20 66 6f 72 28 70  pIter;.    for(p
1240: 49 74 65 72 3d 63 6f 70 79 2e 70 46 69 72 73 74  Iter=copy.pFirst
1250: 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d 70  ; pIter; pIter=p
1260: 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  Iter->pNext){.  
1270: 20 20 20 20 69 66 28 20 69 4f 66 66 20 2b 20 6e      if( iOff + n
1280: 43 68 75 6e 6b 20 3e 20 63 6f 70 79 2e 65 6e 64  Chunk > copy.end
1290: 70 6f 69 6e 74 2e 69 4f 66 66 73 65 74 20 29 7b  point.iOffset ){
12a0: 0a 20 20 20 20 20 20 20 20 6e 43 68 75 6e 6b 20  .        nChunk 
12b0: 3d 20 63 6f 70 79 2e 65 6e 64 70 6f 69 6e 74 2e  = copy.endpoint.
12c0: 69 4f 66 66 73 65 74 20 2d 20 69 4f 66 66 3b 0a  iOffset - iOff;.
12d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63        }.      rc
12e0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74   = sqlite3OsWrit
12f0: 65 28 70 52 65 61 6c 2c 20 28 75 38 2a 29 70 49  e(pReal, (u8*)pI
1300: 74 65 72 2d 3e 7a 43 68 75 6e 6b 2c 20 6e 43 68  ter->zChunk, nCh
1310: 75 6e 6b 2c 20 69 4f 66 66 29 3b 0a 20 20 20 20  unk, iOff);.    
1320: 20 20 69 66 28 20 72 63 20 29 20 62 72 65 61 6b    if( rc ) break
1330: 3b 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d 20  ;.      iOff += 
1340: 6e 43 68 75 6e 6b 3b 0a 20 20 20 20 7d 0a 20 20  nChunk;.    }.  
1350: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1360: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  _OK ){.      /* 
1370: 4e 6f 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  No error has occ
1380: 75 72 72 65 64 2e 20 46 72 65 65 20 74 68 65 20  urred. Free the 
1390: 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72  in-memory buffer
13a0: 73 2e 20 2a 2f 0a 20 20 20 20 20 20 6d 65 6d 6a  s. */.      memj
13b0: 72 6e 6c 46 72 65 65 43 68 75 6e 6b 73 28 26 63  rnlFreeChunks(&c
13c0: 6f 70 79 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  opy);.    }.  }.
13d0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
13e0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66  _OK ){.    /* If
13f0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 72   an error occurr
1400: 65 64 20 77 68 69 6c 65 20 63 72 65 61 74 69 6e  ed while creatin
1410: 67 20 6f 72 20 77 72 69 74 69 6e 67 20 74 6f 20  g or writing to 
1420: 74 68 65 20 66 69 6c 65 2c 20 72 65 73 74 6f 72  the file, restor
1430: 65 0a 20 20 20 20 2a 2a 20 74 68 65 20 6f 72 69  e.    ** the ori
1440: 67 69 6e 61 6c 20 62 65 66 6f 72 65 20 72 65 74  ginal before ret
1450: 75 72 6e 69 6e 67 2e 20 54 68 69 73 20 77 61 79  urning. This way
1460: 2c 20 53 51 4c 69 74 65 20 75 73 65 73 20 74 68  , SQLite uses th
1470: 65 20 69 6e 2d 6d 65 6d 6f 72 79 0a 20 20 20 20  e in-memory.    
1480: 2a 2a 20 6a 6f 75 72 6e 61 6c 20 64 61 74 61 20  ** journal data 
1490: 74 6f 20 72 6f 6c 6c 20 62 61 63 6b 20 63 68 61  to roll back cha
14a0: 6e 67 65 73 20 6d 61 64 65 20 74 6f 20 74 68 65  nges made to the
14b0: 20 69 6e 74 65 72 6e 61 6c 20 70 61 67 65 2d 63   internal page-c
14c0: 61 63 68 65 0a 20 20 20 20 2a 2a 20 62 65 66 6f  ache.    ** befo
14d0: 72 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  re this function
14e0: 20 77 61 73 20 63 61 6c 6c 65 64 2e 20 20 2a 2f   was called.  */
14f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c  .    sqlite3OsCl
1500: 6f 73 65 28 70 52 65 61 6c 29 3b 0a 20 20 20 20  ose(pReal);.    
1510: 2a 70 20 3d 20 63 6f 70 79 3b 0a 20 20 7d 0a 20  *p = copy;.  }. 
1520: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
1530: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64 61 74 61  /*.** Write data
1540: 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f   to the file..*/
1550: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d 6a  .static int memj
1560: 72 6e 6c 57 72 69 74 65 28 0a 20 20 73 71 6c 69  rnlWrite(.  sqli
1570: 74 65 33 5f 66 69 6c 65 20 2a 70 4a 66 64 2c 20  te3_file *pJfd, 
1580: 20 20 20 2f 2a 20 54 68 65 20 6a 6f 75 72 6e 61     /* The journa
1590: 6c 20 66 69 6c 65 20 69 6e 74 6f 20 77 68 69 63  l file into whic
15a0: 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  h to write */.  
15b0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 7a 42 75 66  const void *zBuf
15c0: 2c 20 20 20 20 20 20 2f 2a 20 54 61 6b 65 20 64  ,      /* Take d
15d0: 61 74 61 20 74 6f 20 62 65 20 77 72 69 74 74 65  ata to be writte
15e0: 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a 20  n from here */. 
15f0: 20 69 6e 74 20 69 41 6d 74 2c 20 20 20 20 20 20   int iAmt,      
1600: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1610: 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 77 72  r of bytes to wr
1620: 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f  ite */.  sqlite_
1630: 69 6e 74 36 34 20 69 4f 66 73 74 20 20 20 20 20  int64 iOfst     
1640: 2f 2a 20 42 65 67 69 6e 20 77 72 69 74 69 6e 67  /* Begin writing
1650: 20 61 74 20 74 68 69 73 20 6f 66 66 73 65 74 20   at this offset 
1660: 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 20 2a 2f  into the file */
1670: 0a 29 7b 0a 20 20 4d 65 6d 4a 6f 75 72 6e 61 6c  .){.  MemJournal
1680: 20 2a 70 20 3d 20 28 4d 65 6d 4a 6f 75 72 6e 61   *p = (MemJourna
1690: 6c 20 2a 29 70 4a 66 64 3b 0a 20 20 69 6e 74 20  l *)pJfd;.  int 
16a0: 6e 57 72 69 74 65 20 3d 20 69 41 6d 74 3b 0a 20  nWrite = iAmt;. 
16b0: 20 75 38 20 2a 7a 57 72 69 74 65 20 3d 20 28 75   u8 *zWrite = (u
16c0: 38 20 2a 29 7a 42 75 66 3b 0a 0a 20 20 2f 2a 20  8 *)zBuf;..  /* 
16d0: 49 66 20 74 68 65 20 66 69 6c 65 20 73 68 6f 75  If the file shou
16e0: 6c 64 20 62 65 20 63 72 65 61 74 65 64 20 6e 6f  ld be created no
16f0: 77 2c 20 63 72 65 61 74 65 20 69 74 20 61 6e 64  w, create it and
1700: 20 77 72 69 74 65 20 74 68 65 20 6e 65 77 20 64   write the new d
1710: 61 74 61 0a 20 20 2a 2a 20 69 6e 74 6f 20 74 68  ata.  ** into th
1720: 65 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2e 20  e file on disk. 
1730: 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 6e 53 70 69  */.  if( p->nSpi
1740: 6c 6c 3e 30 20 26 26 20 28 69 41 6d 74 2b 69 4f  ll>0 && (iAmt+iO
1750: 66 73 74 29 3e 70 2d 3e 6e 53 70 69 6c 6c 20 29  fst)>p->nSpill )
1760: 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 6d  {.    int rc = m
1770: 65 6d 6a 72 6e 6c 43 72 65 61 74 65 46 69 6c 65  emjrnlCreateFile
1780: 28 70 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  (p);.    if( rc=
1790: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
17a0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
17b0: 4f 73 57 72 69 74 65 28 70 4a 66 64 2c 20 7a 42  OsWrite(pJfd, zB
17c0: 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29  uf, iAmt, iOfst)
17d0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ;.    }.    retu
17e0: 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  rn rc;.  }..  /*
17f0: 20 49 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   If the contents
1800: 20 6f 66 20 74 68 69 73 20 77 72 69 74 65 20 73   of this write s
1810: 68 6f 75 6c 64 20 62 65 20 73 74 6f 72 65 64 20  hould be stored 
1820: 69 6e 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 65  in memory */.  e
1830: 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 6e 20 69  lse{.    /* An i
1840: 6e 2d 6d 65 6d 6f 72 79 20 6a 6f 75 72 6e 61 6c  n-memory journal
1850: 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 6f 6e 6c   file should onl
1860: 79 20 65 76 65 72 20 62 65 20 61 70 70 65 6e 64  y ever be append
1870: 65 64 20 74 6f 2e 20 52 61 6e 64 6f 6d 0a 20 20  ed to. Random.  
1880: 20 20 2a 2a 20 61 63 63 65 73 73 20 77 72 69 74    ** access writ
1890: 65 73 20 61 72 65 20 6e 6f 74 20 72 65 71 75 69  es are not requi
18a0: 72 65 64 2e 20 54 68 65 20 6f 6e 6c 79 20 65 78  red. The only ex
18b0: 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 69 73 20  ception to this 
18c0: 69 73 20 77 68 65 6e 0a 20 20 20 20 2a 2a 20 74  is when.    ** t
18d0: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6a 6f 75  he in-memory jou
18e0: 72 6e 61 6c 20 69 73 20 62 65 69 6e 67 20 75 73  rnal is being us
18f0: 65 64 20 62 79 20 61 20 63 6f 6e 6e 65 63 74 69  ed by a connecti
1900: 6f 6e 20 75 73 69 6e 67 20 74 68 65 0a 20 20 20  on using the.   
1910: 20 2a 2a 20 61 74 6f 6d 69 63 2d 77 72 69 74 65   ** atomic-write
1920: 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 49   optimization. I
1930: 6e 20 74 68 69 73 20 63 61 73 65 20 74 68 65 20  n this case the 
1940: 66 69 72 73 74 20 32 38 20 62 79 74 65 73 20 6f  first 28 bytes o
1950: 66 20 74 68 65 0a 20 20 20 20 2a 2a 20 6a 6f 75  f the.    ** jou
1960: 72 6e 61 6c 20 66 69 6c 65 20 6d 61 79 20 62 65  rnal file may be
1970: 20 77 72 69 74 74 65 6e 20 61 73 20 70 61 72 74   written as part
1980: 20 6f 66 20 63 6f 6d 6d 69 74 74 69 6e 67 20 74   of committing t
1990: 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  he transaction. 
19a0: 2a 2f 20 0a 20 20 20 20 61 73 73 65 72 74 28 20  */ .    assert( 
19b0: 69 4f 66 73 74 3d 3d 70 2d 3e 65 6e 64 70 6f 69  iOfst==p->endpoi
19c0: 6e 74 2e 69 4f 66 66 73 65 74 20 7c 7c 20 69 4f  nt.iOffset || iO
19d0: 66 73 74 3d 3d 30 20 29 3b 0a 23 69 66 64 65 66  fst==0 );.#ifdef
19e0: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 41   SQLITE_ENABLE_A
19f0: 54 4f 4d 49 43 5f 57 52 49 54 45 0a 20 20 20 20  TOMIC_WRITE.    
1a00: 69 66 28 20 69 4f 66 73 74 3d 3d 30 20 26 26 20  if( iOfst==0 && 
1a10: 70 2d 3e 70 46 69 72 73 74 20 29 7b 0a 20 20 20  p->pFirst ){.   
1a20: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 43     assert( p->nC
1a30: 68 75 6e 6b 53 69 7a 65 3e 69 41 6d 74 20 29 3b  hunkSize>iAmt );
1a40: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 28 75  .      memcpy((u
1a50: 38 2a 29 70 2d 3e 70 46 69 72 73 74 2d 3e 7a 43  8*)p->pFirst->zC
1a60: 68 75 6e 6b 2c 20 7a 42 75 66 2c 20 69 41 6d 74  hunk, zBuf, iAmt
1a70: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65 6c  );.    }else.#el
1a80: 73 65 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  se.    assert( i
1a90: 4f 66 73 74 3e 30 20 7c 7c 20 70 2d 3e 70 46 69  Ofst>0 || p->pFi
1aa0: 72 73 74 3d 3d 30 20 29 3b 0a 23 65 6e 64 69 66  rst==0 );.#endif
1ab0: 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 77 68 69  .    {.      whi
1ac0: 6c 65 28 20 6e 57 72 69 74 65 3e 30 20 29 7b 0a  le( nWrite>0 ){.
1ad0: 20 20 20 20 20 20 20 20 46 69 6c 65 43 68 75 6e          FileChun
1ae0: 6b 20 2a 70 43 68 75 6e 6b 20 3d 20 70 2d 3e 65  k *pChunk = p->e
1af0: 6e 64 70 6f 69 6e 74 2e 70 43 68 75 6e 6b 3b 0a  ndpoint.pChunk;.
1b00: 20 20 20 20 20 20 20 20 69 6e 74 20 69 43 68 75          int iChu
1b10: 6e 6b 4f 66 66 73 65 74 20 3d 20 28 69 6e 74 29  nkOffset = (int)
1b20: 28 70 2d 3e 65 6e 64 70 6f 69 6e 74 2e 69 4f 66  (p->endpoint.iOf
1b30: 66 73 65 74 25 70 2d 3e 6e 43 68 75 6e 6b 53 69  fset%p->nChunkSi
1b40: 7a 65 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  ze);.        int
1b50: 20 69 53 70 61 63 65 20 3d 20 4d 49 4e 28 6e 57   iSpace = MIN(nW
1b60: 72 69 74 65 2c 20 70 2d 3e 6e 43 68 75 6e 6b 53  rite, p->nChunkS
1b70: 69 7a 65 20 2d 20 69 43 68 75 6e 6b 4f 66 66 73  ize - iChunkOffs
1b80: 65 74 29 3b 0a 0a 20 20 20 20 20 20 20 20 69 66  et);..        if
1b90: 28 20 69 43 68 75 6e 6b 4f 66 66 73 65 74 3d 3d  ( iChunkOffset==
1ba0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f  0 ){.          /
1bb0: 2a 20 4e 65 77 20 63 68 75 6e 6b 20 69 73 20 72  * New chunk is r
1bc0: 65 71 75 69 72 65 64 20 74 6f 20 65 78 74 65 6e  equired to exten
1bd0: 64 20 74 68 65 20 66 69 6c 65 2e 20 2a 2f 0a 20  d the file. */. 
1be0: 20 20 20 20 20 20 20 20 20 46 69 6c 65 43 68 75           FileChu
1bf0: 6e 6b 20 2a 70 4e 65 77 20 3d 20 73 71 6c 69 74  nk *pNew = sqlit
1c00: 65 33 5f 6d 61 6c 6c 6f 63 28 66 69 6c 65 43 68  e3_malloc(fileCh
1c10: 75 6e 6b 53 69 7a 65 28 70 2d 3e 6e 43 68 75 6e  unkSize(p->nChun
1c20: 6b 53 69 7a 65 29 29 3b 0a 20 20 20 20 20 20 20  kSize));.       
1c30: 20 20 20 69 66 28 20 21 70 4e 65 77 20 29 7b 0a     if( !pNew ){.
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
1c50: 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f  rn SQLITE_IOERR_
1c60: 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 20 20  NOMEM_BKPT;.    
1c70: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1c80: 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20    pNew->pNext = 
1c90: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  0;.          if(
1ca0: 20 70 43 68 75 6e 6b 20 29 7b 0a 20 20 20 20 20   pChunk ){.     
1cb0: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
1cc0: 2d 3e 70 46 69 72 73 74 20 29 3b 0a 20 20 20 20  ->pFirst );.    
1cd0: 20 20 20 20 20 20 20 20 70 43 68 75 6e 6b 2d 3e          pChunk->
1ce0: 70 4e 65 78 74 20 3d 20 70 4e 65 77 3b 0a 20 20  pNext = pNew;.  
1cf0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
1d00: 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72             asser
1d10: 74 28 20 21 70 2d 3e 70 46 69 72 73 74 20 29 3b  t( !p->pFirst );
1d20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 2d 3e  .            p->
1d30: 70 46 69 72 73 74 20 3d 20 70 4e 65 77 3b 0a 20  pFirst = pNew;. 
1d40: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
1d50: 20 20 20 20 20 70 2d 3e 65 6e 64 70 6f 69 6e 74       p->endpoint
1d60: 2e 70 43 68 75 6e 6b 20 3d 20 70 4e 65 77 3b 0a  .pChunk = pNew;.
1d70: 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
1d80: 20 20 20 6d 65 6d 63 70 79 28 28 75 38 2a 29 70     memcpy((u8*)p
1d90: 2d 3e 65 6e 64 70 6f 69 6e 74 2e 70 43 68 75 6e  ->endpoint.pChun
1da0: 6b 2d 3e 7a 43 68 75 6e 6b 20 2b 20 69 43 68 75  k->zChunk + iChu
1db0: 6e 6b 4f 66 66 73 65 74 2c 20 7a 57 72 69 74 65  nkOffset, zWrite
1dc0: 2c 20 69 53 70 61 63 65 29 3b 0a 20 20 20 20 20  , iSpace);.     
1dd0: 20 20 20 7a 57 72 69 74 65 20 2b 3d 20 69 53 70     zWrite += iSp
1de0: 61 63 65 3b 0a 20 20 20 20 20 20 20 20 6e 57 72  ace;.        nWr
1df0: 69 74 65 20 2d 3d 20 69 53 70 61 63 65 3b 0a 20  ite -= iSpace;. 
1e00: 20 20 20 20 20 20 20 70 2d 3e 65 6e 64 70 6f 69         p->endpoi
1e10: 6e 74 2e 69 4f 66 66 73 65 74 20 2b 3d 20 69 53  nt.iOffset += iS
1e20: 70 61 63 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20  pace;.      }.  
1e30: 20 20 20 20 70 2d 3e 6e 53 69 7a 65 20 3d 20 69      p->nSize = i
1e40: 41 6d 74 20 2b 20 69 4f 66 73 74 3b 0a 20 20 20  Amt + iOfst;.   
1e50: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
1e60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
1e70: 2a 0a 2a 2a 20 54 72 75 6e 63 61 74 65 20 74 68  *.** Truncate th
1e80: 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  e file..**.** If
1e90: 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66 69 6c   the journal fil
1ea0: 65 20 69 73 20 61 6c 72 65 61 64 79 20 6f 6e 20  e is already on 
1eb0: 64 69 73 6b 2c 20 74 72 75 6e 63 61 74 65 20 69  disk, truncate i
1ec0: 74 20 74 68 65 72 65 2e 20 4f 72 2c 20 69 66 20  t there. Or, if 
1ed0: 69 74 0a 2a 2a 20 69 73 20 73 74 69 6c 6c 20 69  it.** is still i
1ee0: 6e 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 20 62 75  n main memory bu
1ef0: 74 20 69 73 20 62 65 69 6e 67 20 74 72 75 6e 63  t is being trunc
1f00: 61 74 65 64 20 74 6f 20 7a 65 72 6f 20 62 79 74  ated to zero byt
1f10: 65 73 20 69 6e 20 73 69 7a 65 2c 0a 2a 2a 20 69  es in size,.** i
1f20: 67 6e 6f 72 65 20 0a 2a 2f 0a 73 74 61 74 69 63  gnore .*/.static
1f30: 20 69 6e 74 20 6d 65 6d 6a 72 6e 6c 54 72 75 6e   int memjrnlTrun
1f40: 63 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  cate(sqlite3_fil
1f50: 65 20 2a 70 4a 66 64 2c 20 73 71 6c 69 74 65 5f  e *pJfd, sqlite_
1f60: 69 6e 74 36 34 20 73 69 7a 65 29 7b 0a 20 20 4d  int64 size){.  M
1f70: 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70 20 3d 20 28  emJournal *p = (
1f80: 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 29 70 4a 66  MemJournal *)pJf
1f90: 64 3b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28  d;.  if( ALWAYS(
1fa0: 73 69 7a 65 3d 3d 30 29 20 29 7b 0a 20 20 20 20  size==0) ){.    
1fb0: 6d 65 6d 6a 72 6e 6c 46 72 65 65 43 68 75 6e 6b  memjrnlFreeChunk
1fc0: 73 28 70 29 3b 0a 20 20 20 20 70 2d 3e 6e 53 69  s(p);.    p->nSi
1fd0: 7a 65 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 65  ze = 0;.    p->e
1fe0: 6e 64 70 6f 69 6e 74 2e 70 43 68 75 6e 6b 20 3d  ndpoint.pChunk =
1ff0: 20 30 3b 0a 20 20 20 20 70 2d 3e 65 6e 64 70 6f   0;.    p->endpo
2000: 69 6e 74 2e 69 4f 66 66 73 65 74 20 3d 20 30 3b  int.iOffset = 0;
2010: 0a 20 20 20 20 70 2d 3e 72 65 61 64 70 6f 69 6e  .    p->readpoin
2020: 74 2e 70 43 68 75 6e 6b 20 3d 20 30 3b 0a 20 20  t.pChunk = 0;.  
2030: 20 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74 2e 69    p->readpoint.i
2040: 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 7d 0a  Offset = 0;.  }.
2050: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2060: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  OK;.}../*.** Clo
2070: 73 65 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a  se the file..*/.
2080: 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d 6a 72  static int memjr
2090: 6e 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f  nlClose(sqlite3_
20a0: 66 69 6c 65 20 2a 70 4a 66 64 29 7b 0a 20 20 4d  file *pJfd){.  M
20b0: 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70 20 3d 20 28  emJournal *p = (
20c0: 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 29 70 4a 66  MemJournal *)pJf
20d0: 64 3b 0a 20 20 6d 65 6d 6a 72 6e 6c 46 72 65 65  d;.  memjrnlFree
20e0: 43 68 75 6e 6b 73 28 70 29 3b 0a 20 20 72 65 74  Chunks(p);.  ret
20f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2100: 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74 68 65  ../*.** Sync the
2110: 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   file..**.** If 
2120: 74 68 65 20 72 65 61 6c 20 66 69 6c 65 20 68 61  the real file ha
2130: 73 20 62 65 65 6e 20 63 72 65 61 74 65 64 2c 20  s been created, 
2140: 63 61 6c 6c 20 69 74 73 20 78 53 79 6e 63 20 6d  call its xSync m
2150: 65 74 68 6f 64 2e 20 4f 74 68 65 72 77 69 73 65  ethod. Otherwise
2160: 2c 20 0a 2a 2a 20 73 79 6e 63 69 6e 67 20 61 6e  , .** syncing an
2170: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6a 6f 75 72 6e   in-memory journ
2180: 61 6c 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 20 0a  al is a no-op. .
2190: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  */.static int me
21a0: 6d 6a 72 6e 6c 53 79 6e 63 28 73 71 6c 69 74 65  mjrnlSync(sqlite
21b0: 33 5f 66 69 6c 65 20 2a 70 4a 66 64 2c 20 69 6e  3_file *pJfd, in
21c0: 74 20 66 6c 61 67 73 29 7b 0a 20 20 55 4e 55 53  t flags){.  UNUS
21d0: 45 44 5f 50 41 52 41 4d 45 54 45 52 32 28 70 4a  ED_PARAMETER2(pJ
21e0: 66 64 2c 20 66 6c 61 67 73 29 3b 0a 20 20 72 65  fd, flags);.  re
21f0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
2200: 7d 0a 0a 2f 2a 0a 2a 2a 20 51 75 65 72 79 20 74  }../*.** Query t
2210: 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 66  he size of the f
2220: 69 6c 65 20 69 6e 20 62 79 74 65 73 2e 0a 2a 2f  ile in bytes..*/
2230: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d 6a  .static int memj
2240: 72 6e 6c 46 69 6c 65 53 69 7a 65 28 73 71 6c 69  rnlFileSize(sqli
2250: 74 65 33 5f 66 69 6c 65 20 2a 70 4a 66 64 2c 20  te3_file *pJfd, 
2260: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53  sqlite_int64 *pS
2270: 69 7a 65 29 7b 0a 20 20 4d 65 6d 4a 6f 75 72 6e  ize){.  MemJourn
2280: 61 6c 20 2a 70 20 3d 20 28 4d 65 6d 4a 6f 75 72  al *p = (MemJour
2290: 6e 61 6c 20 2a 29 70 4a 66 64 3b 0a 20 20 2a 70  nal *)pJfd;.  *p
22a0: 53 69 7a 65 20 3d 20 28 73 71 6c 69 74 65 5f 69  Size = (sqlite_i
22b0: 6e 74 36 34 29 20 70 2d 3e 65 6e 64 70 6f 69 6e  nt64) p->endpoin
22c0: 74 2e 69 4f 66 66 73 65 74 3b 0a 20 20 72 65 74  t.iOffset;.  ret
22d0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
22e0: 0a 0a 2f 2a 0a 2a 2a 20 54 61 62 6c 65 20 6f 66  ../*.** Table of
22f0: 20 6d 65 74 68 6f 64 73 20 66 6f 72 20 4d 65 6d   methods for Mem
2300: 4a 6f 75 72 6e 61 6c 20 73 71 6c 69 74 65 33 5f  Journal sqlite3_
2310: 66 69 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a  file object..*/.
2320: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73 74 72  static const str
2330: 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  uct sqlite3_io_m
2340: 65 74 68 6f 64 73 20 4d 65 6d 4a 6f 75 72 6e 61  ethods MemJourna
2350: 6c 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 31  lMethods = {.  1
2360: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2370: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
2380: 20 20 6d 65 6d 6a 72 6e 6c 43 6c 6f 73 65 2c 20    memjrnlClose, 
2390: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a 2f      /* xClose */
23a0: 0a 20 20 6d 65 6d 6a 72 6e 6c 52 65 61 64 2c 20  .  memjrnlRead, 
23b0: 20 20 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f       /* xRead */
23c0: 0a 20 20 6d 65 6d 6a 72 6e 6c 57 72 69 74 65 2c  .  memjrnlWrite,
23d0: 20 20 20 20 20 2f 2a 20 78 57 72 69 74 65 20 2a       /* xWrite *
23e0: 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 54 72 75 6e 63  /.  memjrnlTrunc
23f0: 61 74 65 2c 20 20 2f 2a 20 78 54 72 75 6e 63 61  ate,  /* xTrunca
2400: 74 65 20 2a 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 53  te */.  memjrnlS
2410: 79 6e 63 2c 20 20 20 20 20 20 2f 2a 20 78 53 79  ync,      /* xSy
2420: 6e 63 20 2a 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 46  nc */.  memjrnlF
2430: 69 6c 65 53 69 7a 65 2c 20 20 2f 2a 20 78 46 69  ileSize,  /* xFi
2440: 6c 65 53 69 7a 65 20 2a 2f 0a 20 20 30 2c 20 20  leSize */.  0,  
2450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2460: 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20 30 2c 20 20   xLock */.  0,  
2470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2480: 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20 30 2c   xUnlock */.  0,
2490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24a0: 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  /* xCheckReserve
24b0: 64 4c 6f 63 6b 20 2a 2f 0a 20 20 30 2c 20 20 20  dLock */.  0,   
24c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
24d0: 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a  xFileControl */.
24e0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
24f0: 20 20 20 20 2f 2a 20 78 53 65 63 74 6f 72 53 69      /* xSectorSi
2500: 7a 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  ze */.  0,      
2510: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
2520: 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74  viceCharacterist
2530: 69 63 73 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ics */.  0,     
2540: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
2550: 68 6d 4d 61 70 20 2a 2f 0a 20 20 30 2c 20 20 20  hmMap */.  0,   
2560: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2570: 78 53 68 6d 4c 6f 63 6b 20 2a 2f 0a 20 20 30 2c  xShmLock */.  0,
2580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2590: 2f 2a 20 78 53 68 6d 42 61 72 72 69 65 72 20 2a  /* xShmBarrier *
25a0: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
25b0: 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55 6e 6d        /* xShmUnm
25c0: 61 70 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  ap */.  0,      
25d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65            /* xFe
25e0: 74 63 68 20 2a 2f 0a 20 20 30 20 20 20 20 20 20  tch */.  0      
25f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
2600: 6e 66 65 74 63 68 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  nfetch */.};../*
2610: 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 6a 6f 75 72   .** Open a jour
2620: 6e 61 6c 20 66 69 6c 65 2e 20 0a 2a 2a 0a 2a 2a  nal file. .**.**
2630: 20 54 68 65 20 62 65 68 61 76 69 6f 75 72 20 6f   The behaviour o
2640: 66 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66 69  f the journal fi
2650: 6c 65 20 64 65 70 65 6e 64 73 20 6f 6e 20 74 68  le depends on th
2660: 65 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d  e value of param
2670: 65 74 65 72 20 0a 2a 2a 20 6e 53 70 69 6c 6c 2e  eter .** nSpill.
2680: 20 49 66 20 6e 53 70 69 6c 6c 20 69 73 20 30 2c   If nSpill is 0,
2690: 20 74 68 65 6e 20 74 68 65 20 6a 6f 75 72 6e 61   then the journa
26a0: 6c 20 66 69 6c 65 20 69 73 20 61 6c 77 61 79 73  l file is always
26b0: 20 63 72 65 61 74 65 20 61 6e 64 20 0a 2a 2a 20   create and .** 
26c0: 61 63 63 65 73 73 65 64 20 75 73 69 6e 67 20 74  accessed using t
26d0: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 56 46  he underlying VF
26e0: 53 2e 20 49 66 20 6e 53 70 69 6c 6c 20 69 73 20  S. If nSpill is 
26f0: 6c 65 73 73 20 74 68 61 6e 20 7a 65 72 6f 2c 20  less than zero, 
2700: 74 68 65 6e 0a 2a 2a 20 61 6c 6c 20 63 6f 6e 74  then.** all cont
2710: 65 6e 74 20 69 73 20 61 6c 77 61 79 73 20 73 74  ent is always st
2720: 6f 72 65 64 20 69 6e 20 6d 61 69 6e 2d 6d 65 6d  ored in main-mem
2730: 6f 72 79 2e 20 46 69 6e 61 6c 6c 79 2c 20 69 66  ory. Finally, if
2740: 20 6e 53 70 69 6c 6c 20 69 73 20 61 0a 2a 2a 20   nSpill is a.** 
2750: 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65 2c 20  positive value, 
2760: 74 68 65 6e 20 74 68 65 20 6a 6f 75 72 6e 61 6c  then the journal
2770: 20 66 69 6c 65 20 69 73 20 69 6e 69 74 69 61 6c   file is initial
2780: 6c 79 20 63 72 65 61 74 65 64 20 69 6e 2d 6d 65  ly created in-me
2790: 6d 6f 72 79 0a 2a 2a 20 62 75 74 20 6d 61 79 20  mory.** but may 
27a0: 62 65 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69  be flushed to di
27b0: 73 6b 20 6c 61 74 65 72 20 6f 6e 2e 20 49 6e 20  sk later on. In 
27c0: 74 68 69 73 20 63 61 73 65 20 74 68 65 20 6a 6f  this case the jo
27d0: 75 72 6e 61 6c 20 66 69 6c 65 20 69 73 0a 2a 2a  urnal file is.**
27e0: 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69 73 6b   flushed to disk
27f0: 20 65 69 74 68 65 72 20 77 68 65 6e 20 69 74 20   either when it 
2800: 67 72 6f 77 73 20 6c 61 72 67 65 72 20 74 68 61  grows larger tha
2810: 6e 20 6e 53 70 69 6c 6c 20 62 79 74 65 73 20 69  n nSpill bytes i
2820: 6e 20 73 69 7a 65 2c 0a 2a 2a 20 6f 72 20 77 68  n size,.** or wh
2830: 65 6e 20 73 71 6c 69 74 65 33 4a 6f 75 72 6e 61  en sqlite3Journa
2840: 6c 43 72 65 61 74 65 28 29 20 69 73 20 63 61 6c  lCreate() is cal
2850: 6c 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  led..*/.int sqli
2860: 74 65 33 4a 6f 75 72 6e 61 6c 4f 70 65 6e 28 0a  te3JournalOpen(.
2870: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70    sqlite3_vfs *p
2880: 56 66 73 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  Vfs,         /* 
2890: 54 68 65 20 56 46 53 20 74 6f 20 75 73 65 20 66  The VFS to use f
28a0: 6f 72 20 61 63 74 75 61 6c 20 66 69 6c 65 20 49  or actual file I
28b0: 2f 4f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  /O */.  const ch
28c0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20  ar *zName,      
28d0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68     /* Name of th
28e0: 65 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 2a  e journal file *
28f0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
2900: 20 2a 70 4a 66 64 2c 20 20 20 20 20 20 20 20 2f   *pJfd,        /
2910: 2a 20 50 72 65 61 6c 6c 6f 63 61 74 65 64 2c 20  * Preallocated, 
2920: 62 6c 61 6e 6b 20 66 69 6c 65 20 68 61 6e 64 6c  blank file handl
2930: 65 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73  e */.  int flags
2940: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2950: 20 20 2f 2a 20 4f 70 65 6e 69 6e 67 20 66 6c 61    /* Opening fla
2960: 67 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 70 69  gs */.  int nSpi
2970: 6c 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ll              
2980: 20 20 20 2f 2a 20 42 79 74 65 73 20 62 75 66 66     /* Bytes buff
2990: 65 72 65 64 20 62 65 66 6f 72 65 20 6f 70 65 6e  ered before open
29a0: 69 6e 67 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a  ing the file */.
29b0: 29 7b 0a 20 20 4d 65 6d 4a 6f 75 72 6e 61 6c 20  ){.  MemJournal 
29c0: 2a 70 20 3d 20 28 4d 65 6d 4a 6f 75 72 6e 61 6c  *p = (MemJournal
29d0: 2a 29 70 4a 66 64 3b 0a 0a 20 20 2f 2a 20 5a 65  *)pJfd;..  /* Ze
29e0: 72 6f 20 74 68 65 20 66 69 6c 65 2d 68 61 6e 64  ro the file-hand
29f0: 6c 65 20 6f 62 6a 65 63 74 2e 20 49 66 20 6e 53  le object. If nS
2a00: 70 69 6c 6c 20 77 61 73 20 70 61 73 73 65 64 20  pill was passed 
2a10: 7a 65 72 6f 2c 20 69 6e 69 74 69 61 6c 69 7a 65  zero, initialize
2a20: 0a 20 20 2a 2a 20 69 74 20 75 73 69 6e 67 20 74  .  ** it using t
2a30: 68 65 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e  he sqlite3OsOpen
2a40: 28 29 20 66 75 6e 63 74 69 6f 6e 20 6f 66 20 74  () function of t
2a50: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 56 46  he underlying VF
2a60: 53 2e 20 49 6e 20 74 68 69 73 0a 20 20 2a 2a 20  S. In this.  ** 
2a70: 63 61 73 65 20 6e 6f 6e 65 20 6f 66 20 74 68 65  case none of the
2a80: 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20 6d 6f   code in this mo
2a90: 64 75 6c 65 20 69 73 20 65 78 65 63 75 74 65 64  dule is executed
2aa0: 20 61 73 20 61 20 72 65 73 75 6c 74 20 6f 66 20   as a result of 
2ab0: 63 61 6c 6c 73 0a 20 20 2a 2a 20 6d 61 64 65 20  calls.  ** made 
2ac0: 6f 6e 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66  on the journal f
2ad0: 69 6c 65 2d 68 61 6e 64 6c 65 2e 20 20 2a 2f 0a  ile-handle.  */.
2ae0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
2af0: 69 7a 65 6f 66 28 4d 65 6d 4a 6f 75 72 6e 61 6c  izeof(MemJournal
2b00: 29 29 3b 0a 20 20 69 66 28 20 6e 53 70 69 6c 6c  ));.  if( nSpill
2b10: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
2b20: 6e 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 28  n sqlite3OsOpen(
2b30: 70 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 70 4a 66  pVfs, zName, pJf
2b40: 64 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a 20 20  d, flags, 0);.  
2b50: 7d 0a 0a 20 20 69 66 28 20 6e 53 70 69 6c 6c 3e  }..  if( nSpill>
2b60: 30 20 29 7b 0a 20 20 20 20 70 2d 3e 6e 43 68 75  0 ){.    p->nChu
2b70: 6e 6b 53 69 7a 65 20 3d 20 6e 53 70 69 6c 6c 3b  nkSize = nSpill;
2b80: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 2d  .  }else{.    p-
2b90: 3e 6e 43 68 75 6e 6b 53 69 7a 65 20 3d 20 38 20  >nChunkSize = 8 
2ba0: 2b 20 4d 45 4d 4a 4f 55 52 4e 41 4c 5f 44 46 4c  + MEMJOURNAL_DFL
2bb0: 54 5f 46 49 4c 45 43 48 55 4e 4b 53 49 5a 45 20  T_FILECHUNKSIZE 
2bc0: 2d 20 73 69 7a 65 6f 66 28 46 69 6c 65 43 68 75  - sizeof(FileChu
2bd0: 6e 6b 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  nk);.    assert(
2be0: 20 4d 45 4d 4a 4f 55 52 4e 41 4c 5f 44 46 4c 54   MEMJOURNAL_DFLT
2bf0: 5f 46 49 4c 45 43 48 55 4e 4b 53 49 5a 45 3d 3d  _FILECHUNKSIZE==
2c00: 66 69 6c 65 43 68 75 6e 6b 53 69 7a 65 28 70 2d  fileChunkSize(p-
2c10: 3e 6e 43 68 75 6e 6b 53 69 7a 65 29 20 29 3b 0a  >nChunkSize) );.
2c20: 20 20 7d 0a 0a 20 20 70 2d 3e 70 4d 65 74 68 6f    }..  p->pMetho
2c30: 64 20 3d 20 28 63 6f 6e 73 74 20 73 71 6c 69 74  d = (const sqlit
2c40: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 2a 29 26  e3_io_methods*)&
2c50: 4d 65 6d 4a 6f 75 72 6e 61 6c 4d 65 74 68 6f 64  MemJournalMethod
2c60: 73 3b 0a 20 20 70 2d 3e 6e 53 70 69 6c 6c 20 3d  s;.  p->nSpill =
2c70: 20 6e 53 70 69 6c 6c 3b 0a 20 20 70 2d 3e 66 6c   nSpill;.  p->fl
2c80: 61 67 73 20 3d 20 66 6c 61 67 73 3b 0a 20 20 70  ags = flags;.  p
2c90: 2d 3e 7a 4a 6f 75 72 6e 61 6c 20 3d 20 7a 4e 61  ->zJournal = zNa
2ca0: 6d 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20 3d 20  me;.  p->pVfs = 
2cb0: 70 56 66 73 3b 0a 20 20 72 65 74 75 72 6e 20 53  pVfs;.  return S
2cc0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2cd0: 2a 2a 20 4f 70 65 6e 20 61 6e 20 69 6e 2d 6d 65  ** Open an in-me
2ce0: 6d 6f 72 79 20 6a 6f 75 72 6e 61 6c 20 66 69 6c  mory journal fil
2cf0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
2d00: 65 33 4d 65 6d 4a 6f 75 72 6e 61 6c 4f 70 65 6e  e3MemJournalOpen
2d10: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
2d20: 4a 66 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 4a  Jfd){.  sqlite3J
2d30: 6f 75 72 6e 61 6c 4f 70 65 6e 28 30 2c 20 30 2c  ournalOpen(0, 0,
2d40: 20 70 4a 66 64 2c 20 30 2c 20 2d 31 29 3b 0a 7d   pJfd, 0, -1);.}
2d50: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
2d60: 45 4e 41 42 4c 45 5f 41 54 4f 4d 49 43 5f 57 52  ENABLE_ATOMIC_WR
2d70: 49 54 45 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65  ITE./*.** If the
2d80: 20 61 72 67 75 6d 65 6e 74 20 70 20 70 6f 69 6e   argument p poin
2d90: 74 73 20 74 6f 20 61 20 4d 65 6d 4a 6f 75 72 6e  ts to a MemJourn
2da0: 61 6c 20 73 74 72 75 63 74 75 72 65 20 74 68 61  al structure tha
2db0: 74 20 69 73 20 6e 6f 74 20 61 6e 20 0a 2a 2a 20  t is not an .** 
2dc0: 69 6e 2d 6d 65 6d 6f 72 79 2d 6f 6e 6c 79 20 6a  in-memory-only j
2dd0: 6f 75 72 6e 61 6c 20 66 69 6c 65 20 28 69 2e 65  ournal file (i.e
2de0: 2e 20 69 73 20 6f 6e 65 20 74 68 61 74 20 77 61  . is one that wa
2df0: 73 20 6f 70 65 6e 65 64 20 77 69 74 68 20 61 20  s opened with a 
2e00: 2b 76 65 0a 2a 2a 20 6e 53 70 69 6c 6c 20 70 61  +ve.** nSpill pa
2e10: 72 61 6d 65 74 65 72 29 2c 20 61 6e 64 20 74 68  rameter), and th
2e20: 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66 69 6c  e underlying fil
2e30: 65 20 68 61 73 20 6e 6f 74 20 79 65 74 20 62 65  e has not yet be
2e40: 65 6e 20 63 72 65 61 74 65 64 2c 20 0a 2a 2a 20  en created, .** 
2e50: 63 72 65 61 74 65 20 69 74 20 6e 6f 77 2e 0a 2a  create it now..*
2e60: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a 6f 75  /.int sqlite3Jou
2e70: 72 6e 61 6c 43 72 65 61 74 65 28 73 71 6c 69 74  rnalCreate(sqlit
2e80: 65 33 5f 66 69 6c 65 20 2a 70 29 7b 0a 20 20 69  e3_file *p){.  i
2e90: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2ea0: 4b 3b 0a 20 20 69 66 28 20 70 2d 3e 70 4d 65 74  K;.  if( p->pMet
2eb0: 68 6f 64 73 3d 3d 26 4d 65 6d 4a 6f 75 72 6e 61  hods==&MemJourna
2ec0: 6c 4d 65 74 68 6f 64 73 20 26 26 20 28 28 4d 65  lMethods && ((Me
2ed0: 6d 4a 6f 75 72 6e 61 6c 2a 29 70 29 2d 3e 6e 53  mJournal*)p)->nS
2ee0: 70 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 72 63  pill>0 ){.    rc
2ef0: 20 3d 20 6d 65 6d 6a 72 6e 6c 43 72 65 61 74 65   = memjrnlCreate
2f00: 46 69 6c 65 28 28 4d 65 6d 4a 6f 75 72 6e 61 6c  File((MemJournal
2f10: 2a 29 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  *)p);.  }.  retu
2f20: 72 6e 20 72 63 3b 0a 7d 0a 23 65 6e 64 69 66 0a  rn rc;.}.#endif.
2f30: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 6c 65 2d  ./*.** The file-
2f40: 68 61 6e 64 6c 65 20 70 61 73 73 65 64 20 61 73  handle passed as
2f50: 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65   the only argume
2f60: 6e 74 20 69 73 20 6f 70 65 6e 20 6f 6e 20 61 20  nt is open on a 
2f70: 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 2e 0a 2a 2a  journal file..**
2f80: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20   Return true if 
2f90: 74 68 69 73 20 22 6a 6f 75 72 6e 61 6c 20 66 69  this "journal fi
2fa0: 6c 65 22 20 69 73 20 63 75 72 72 65 6e 74 6c 79  le" is currently
2fb0: 20 73 74 6f 72 65 64 20 69 6e 20 68 65 61 70 20   stored in heap 
2fc0: 6d 65 6d 6f 72 79 2c 0a 2a 2a 20 6f 72 20 66 61  memory,.** or fa
2fd0: 6c 73 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  lse otherwise..*
2fe0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a 6f 75  /.int sqlite3Jou
2ff0: 72 6e 61 6c 49 73 49 6e 4d 65 6d 6f 72 79 28 73  rnalIsInMemory(s
3000: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 29 7b  qlite3_file *p){
3010: 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 70 4d 65  .  return p->pMe
3020: 74 68 6f 64 73 3d 3d 26 4d 65 6d 4a 6f 75 72 6e  thods==&MemJourn
3030: 61 6c 4d 65 74 68 6f 64 73 3b 0a 7d 0a 0a 2f 2a  alMethods;.}../*
3040: 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20   .** Return the 
3050: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
3060: 72 65 71 75 69 72 65 64 20 74 6f 20 73 74 6f 72  required to stor
3070: 65 20 61 20 4a 6f 75 72 6e 61 6c 46 69 6c 65 20  e a JournalFile 
3080: 74 68 61 74 20 75 73 65 73 20 76 66 73 0a 2a 2a  that uses vfs.**
3090: 20 70 56 66 73 20 74 6f 20 63 72 65 61 74 65 20   pVfs to create 
30a0: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 6f  the underlying o
30b0: 6e 2d 64 69 73 6b 20 66 69 6c 65 73 2e 0a 2a 2f  n-disk files..*/
30c0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a 6f 75 72  .int sqlite3Jour
30d0: 6e 61 6c 53 69 7a 65 28 73 71 6c 69 74 65 33 5f  nalSize(sqlite3_
30e0: 76 66 73 20 2a 70 56 66 73 29 7b 0a 20 20 72 65  vfs *pVfs){.  re
30f0: 74 75 72 6e 20 4d 41 58 28 70 56 66 73 2d 3e 73  turn MAX(pVfs->s
3100: 7a 4f 73 46 69 6c 65 2c 20 28 69 6e 74 29 73 69  zOsFile, (int)si
3110: 7a 65 6f 66 28 4d 65 6d 4a 6f 75 72 6e 61 6c 29  zeof(MemJournal)
3120: 29 3b 0a 7d 0a                                   );.}.