/ Hex Artifact Content
Login

Artifact 13ae08696117438e7fa2518af71e52ee00c02395:


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 69 66 28 20 28 69 41 6d 74 2b 69 4f  ;.  if( (iAmt+iO
0be0: 66 73 74 29 3e 70 2d 3e 65 6e 64 70 6f 69 6e 74  fst)>p->endpoint
0bf0: 2e 69 4f 66 66 73 65 74 20 29 7b 0a 20 20 20 20  .iOffset ){.    
0c00: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
0c10: 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 3b 0a  ERR_SHORT_READ;.
0c20: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 75 38 20    }else{.    u8 
0c30: 2a 7a 4f 75 74 20 3d 20 7a 42 75 66 3b 0a 20 20  *zOut = zBuf;.  
0c40: 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 69 41    int nRead = iA
0c50: 6d 74 3b 0a 20 20 20 20 69 6e 74 20 69 43 68 75  mt;.    int iChu
0c60: 6e 6b 4f 66 66 73 65 74 3b 0a 20 20 20 20 46 69  nkOffset;.    Fi
0c70: 6c 65 43 68 75 6e 6b 20 2a 70 43 68 75 6e 6b 3b  leChunk *pChunk;
0c80: 0a 0a 20 20 20 20 69 66 28 20 70 2d 3e 72 65 61  ..    if( p->rea
0c90: 64 70 6f 69 6e 74 2e 69 4f 66 66 73 65 74 21 3d  dpoint.iOffset!=
0ca0: 69 4f 66 73 74 20 7c 7c 20 69 4f 66 73 74 3d 3d  iOfst || iOfst==
0cb0: 30 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  0 ){.      sqlit
0cc0: 65 33 5f 69 6e 74 36 34 20 69 4f 66 66 20 3d 20  e3_int64 iOff = 
0cd0: 30 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 43 68  0;.      for(pCh
0ce0: 75 6e 6b 3d 70 2d 3e 70 46 69 72 73 74 3b 20 0a  unk=p->pFirst; .
0cf0: 20 20 20 20 20 20 20 20 20 20 41 4c 57 41 59 53            ALWAYS
0d00: 28 70 43 68 75 6e 6b 29 20 26 26 20 28 69 4f 66  (pChunk) && (iOf
0d10: 66 2b 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 29  f+p->nChunkSize)
0d20: 3c 3d 69 4f 66 73 74 3b 0a 20 20 20 20 20 20 20  <=iOfst;.       
0d30: 20 20 20 70 43 68 75 6e 6b 3d 70 43 68 75 6e 6b     pChunk=pChunk
0d40: 2d 3e 70 4e 65 78 74 0a 20 20 20 20 20 20 29 7b  ->pNext.      ){
0d50: 0a 20 20 20 20 20 20 20 20 69 4f 66 66 20 2b 3d  .        iOff +=
0d60: 20 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 3b 0a   p->nChunkSize;.
0d70: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
0d80: 65 7b 0a 20 20 20 20 20 20 70 43 68 75 6e 6b 20  e{.      pChunk 
0d90: 3d 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74 2e 70  = p->readpoint.p
0da0: 43 68 75 6e 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  Chunk;.    }..  
0db0: 20 20 69 43 68 75 6e 6b 4f 66 66 73 65 74 20 3d    iChunkOffset =
0dc0: 20 28 69 6e 74 29 28 69 4f 66 73 74 25 70 2d 3e   (int)(iOfst%p->
0dd0: 6e 43 68 75 6e 6b 53 69 7a 65 29 3b 0a 20 20 20  nChunkSize);.   
0de0: 20 64 6f 20 7b 0a 20 20 20 20 20 20 69 6e 74 20   do {.      int 
0df0: 69 53 70 61 63 65 20 3d 20 70 2d 3e 6e 43 68 75  iSpace = p->nChu
0e00: 6e 6b 53 69 7a 65 20 2d 20 69 43 68 75 6e 6b 4f  nkSize - iChunkO
0e10: 66 66 73 65 74 3b 0a 20 20 20 20 20 20 69 6e 74  ffset;.      int
0e20: 20 6e 43 6f 70 79 20 3d 20 4d 49 4e 28 6e 52 65   nCopy = MIN(nRe
0e30: 61 64 2c 20 28 70 2d 3e 6e 43 68 75 6e 6b 53 69  ad, (p->nChunkSi
0e40: 7a 65 20 2d 20 69 43 68 75 6e 6b 4f 66 66 73 65  ze - iChunkOffse
0e50: 74 29 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  t));.      memcp
0e60: 79 28 7a 4f 75 74 2c 20 28 75 38 2a 29 70 43 68  y(zOut, (u8*)pCh
0e70: 75 6e 6b 2d 3e 7a 43 68 75 6e 6b 20 2b 20 69 43  unk->zChunk + iC
0e80: 68 75 6e 6b 4f 66 66 73 65 74 2c 20 6e 43 6f 70  hunkOffset, nCop
0e90: 79 29 3b 0a 20 20 20 20 20 20 7a 4f 75 74 20 2b  y);.      zOut +
0ea0: 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 20 20 6e  = nCopy;.      n
0eb0: 52 65 61 64 20 2d 3d 20 69 53 70 61 63 65 3b 0a  Read -= iSpace;.
0ec0: 20 20 20 20 20 20 69 43 68 75 6e 6b 4f 66 66 73        iChunkOffs
0ed0: 65 74 20 3d 20 30 3b 0a 20 20 20 20 7d 20 77 68  et = 0;.    } wh
0ee0: 69 6c 65 28 20 6e 52 65 61 64 3e 3d 30 20 26 26  ile( nRead>=0 &&
0ef0: 20 28 70 43 68 75 6e 6b 3d 70 43 68 75 6e 6b 2d   (pChunk=pChunk-
0f00: 3e 70 4e 65 78 74 29 21 3d 30 20 26 26 20 6e 52  >pNext)!=0 && nR
0f10: 65 61 64 3e 30 20 29 3b 0a 20 20 20 20 70 2d 3e  ead>0 );.    p->
0f20: 72 65 61 64 70 6f 69 6e 74 2e 69 4f 66 66 73 65  readpoint.iOffse
0f30: 74 20 3d 20 69 4f 66 73 74 2b 69 41 6d 74 3b 0a  t = iOfst+iAmt;.
0f40: 20 20 20 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74      p->readpoint
0f50: 2e 70 43 68 75 6e 6b 20 3d 20 70 43 68 75 6e 6b  .pChunk = pChunk
0f60: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
0f70: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
0f80: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73  .** Free the lis
0f90: 74 20 6f 66 20 46 69 6c 65 43 68 75 6e 6b 20 73  t of FileChunk s
0fa0: 74 72 75 63 74 75 72 65 73 20 68 65 61 64 65 64  tructures headed
0fb0: 20 61 74 20 4d 65 6d 4a 6f 75 72 6e 61 6c 2e 70   at MemJournal.p
0fc0: 46 69 72 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  First..*/.static
0fd0: 20 76 6f 69 64 20 6d 65 6d 6a 72 6e 6c 46 72 65   void memjrnlFre
0fe0: 65 43 68 75 6e 6b 73 28 4d 65 6d 4a 6f 75 72 6e  eChunks(MemJourn
0ff0: 61 6c 20 2a 70 29 7b 0a 20 20 46 69 6c 65 43 68  al *p){.  FileCh
1000: 75 6e 6b 20 2a 70 49 74 65 72 3b 0a 20 20 46 69  unk *pIter;.  Fi
1010: 6c 65 43 68 75 6e 6b 20 2a 70 4e 65 78 74 3b 0a  leChunk *pNext;.
1020: 20 20 66 6f 72 28 70 49 74 65 72 3d 70 2d 3e 70    for(pIter=p->p
1030: 46 69 72 73 74 3b 20 70 49 74 65 72 3b 20 70 49  First; pIter; pI
1040: 74 65 72 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ter=pNext){.    
1050: 70 4e 65 78 74 20 3d 20 70 49 74 65 72 2d 3e 70  pNext = pIter->p
1060: 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65  Next;.    sqlite
1070: 33 5f 66 72 65 65 28 70 49 74 65 72 29 3b 0a 20  3_free(pIter);. 
1080: 20 7d 20 0a 20 20 70 2d 3e 70 46 69 72 73 74 20   } .  p->pFirst 
1090: 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c  = 0;.}../*.** Fl
10a0: 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ush the contents
10b0: 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20   of memory to a 
10c0: 72 65 61 6c 20 66 69 6c 65 20 6f 6e 20 64 69 73  real file on dis
10d0: 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  k..*/.static int
10e0: 20 6d 65 6d 6a 72 6e 6c 43 72 65 61 74 65 46 69   memjrnlCreateFi
10f0: 6c 65 28 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70  le(MemJournal *p
1100: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73  ){.  int rc;.  s
1110: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 52 65  qlite3_file *pRe
1120: 61 6c 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69  al = (sqlite3_fi
1130: 6c 65 2a 29 70 3b 0a 20 20 4d 65 6d 4a 6f 75 72  le*)p;.  MemJour
1140: 6e 61 6c 20 63 6f 70 79 20 3d 20 2a 70 3b 0a 0a  nal copy = *p;..
1150: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
1160: 69 7a 65 6f 66 28 4d 65 6d 4a 6f 75 72 6e 61 6c  izeof(MemJournal
1170: 29 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  ));.  rc = sqlit
1180: 65 33 4f 73 4f 70 65 6e 28 63 6f 70 79 2e 70 56  e3OsOpen(copy.pV
1190: 66 73 2c 20 63 6f 70 79 2e 7a 4a 6f 75 72 6e 61  fs, copy.zJourna
11a0: 6c 2c 20 70 52 65 61 6c 2c 20 63 6f 70 79 2e 66  l, pReal, copy.f
11b0: 6c 61 67 73 2c 20 30 29 3b 0a 20 20 69 66 28 20  lags, 0);.  if( 
11c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11d0: 0a 20 20 20 20 69 6e 74 20 6e 43 68 75 6e 6b 20  .    int nChunk 
11e0: 3d 20 63 6f 70 79 2e 6e 43 68 75 6e 6b 53 69 7a  = copy.nChunkSiz
11f0: 65 3b 0a 20 20 20 20 69 36 34 20 69 4f 66 66 20  e;.    i64 iOff 
1200: 3d 20 30 3b 0a 20 20 20 20 46 69 6c 65 43 68 75  = 0;.    FileChu
1210: 6e 6b 20 2a 70 49 74 65 72 3b 0a 20 20 20 20 66  nk *pIter;.    f
1220: 6f 72 28 70 49 74 65 72 3d 63 6f 70 79 2e 70 46  or(pIter=copy.pF
1230: 69 72 73 74 3b 20 70 49 74 65 72 3b 20 70 49 74  irst; pIter; pIt
1240: 65 72 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74 29  er=pIter->pNext)
1250: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 57 72 69  {.      int nWri
1260: 74 65 20 3d 20 6e 43 68 75 6e 6b 3b 0a 20 20 20  te = nChunk;.   
1270: 20 20 20 69 66 28 20 70 49 74 65 72 3d 3d 63 6f     if( pIter==co
1280: 70 79 2e 65 6e 64 70 6f 69 6e 74 2e 70 43 68 75  py.endpoint.pChu
1290: 6e 6b 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 57  nk ){.        nW
12a0: 72 69 74 65 20 3d 20 63 6f 70 79 2e 65 6e 64 70  rite = copy.endp
12b0: 6f 69 6e 74 2e 69 4f 66 66 73 65 74 20 25 20 63  oint.iOffset % c
12c0: 6f 70 79 2e 6e 43 68 75 6e 6b 53 69 7a 65 3b 0a  opy.nChunkSize;.
12d0: 20 20 20 20 20 20 20 20 69 66 28 20 6e 57 72 69          if( nWri
12e0: 74 65 3d 3d 30 20 29 20 6e 57 72 69 74 65 20 3d  te==0 ) nWrite =
12f0: 20 63 6f 70 79 2e 6e 43 68 75 6e 6b 53 69 7a 65   copy.nChunkSize
1300: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
1310: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
1320: 69 74 65 28 70 52 65 61 6c 2c 20 28 75 38 2a 29  ite(pReal, (u8*)
1330: 70 49 74 65 72 2d 3e 7a 43 68 75 6e 6b 2c 20 6e  pIter->zChunk, n
1340: 57 72 69 74 65 2c 20 69 4f 66 66 29 3b 0a 20 20  Write, iOff);.  
1350: 20 20 20 20 69 66 28 20 72 63 20 29 20 62 72 65      if( rc ) bre
1360: 61 6b 3b 0a 20 20 20 20 20 20 69 4f 66 66 20 2b  ak;.      iOff +
1370: 3d 20 6e 57 72 69 74 65 3b 0a 20 20 20 20 7d 0a  = nWrite;.    }.
1380: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
1390: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2f  TE_OK ){.      /
13a0: 2a 20 4e 6f 20 65 72 72 6f 72 20 68 61 73 20 6f  * No error has o
13b0: 63 63 75 72 72 65 64 2e 20 46 72 65 65 20 74 68  ccurred. Free th
13c0: 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66  e in-memory buff
13d0: 65 72 73 2e 20 2a 2f 0a 20 20 20 20 20 20 6d 65  ers. */.      me
13e0: 6d 6a 72 6e 6c 46 72 65 65 43 68 75 6e 6b 73 28  mjrnlFreeChunks(
13f0: 26 63 6f 70 79 29 3b 0a 20 20 20 20 7d 0a 20 20  &copy);.    }.  
1400: 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  }.  if( rc!=SQLI
1410: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20  TE_OK ){.    /* 
1420: 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  If an error occu
1430: 72 72 65 64 20 77 68 69 6c 65 20 63 72 65 61 74  rred while creat
1440: 69 6e 67 20 6f 72 20 77 72 69 74 69 6e 67 20 74  ing or writing t
1450: 6f 20 74 68 65 20 66 69 6c 65 2c 20 72 65 73 74  o the file, rest
1460: 6f 72 65 0a 20 20 20 20 2a 2a 20 74 68 65 20 6f  ore.    ** the o
1470: 72 69 67 69 6e 61 6c 20 62 65 66 6f 72 65 20 72  riginal before r
1480: 65 74 75 72 6e 69 6e 67 2e 20 54 68 69 73 20 77  eturning. This w
1490: 61 79 2c 20 53 51 4c 69 74 65 20 75 73 65 73 20  ay, SQLite uses 
14a0: 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 0a 20 20  the in-memory.  
14b0: 20 20 2a 2a 20 6a 6f 75 72 6e 61 6c 20 64 61 74    ** journal dat
14c0: 61 20 74 6f 20 72 6f 6c 6c 20 62 61 63 6b 20 63  a to roll back c
14d0: 68 61 6e 67 65 73 20 6d 61 64 65 20 74 6f 20 74  hanges made to t
14e0: 68 65 20 69 6e 74 65 72 6e 61 6c 20 70 61 67 65  he internal page
14f0: 2d 63 61 63 68 65 0a 20 20 20 20 2a 2a 20 62 65  -cache.    ** be
1500: 66 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69  fore this functi
1510: 6f 6e 20 77 61 73 20 63 61 6c 6c 65 64 2e 20 20  on was called.  
1520: 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  */.    sqlite3Os
1530: 43 6c 6f 73 65 28 70 52 65 61 6c 29 3b 0a 20 20  Close(pReal);.  
1540: 20 20 2a 70 20 3d 20 63 6f 70 79 3b 0a 20 20 7d    *p = copy;.  }
1550: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1560: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64 61  ../*.** Write da
1570: 74 61 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a  ta to the file..
1580: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  */.static int me
1590: 6d 6a 72 6e 6c 57 72 69 74 65 28 0a 20 20 73 71  mjrnlWrite(.  sq
15a0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 4a 66 64  lite3_file *pJfd
15b0: 2c 20 20 20 20 2f 2a 20 54 68 65 20 6a 6f 75 72  ,    /* The jour
15c0: 6e 61 6c 20 66 69 6c 65 20 69 6e 74 6f 20 77 68  nal file into wh
15d0: 69 63 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  ich to write */.
15e0: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 7a 42    const void *zB
15f0: 75 66 2c 20 20 20 20 20 20 2f 2a 20 54 61 6b 65  uf,      /* Take
1600: 20 64 61 74 61 20 74 6f 20 62 65 20 77 72 69 74   data to be writ
1610: 74 65 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f  ten from here */
1620: 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 20 20 20  .  int iAmt,    
1630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
1640: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
1650: 77 72 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74  write */.  sqlit
1660: 65 5f 69 6e 74 36 34 20 69 4f 66 73 74 20 20 20  e_int64 iOfst   
1670: 20 20 2f 2a 20 42 65 67 69 6e 20 77 72 69 74 69    /* Begin writi
1680: 6e 67 20 61 74 20 74 68 69 73 20 6f 66 66 73 65  ng at this offse
1690: 74 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 20  t into the file 
16a0: 2a 2f 0a 29 7b 0a 20 20 4d 65 6d 4a 6f 75 72 6e  */.){.  MemJourn
16b0: 61 6c 20 2a 70 20 3d 20 28 4d 65 6d 4a 6f 75 72  al *p = (MemJour
16c0: 6e 61 6c 20 2a 29 70 4a 66 64 3b 0a 20 20 69 6e  nal *)pJfd;.  in
16d0: 74 20 6e 57 72 69 74 65 20 3d 20 69 41 6d 74 3b  t nWrite = iAmt;
16e0: 0a 20 20 75 38 20 2a 7a 57 72 69 74 65 20 3d 20  .  u8 *zWrite = 
16f0: 28 75 38 20 2a 29 7a 42 75 66 3b 0a 0a 20 20 2f  (u8 *)zBuf;..  /
1700: 2a 20 49 66 20 74 68 65 20 66 69 6c 65 20 73 68  * If the file sh
1710: 6f 75 6c 64 20 62 65 20 63 72 65 61 74 65 64 20  ould be created 
1720: 6e 6f 77 2c 20 63 72 65 61 74 65 20 69 74 20 61  now, create it a
1730: 6e 64 20 77 72 69 74 65 20 74 68 65 20 6e 65 77  nd write the new
1740: 20 64 61 74 61 0a 20 20 2a 2a 20 69 6e 74 6f 20   data.  ** into 
1750: 74 68 65 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b  the file on disk
1760: 2e 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 6e 53  . */.  if( p->nS
1770: 70 69 6c 6c 3e 30 20 26 26 20 28 69 41 6d 74 2b  pill>0 && (iAmt+
1780: 69 4f 66 73 74 29 3e 70 2d 3e 6e 53 70 69 6c 6c  iOfst)>p->nSpill
1790: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d   ){.    int rc =
17a0: 20 6d 65 6d 6a 72 6e 6c 43 72 65 61 74 65 46 69   memjrnlCreateFi
17b0: 6c 65 28 70 29 3b 0a 20 20 20 20 69 66 28 20 72  le(p);.    if( r
17c0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
17d0: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
17e0: 65 33 4f 73 57 72 69 74 65 28 70 4a 66 64 2c 20  e3OsWrite(pJfd, 
17f0: 7a 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73  zBuf, iAmt, iOfs
1800: 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65  t);.    }.    re
1810: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
1820: 2f 2a 20 49 66 20 74 68 65 20 63 6f 6e 74 65 6e  /* If the conten
1830: 74 73 20 6f 66 20 74 68 69 73 20 77 72 69 74 65  ts of this write
1840: 20 73 68 6f 75 6c 64 20 62 65 20 73 74 6f 72 65   should be store
1850: 64 20 69 6e 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20  d in memory */. 
1860: 20 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 6e   else{.    /* An
1870: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6a 6f 75 72 6e   in-memory journ
1880: 61 6c 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 6f  al file should o
1890: 6e 6c 79 20 65 76 65 72 20 62 65 20 61 70 70 65  nly ever be appe
18a0: 6e 64 65 64 20 74 6f 2e 20 52 61 6e 64 6f 6d 0a  nded to. Random.
18b0: 20 20 20 20 2a 2a 20 61 63 63 65 73 73 20 77 72      ** access wr
18c0: 69 74 65 73 20 61 72 65 20 6e 6f 74 20 72 65 71  ites are not req
18d0: 75 69 72 65 64 2e 20 54 68 65 20 6f 6e 6c 79 20  uired. The only 
18e0: 65 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 69  exception to thi
18f0: 73 20 69 73 20 77 68 65 6e 0a 20 20 20 20 2a 2a  s is when.    **
1900: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6a   the in-memory j
1910: 6f 75 72 6e 61 6c 20 69 73 20 62 65 69 6e 67 20  ournal is being 
1920: 75 73 65 64 20 62 79 20 61 20 63 6f 6e 6e 65 63  used by a connec
1930: 74 69 6f 6e 20 75 73 69 6e 67 20 74 68 65 0a 20  tion using the. 
1940: 20 20 20 2a 2a 20 61 74 6f 6d 69 63 2d 77 72 69     ** atomic-wri
1950: 74 65 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 2e  te optimization.
1960: 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 74 68   In this case th
1970: 65 20 66 69 72 73 74 20 32 38 20 62 79 74 65 73  e first 28 bytes
1980: 20 6f 66 20 74 68 65 0a 20 20 20 20 2a 2a 20 6a   of the.    ** j
1990: 6f 75 72 6e 61 6c 20 66 69 6c 65 20 6d 61 79 20  ournal file may 
19a0: 62 65 20 77 72 69 74 74 65 6e 20 61 73 20 70 61  be written as pa
19b0: 72 74 20 6f 66 20 63 6f 6d 6d 69 74 74 69 6e 67  rt of committing
19c0: 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e   the transaction
19d0: 2e 20 2a 2f 20 0a 20 20 20 20 61 73 73 65 72 74  . */ .    assert
19e0: 28 20 69 4f 66 73 74 3d 3d 70 2d 3e 65 6e 64 70  ( iOfst==p->endp
19f0: 6f 69 6e 74 2e 69 4f 66 66 73 65 74 20 7c 7c 20  oint.iOffset || 
1a00: 69 4f 66 73 74 3d 3d 30 20 29 3b 0a 23 69 66 64  iOfst==0 );.#ifd
1a10: 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
1a20: 5f 41 54 4f 4d 49 43 5f 57 52 49 54 45 0a 20 20  _ATOMIC_WRITE.  
1a30: 20 20 69 66 28 20 69 4f 66 73 74 3d 3d 30 20 26    if( iOfst==0 &
1a40: 26 20 70 2d 3e 70 46 69 72 73 74 20 29 7b 0a 20  & p->pFirst ){. 
1a50: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
1a60: 6e 43 68 75 6e 6b 53 69 7a 65 3e 69 41 6d 74 20  nChunkSize>iAmt 
1a70: 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  );.      memcpy(
1a80: 28 75 38 2a 29 70 2d 3e 70 46 69 72 73 74 2d 3e  (u8*)p->pFirst->
1a90: 7a 43 68 75 6e 6b 2c 20 7a 42 75 66 2c 20 69 41  zChunk, zBuf, iA
1aa0: 6d 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 0a 23  mt);.    }else.#
1ab0: 65 6c 73 65 0a 20 20 20 20 61 73 73 65 72 74 28  else.    assert(
1ac0: 20 69 4f 66 73 74 3e 30 20 7c 7c 20 70 2d 3e 70   iOfst>0 || p->p
1ad0: 46 69 72 73 74 3d 3d 30 20 29 3b 0a 23 65 6e 64  First==0 );.#end
1ae0: 69 66 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 77  if.    {.      w
1af0: 68 69 6c 65 28 20 6e 57 72 69 74 65 3e 30 20 29  hile( nWrite>0 )
1b00: 7b 0a 20 20 20 20 20 20 20 20 46 69 6c 65 43 68  {.        FileCh
1b10: 75 6e 6b 20 2a 70 43 68 75 6e 6b 20 3d 20 70 2d  unk *pChunk = p-
1b20: 3e 65 6e 64 70 6f 69 6e 74 2e 70 43 68 75 6e 6b  >endpoint.pChunk
1b30: 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 43  ;.        int iC
1b40: 68 75 6e 6b 4f 66 66 73 65 74 20 3d 20 28 69 6e  hunkOffset = (in
1b50: 74 29 28 70 2d 3e 65 6e 64 70 6f 69 6e 74 2e 69  t)(p->endpoint.i
1b60: 4f 66 66 73 65 74 25 70 2d 3e 6e 43 68 75 6e 6b  Offset%p->nChunk
1b70: 53 69 7a 65 29 3b 0a 20 20 20 20 20 20 20 20 69  Size);.        i
1b80: 6e 74 20 69 53 70 61 63 65 20 3d 20 4d 49 4e 28  nt iSpace = MIN(
1b90: 6e 57 72 69 74 65 2c 20 70 2d 3e 6e 43 68 75 6e  nWrite, p->nChun
1ba0: 6b 53 69 7a 65 20 2d 20 69 43 68 75 6e 6b 4f 66  kSize - iChunkOf
1bb0: 66 73 65 74 29 3b 0a 0a 20 20 20 20 20 20 20 20  fset);..        
1bc0: 69 66 28 20 69 43 68 75 6e 6b 4f 66 66 73 65 74  if( iChunkOffset
1bd0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
1be0: 20 2f 2a 20 4e 65 77 20 63 68 75 6e 6b 20 69 73   /* New chunk is
1bf0: 20 72 65 71 75 69 72 65 64 20 74 6f 20 65 78 74   required to ext
1c00: 65 6e 64 20 74 68 65 20 66 69 6c 65 2e 20 2a 2f  end the file. */
1c10: 0a 20 20 20 20 20 20 20 20 20 20 46 69 6c 65 43  .          FileC
1c20: 68 75 6e 6b 20 2a 70 4e 65 77 20 3d 20 73 71 6c  hunk *pNew = sql
1c30: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 66 69 6c 65  ite3_malloc(file
1c40: 43 68 75 6e 6b 53 69 7a 65 28 70 2d 3e 6e 43 68  ChunkSize(p->nCh
1c50: 75 6e 6b 53 69 7a 65 29 29 3b 0a 20 20 20 20 20  unkSize));.     
1c60: 20 20 20 20 20 69 66 28 20 21 70 4e 65 77 20 29       if( !pNew )
1c70: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  {.            re
1c80: 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52  turn SQLITE_IOER
1c90: 52 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20  R_NOMEM_BKPT;.  
1ca0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1cb0: 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20      pNew->pNext 
1cc0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69  = 0;.          i
1cd0: 66 28 20 70 43 68 75 6e 6b 20 29 7b 0a 20 20 20  f( pChunk ){.   
1ce0: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
1cf0: 20 70 2d 3e 70 46 69 72 73 74 20 29 3b 0a 20 20   p->pFirst );.  
1d00: 20 20 20 20 20 20 20 20 20 20 70 43 68 75 6e 6b            pChunk
1d10: 2d 3e 70 4e 65 78 74 20 3d 20 70 4e 65 77 3b 0a  ->pNext = pNew;.
1d20: 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
1d30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73  .            ass
1d40: 65 72 74 28 20 21 70 2d 3e 70 46 69 72 73 74 20  ert( !p->pFirst 
1d50: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  );.            p
1d60: 2d 3e 70 46 69 72 73 74 20 3d 20 70 4e 65 77 3b  ->pFirst = pNew;
1d70: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
1d80: 20 20 20 20 20 20 20 70 2d 3e 65 6e 64 70 6f 69         p->endpoi
1d90: 6e 74 2e 70 43 68 75 6e 6b 20 3d 20 70 4e 65 77  nt.pChunk = pNew
1da0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20  ;.        }..   
1db0: 20 20 20 20 20 6d 65 6d 63 70 79 28 28 75 38 2a       memcpy((u8*
1dc0: 29 70 2d 3e 65 6e 64 70 6f 69 6e 74 2e 70 43 68  )p->endpoint.pCh
1dd0: 75 6e 6b 2d 3e 7a 43 68 75 6e 6b 20 2b 20 69 43  unk->zChunk + iC
1de0: 68 75 6e 6b 4f 66 66 73 65 74 2c 20 7a 57 72 69  hunkOffset, zWri
1df0: 74 65 2c 20 69 53 70 61 63 65 29 3b 0a 20 20 20  te, iSpace);.   
1e00: 20 20 20 20 20 7a 57 72 69 74 65 20 2b 3d 20 69       zWrite += i
1e10: 53 70 61 63 65 3b 0a 20 20 20 20 20 20 20 20 6e  Space;.        n
1e20: 57 72 69 74 65 20 2d 3d 20 69 53 70 61 63 65 3b  Write -= iSpace;
1e30: 0a 20 20 20 20 20 20 20 20 70 2d 3e 65 6e 64 70  .        p->endp
1e40: 6f 69 6e 74 2e 69 4f 66 66 73 65 74 20 2b 3d 20  oint.iOffset += 
1e50: 69 53 70 61 63 65 3b 0a 20 20 20 20 20 20 7d 0a  iSpace;.      }.
1e60: 20 20 20 20 20 20 70 2d 3e 6e 53 69 7a 65 20 3d        p->nSize =
1e70: 20 69 41 6d 74 20 2b 20 69 4f 66 73 74 3b 0a 20   iAmt + iOfst;. 
1e80: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
1e90: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
1ea0: 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63 61 74 65 20  ./*.** Truncate 
1eb0: 74 68 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20  the file..**.** 
1ec0: 49 66 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66  If the journal f
1ed0: 69 6c 65 20 69 73 20 61 6c 72 65 61 64 79 20 6f  ile is already o
1ee0: 6e 20 64 69 73 6b 2c 20 74 72 75 6e 63 61 74 65  n disk, truncate
1ef0: 20 69 74 20 74 68 65 72 65 2e 20 4f 72 2c 20 69   it there. Or, i
1f00: 66 20 69 74 0a 2a 2a 20 69 73 20 73 74 69 6c 6c  f it.** is still
1f10: 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 20   in main memory 
1f20: 62 75 74 20 69 73 20 62 65 69 6e 67 20 74 72 75  but is being tru
1f30: 6e 63 61 74 65 64 20 74 6f 20 7a 65 72 6f 20 62  ncated to zero b
1f40: 79 74 65 73 20 69 6e 20 73 69 7a 65 2c 0a 2a 2a  ytes in size,.**
1f50: 20 69 67 6e 6f 72 65 20 0a 2a 2f 0a 73 74 61 74   ignore .*/.stat
1f60: 69 63 20 69 6e 74 20 6d 65 6d 6a 72 6e 6c 54 72  ic int memjrnlTr
1f70: 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 66  uncate(sqlite3_f
1f80: 69 6c 65 20 2a 70 4a 66 64 2c 20 73 71 6c 69 74  ile *pJfd, sqlit
1f90: 65 5f 69 6e 74 36 34 20 73 69 7a 65 29 7b 0a 20  e_int64 size){. 
1fa0: 20 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70 20 3d   MemJournal *p =
1fb0: 20 28 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 29 70   (MemJournal *)p
1fc0: 4a 66 64 3b 0a 20 20 69 66 28 20 41 4c 57 41 59  Jfd;.  if( ALWAY
1fd0: 53 28 73 69 7a 65 3d 3d 30 29 20 29 7b 0a 20 20  S(size==0) ){.  
1fe0: 20 20 6d 65 6d 6a 72 6e 6c 46 72 65 65 43 68 75    memjrnlFreeChu
1ff0: 6e 6b 73 28 70 29 3b 0a 20 20 20 20 70 2d 3e 6e  nks(p);.    p->n
2000: 53 69 7a 65 20 3d 20 30 3b 0a 20 20 20 20 70 2d  Size = 0;.    p-
2010: 3e 65 6e 64 70 6f 69 6e 74 2e 70 43 68 75 6e 6b  >endpoint.pChunk
2020: 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 65 6e 64   = 0;.    p->end
2030: 70 6f 69 6e 74 2e 69 4f 66 66 73 65 74 20 3d 20  point.iOffset = 
2040: 30 3b 0a 20 20 20 20 70 2d 3e 72 65 61 64 70 6f  0;.    p->readpo
2050: 69 6e 74 2e 70 43 68 75 6e 6b 20 3d 20 30 3b 0a  int.pChunk = 0;.
2060: 20 20 20 20 70 2d 3e 72 65 61 64 70 6f 69 6e 74      p->readpoint
2070: 2e 69 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20  .iOffset = 0;.  
2080: 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
2090: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
20a0: 6c 6f 73 65 20 74 68 65 20 66 69 6c 65 2e 0a 2a  lose the file..*
20b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d  /.static int mem
20c0: 6a 72 6e 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65  jrnlClose(sqlite
20d0: 33 5f 66 69 6c 65 20 2a 70 4a 66 64 29 7b 0a 20  3_file *pJfd){. 
20e0: 20 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 70 20 3d   MemJournal *p =
20f0: 20 28 4d 65 6d 4a 6f 75 72 6e 61 6c 20 2a 29 70   (MemJournal *)p
2100: 4a 66 64 3b 0a 20 20 6d 65 6d 6a 72 6e 6c 46 72  Jfd;.  memjrnlFr
2110: 65 65 43 68 75 6e 6b 73 28 70 29 3b 0a 20 20 72  eeChunks(p);.  r
2120: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2130: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74  .}../*.** Sync t
2140: 68 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49  he file..**.** I
2150: 66 20 74 68 65 20 72 65 61 6c 20 66 69 6c 65 20  f the real file 
2160: 68 61 73 20 62 65 65 6e 20 63 72 65 61 74 65 64  has been created
2170: 2c 20 63 61 6c 6c 20 69 74 73 20 78 53 79 6e 63  , call its xSync
2180: 20 6d 65 74 68 6f 64 2e 20 4f 74 68 65 72 77 69   method. Otherwi
2190: 73 65 2c 20 0a 2a 2a 20 73 79 6e 63 69 6e 67 20  se, .** syncing 
21a0: 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 6a 6f 75  an in-memory jou
21b0: 72 6e 61 6c 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  rnal is a no-op.
21c0: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
21d0: 6d 65 6d 6a 72 6e 6c 53 79 6e 63 28 73 71 6c 69  memjrnlSync(sqli
21e0: 74 65 33 5f 66 69 6c 65 20 2a 70 4a 66 64 2c 20  te3_file *pJfd, 
21f0: 69 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20 55 4e  int flags){.  UN
2200: 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 32 28  USED_PARAMETER2(
2210: 70 4a 66 64 2c 20 66 6c 61 67 73 29 3b 0a 20 20  pJfd, flags);.  
2220: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2230: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 51 75 65 72 79  ;.}../*.** Query
2240: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
2250: 20 66 69 6c 65 20 69 6e 20 62 79 74 65 73 2e 0a   file in bytes..
2260: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  */.static int me
2270: 6d 6a 72 6e 6c 46 69 6c 65 53 69 7a 65 28 73 71  mjrnlFileSize(sq
2280: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 4a 66 64  lite3_file *pJfd
2290: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a  , sqlite_int64 *
22a0: 70 53 69 7a 65 29 7b 0a 20 20 4d 65 6d 4a 6f 75  pSize){.  MemJou
22b0: 72 6e 61 6c 20 2a 70 20 3d 20 28 4d 65 6d 4a 6f  rnal *p = (MemJo
22c0: 75 72 6e 61 6c 20 2a 29 70 4a 66 64 3b 0a 20 20  urnal *)pJfd;.  
22d0: 2a 70 53 69 7a 65 20 3d 20 28 73 71 6c 69 74 65  *pSize = (sqlite
22e0: 5f 69 6e 74 36 34 29 20 70 2d 3e 65 6e 64 70 6f  _int64) p->endpo
22f0: 69 6e 74 2e 69 4f 66 66 73 65 74 3b 0a 20 20 72  int.iOffset;.  r
2300: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2310: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 61 62 6c 65 20  .}../*.** Table 
2320: 6f 66 20 6d 65 74 68 6f 64 73 20 66 6f 72 20 4d  of methods for M
2330: 65 6d 4a 6f 75 72 6e 61 6c 20 73 71 6c 69 74 65  emJournal sqlite
2340: 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a  3_file object..*
2350: 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73  /.static const s
2360: 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6f  truct sqlite3_io
2370: 5f 6d 65 74 68 6f 64 73 20 4d 65 6d 4a 6f 75 72  _methods MemJour
2380: 6e 61 6c 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20  nalMethods = {. 
2390: 20 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   1,             
23a0: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
23b0: 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 43 6c 6f 73 65  /.  memjrnlClose
23c0: 2c 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20  ,     /* xClose 
23d0: 2a 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 52 65 61 64  */.  memjrnlRead
23e0: 2c 20 20 20 20 20 20 2f 2a 20 78 52 65 61 64 20  ,      /* xRead 
23f0: 2a 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 57 72 69 74  */.  memjrnlWrit
2400: 65 2c 20 20 20 20 20 2f 2a 20 78 57 72 69 74 65  e,     /* xWrite
2410: 20 2a 2f 0a 20 20 6d 65 6d 6a 72 6e 6c 54 72 75   */.  memjrnlTru
2420: 6e 63 61 74 65 2c 20 20 2f 2a 20 78 54 72 75 6e  ncate,  /* xTrun
2430: 63 61 74 65 20 2a 2f 0a 20 20 6d 65 6d 6a 72 6e  cate */.  memjrn
2440: 6c 53 79 6e 63 2c 20 20 20 20 20 20 2f 2a 20 78  lSync,      /* x
2450: 53 79 6e 63 20 2a 2f 0a 20 20 6d 65 6d 6a 72 6e  Sync */.  memjrn
2460: 6c 46 69 6c 65 53 69 7a 65 2c 20 20 2f 2a 20 78  lFileSize,  /* x
2470: 46 69 6c 65 53 69 7a 65 20 2a 2f 0a 20 20 30 2c  FileSize */.  0,
2480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2490: 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20 30 2c  /* xLock */.  0,
24a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b0: 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20  /* xUnlock */.  
24c0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
24d0: 20 20 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72    /* xCheckReser
24e0: 76 65 64 4c 6f 63 6b 20 2a 2f 0a 20 20 30 2c 20  vedLock */.  0, 
24f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2500: 2a 20 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a  * xFileControl *
2510: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
2520: 20 20 20 20 20 20 2f 2a 20 78 53 65 63 74 6f 72        /* xSector
2530: 53 69 7a 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20  Size */.  0,    
2540: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2550: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
2560: 73 74 69 63 73 20 2a 2f 0a 20 20 30 2c 20 20 20  stics */.  0,   
2570: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2580: 78 53 68 6d 4d 61 70 20 2a 2f 0a 20 20 30 2c 20  xShmMap */.  0, 
2590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
25a0: 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a 2f 0a 20 20  * xShmLock */.  
25b0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
25c0: 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69 65 72    /* xShmBarrier
25d0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
25e0: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55          /* xShmU
25f0: 6e 6d 61 70 20 2a 2f 0a 20 20 30 2c 20 20 20 20  nmap */.  0,    
2600: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2610: 46 65 74 63 68 20 2a 2f 0a 20 20 30 20 20 20 20  Fetch */.  0    
2620: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2630: 78 55 6e 66 65 74 63 68 20 2a 2f 0a 7d 3b 0a 0a  xUnfetch */.};..
2640: 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 6a 6f  /* .** Open a jo
2650: 75 72 6e 61 6c 20 66 69 6c 65 2e 20 0a 2a 2a 0a  urnal file. .**.
2660: 2a 2a 20 54 68 65 20 62 65 68 61 76 69 6f 75 72  ** The behaviour
2670: 20 6f 66 20 74 68 65 20 6a 6f 75 72 6e 61 6c 20   of the journal 
2680: 66 69 6c 65 20 64 65 70 65 6e 64 73 20 6f 6e 20  file depends on 
2690: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 70 61 72  the value of par
26a0: 61 6d 65 74 65 72 20 0a 2a 2a 20 6e 53 70 69 6c  ameter .** nSpil
26b0: 6c 2e 20 49 66 20 6e 53 70 69 6c 6c 20 69 73 20  l. If nSpill is 
26c0: 30 2c 20 74 68 65 6e 20 74 68 65 20 6a 6f 75 72  0, then the jour
26d0: 6e 61 6c 20 66 69 6c 65 20 69 73 20 61 6c 77 61  nal file is alwa
26e0: 79 73 20 63 72 65 61 74 65 20 61 6e 64 20 0a 2a  ys create and .*
26f0: 2a 20 61 63 63 65 73 73 65 64 20 75 73 69 6e 67  * accessed using
2700: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
2710: 56 46 53 2e 20 49 66 20 6e 53 70 69 6c 6c 20 69  VFS. If nSpill i
2720: 73 20 6c 65 73 73 20 74 68 61 6e 20 7a 65 72 6f  s less than zero
2730: 2c 20 74 68 65 6e 0a 2a 2a 20 61 6c 6c 20 63 6f  , then.** all co
2740: 6e 74 65 6e 74 20 69 73 20 61 6c 77 61 79 73 20  ntent is always 
2750: 73 74 6f 72 65 64 20 69 6e 20 6d 61 69 6e 2d 6d  stored in main-m
2760: 65 6d 6f 72 79 2e 20 46 69 6e 61 6c 6c 79 2c 20  emory. Finally, 
2770: 69 66 20 6e 53 70 69 6c 6c 20 69 73 20 61 0a 2a  if nSpill is a.*
2780: 2a 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65  * positive value
2790: 2c 20 74 68 65 6e 20 74 68 65 20 6a 6f 75 72 6e  , then the journ
27a0: 61 6c 20 66 69 6c 65 20 69 73 20 69 6e 69 74 69  al file is initi
27b0: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 69 6e 2d  ally created in-
27c0: 6d 65 6d 6f 72 79 0a 2a 2a 20 62 75 74 20 6d 61  memory.** but ma
27d0: 79 20 62 65 20 66 6c 75 73 68 65 64 20 74 6f 20  y be flushed to 
27e0: 64 69 73 6b 20 6c 61 74 65 72 20 6f 6e 2e 20 49  disk later on. I
27f0: 6e 20 74 68 69 73 20 63 61 73 65 20 74 68 65 20  n this case the 
2800: 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 69 73 0a  journal file is.
2810: 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69  ** flushed to di
2820: 73 6b 20 65 69 74 68 65 72 20 77 68 65 6e 20 69  sk either when i
2830: 74 20 67 72 6f 77 73 20 6c 61 72 67 65 72 20 74  t grows larger t
2840: 68 61 6e 20 6e 53 70 69 6c 6c 20 62 79 74 65 73  han nSpill bytes
2850: 20 69 6e 20 73 69 7a 65 2c 0a 2a 2a 20 6f 72 20   in size,.** or 
2860: 77 68 65 6e 20 73 71 6c 69 74 65 33 4a 6f 75 72  when sqlite3Jour
2870: 6e 61 6c 43 72 65 61 74 65 28 29 20 69 73 20 63  nalCreate() is c
2880: 61 6c 6c 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  alled..*/.int sq
2890: 6c 69 74 65 33 4a 6f 75 72 6e 61 6c 4f 70 65 6e  lite3JournalOpen
28a0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  (.  sqlite3_vfs 
28b0: 2a 70 56 66 73 2c 20 20 20 20 20 20 20 20 20 2f  *pVfs,         /
28c0: 2a 20 54 68 65 20 56 46 53 20 74 6f 20 75 73 65  * The VFS to use
28d0: 20 66 6f 72 20 61 63 74 75 61 6c 20 66 69 6c 65   for actual file
28e0: 20 49 2f 4f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20   I/O */.  const 
28f0: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20  char *zName,    
2900: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
2910: 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65  the journal file
2920: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
2930: 6c 65 20 2a 70 4a 66 64 2c 20 20 20 20 20 20 20  le *pJfd,       
2940: 20 2f 2a 20 50 72 65 61 6c 6c 6f 63 61 74 65 64   /* Preallocated
2950: 2c 20 62 6c 61 6e 6b 20 66 69 6c 65 20 68 61 6e  , blank file han
2960: 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61  dle */.  int fla
2970: 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  gs,             
2980: 20 20 20 20 2f 2a 20 4f 70 65 6e 69 6e 67 20 66      /* Opening f
2990: 6c 61 67 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 53  lags */.  int nS
29a0: 70 69 6c 6c 20 20 20 20 20 20 20 20 20 20 20 20  pill            
29b0: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 62 75       /* Bytes bu
29c0: 66 66 65 72 65 64 20 62 65 66 6f 72 65 20 6f 70  ffered before op
29d0: 65 6e 69 6e 67 20 74 68 65 20 66 69 6c 65 20 2a  ening the file *
29e0: 2f 0a 29 7b 0a 20 20 4d 65 6d 4a 6f 75 72 6e 61  /.){.  MemJourna
29f0: 6c 20 2a 70 20 3d 20 28 4d 65 6d 4a 6f 75 72 6e  l *p = (MemJourn
2a00: 61 6c 2a 29 70 4a 66 64 3b 0a 0a 20 20 2f 2a 20  al*)pJfd;..  /* 
2a10: 5a 65 72 6f 20 74 68 65 20 66 69 6c 65 2d 68 61  Zero the file-ha
2a20: 6e 64 6c 65 20 6f 62 6a 65 63 74 2e 20 49 66 20  ndle object. If 
2a30: 6e 53 70 69 6c 6c 20 77 61 73 20 70 61 73 73 65  nSpill was passe
2a40: 64 20 7a 65 72 6f 2c 20 69 6e 69 74 69 61 6c 69  d zero, initiali
2a50: 7a 65 0a 20 20 2a 2a 20 69 74 20 75 73 69 6e 67  ze.  ** it using
2a60: 20 74 68 65 20 73 71 6c 69 74 65 33 4f 73 4f 70   the sqlite3OsOp
2a70: 65 6e 28 29 20 66 75 6e 63 74 69 6f 6e 20 6f 66  en() function of
2a80: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
2a90: 56 46 53 2e 20 49 6e 20 74 68 69 73 0a 20 20 2a  VFS. In this.  *
2aa0: 2a 20 63 61 73 65 20 6e 6f 6e 65 20 6f 66 20 74  * case none of t
2ab0: 68 65 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  he code in this 
2ac0: 6d 6f 64 75 6c 65 20 69 73 20 65 78 65 63 75 74  module is execut
2ad0: 65 64 20 61 73 20 61 20 72 65 73 75 6c 74 20 6f  ed as a result o
2ae0: 66 20 63 61 6c 6c 73 0a 20 20 2a 2a 20 6d 61 64  f calls.  ** mad
2af0: 65 20 6f 6e 20 74 68 65 20 6a 6f 75 72 6e 61 6c  e on the journal
2b00: 20 66 69 6c 65 2d 68 61 6e 64 6c 65 2e 20 20 2a   file-handle.  *
2b10: 2f 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c  /.  memset(p, 0,
2b20: 20 73 69 7a 65 6f 66 28 4d 65 6d 4a 6f 75 72 6e   sizeof(MemJourn
2b30: 61 6c 29 29 3b 0a 20 20 69 66 28 20 6e 53 70 69  al));.  if( nSpi
2b40: 6c 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  ll==0 ){.    ret
2b50: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  urn sqlite3OsOpe
2b60: 6e 28 70 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 70  n(pVfs, zName, p
2b70: 4a 66 64 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a  Jfd, flags, 0);.
2b80: 20 20 7d 0a 0a 20 20 69 66 28 20 6e 53 70 69 6c    }..  if( nSpil
2b90: 6c 3e 30 20 29 7b 0a 20 20 20 20 70 2d 3e 6e 43  l>0 ){.    p->nC
2ba0: 68 75 6e 6b 53 69 7a 65 20 3d 20 6e 53 70 69 6c  hunkSize = nSpil
2bb0: 6c 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  l;.  }else{.    
2bc0: 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 20 3d 20  p->nChunkSize = 
2bd0: 38 20 2b 20 4d 45 4d 4a 4f 55 52 4e 41 4c 5f 44  8 + MEMJOURNAL_D
2be0: 46 4c 54 5f 46 49 4c 45 43 48 55 4e 4b 53 49 5a  FLT_FILECHUNKSIZ
2bf0: 45 20 2d 20 73 69 7a 65 6f 66 28 46 69 6c 65 43  E - sizeof(FileC
2c00: 68 75 6e 6b 29 3b 0a 20 20 20 20 61 73 73 65 72  hunk);.    asser
2c10: 74 28 20 4d 45 4d 4a 4f 55 52 4e 41 4c 5f 44 46  t( MEMJOURNAL_DF
2c20: 4c 54 5f 46 49 4c 45 43 48 55 4e 4b 53 49 5a 45  LT_FILECHUNKSIZE
2c30: 3d 3d 66 69 6c 65 43 68 75 6e 6b 53 69 7a 65 28  ==fileChunkSize(
2c40: 70 2d 3e 6e 43 68 75 6e 6b 53 69 7a 65 29 20 29  p->nChunkSize) )
2c50: 3b 0a 20 20 7d 0a 0a 20 20 70 2d 3e 70 4d 65 74  ;.  }..  p->pMet
2c60: 68 6f 64 20 3d 20 28 63 6f 6e 73 74 20 73 71 6c  hod = (const sql
2c70: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 2a  ite3_io_methods*
2c80: 29 26 4d 65 6d 4a 6f 75 72 6e 61 6c 4d 65 74 68  )&MemJournalMeth
2c90: 6f 64 73 3b 0a 20 20 70 2d 3e 6e 53 70 69 6c 6c  ods;.  p->nSpill
2ca0: 20 3d 20 6e 53 70 69 6c 6c 3b 0a 20 20 70 2d 3e   = nSpill;.  p->
2cb0: 66 6c 61 67 73 20 3d 20 66 6c 61 67 73 3b 0a 20  flags = flags;. 
2cc0: 20 70 2d 3e 7a 4a 6f 75 72 6e 61 6c 20 3d 20 7a   p->zJournal = z
2cd0: 4e 61 6d 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20  Name;.  p->pVfs 
2ce0: 3d 20 70 56 66 73 3b 0a 20 20 72 65 74 75 72 6e  = pVfs;.  return
2cf0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
2d00: 2a 0a 2a 2a 20 4f 70 65 6e 20 61 6e 20 69 6e 2d  *.** Open an in-
2d10: 6d 65 6d 6f 72 79 20 6a 6f 75 72 6e 61 6c 20 66  memory journal f
2d20: 69 6c 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ile..*/.void sql
2d30: 69 74 65 33 4d 65 6d 4a 6f 75 72 6e 61 6c 4f 70  ite3MemJournalOp
2d40: 65 6e 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  en(sqlite3_file 
2d50: 2a 70 4a 66 64 29 7b 0a 20 20 73 71 6c 69 74 65  *pJfd){.  sqlite
2d60: 33 4a 6f 75 72 6e 61 6c 4f 70 65 6e 28 30 2c 20  3JournalOpen(0, 
2d70: 30 2c 20 70 4a 66 64 2c 20 30 2c 20 2d 31 29 3b  0, pJfd, 0, -1);
2d80: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
2d90: 45 5f 45 4e 41 42 4c 45 5f 41 54 4f 4d 49 43 5f  E_ENABLE_ATOMIC_
2da0: 57 52 49 54 45 0a 2f 2a 0a 2a 2a 20 49 66 20 74  WRITE./*.** If t
2db0: 68 65 20 61 72 67 75 6d 65 6e 74 20 70 20 70 6f  he argument p po
2dc0: 69 6e 74 73 20 74 6f 20 61 20 4d 65 6d 4a 6f 75  ints to a MemJou
2dd0: 72 6e 61 6c 20 73 74 72 75 63 74 75 72 65 20 74  rnal structure t
2de0: 68 61 74 20 69 73 20 6e 6f 74 20 61 6e 20 0a 2a  hat is not an .*
2df0: 2a 20 69 6e 2d 6d 65 6d 6f 72 79 2d 6f 6e 6c 79  * in-memory-only
2e00: 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 28 69   journal file (i
2e10: 2e 65 2e 20 69 73 20 6f 6e 65 20 74 68 61 74 20  .e. is one that 
2e20: 77 61 73 20 6f 70 65 6e 65 64 20 77 69 74 68 20  was opened with 
2e30: 61 20 2b 76 65 0a 2a 2a 20 6e 53 70 69 6c 6c 20  a +ve.** nSpill 
2e40: 70 61 72 61 6d 65 74 65 72 29 2c 20 61 6e 64 20  parameter), and 
2e50: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66  the underlying f
2e60: 69 6c 65 20 68 61 73 20 6e 6f 74 20 79 65 74 20  ile has not yet 
2e70: 62 65 65 6e 20 63 72 65 61 74 65 64 2c 20 0a 2a  been created, .*
2e80: 2a 20 63 72 65 61 74 65 20 69 74 20 6e 6f 77 2e  * create it now.
2e90: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a  .*/.int sqlite3J
2ea0: 6f 75 72 6e 61 6c 43 72 65 61 74 65 28 73 71 6c  ournalCreate(sql
2eb0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 29 7b 0a 20  ite3_file *p){. 
2ec0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2ed0: 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 2d 3e 70 4d  _OK;.  if( p->pM
2ee0: 65 74 68 6f 64 73 3d 3d 26 4d 65 6d 4a 6f 75 72  ethods==&MemJour
2ef0: 6e 61 6c 4d 65 74 68 6f 64 73 20 26 26 20 28 28  nalMethods && ((
2f00: 4d 65 6d 4a 6f 75 72 6e 61 6c 2a 29 70 29 2d 3e  MemJournal*)p)->
2f10: 6e 53 70 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20  nSpill>0 ){.    
2f20: 72 63 20 3d 20 6d 65 6d 6a 72 6e 6c 43 72 65 61  rc = memjrnlCrea
2f30: 74 65 46 69 6c 65 28 28 4d 65 6d 4a 6f 75 72 6e  teFile((MemJourn
2f40: 61 6c 2a 29 70 29 3b 0a 20 20 7d 0a 20 20 72 65  al*)p);.  }.  re
2f50: 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6e 64 69  turn rc;.}.#endi
2f60: 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 6c  f../*.** The fil
2f70: 65 2d 68 61 6e 64 6c 65 20 70 61 73 73 65 64 20  e-handle passed 
2f80: 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75  as the only argu
2f90: 6d 65 6e 74 20 69 73 20 6f 70 65 6e 20 6f 6e 20  ment is open on 
2fa0: 61 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 2e 0a  a journal file..
2fb0: 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  ** Return true i
2fc0: 66 20 74 68 69 73 20 22 6a 6f 75 72 6e 61 6c 20  f this "journal 
2fd0: 66 69 6c 65 22 20 69 73 20 63 75 72 72 65 6e 74  file" is current
2fe0: 6c 79 20 73 74 6f 72 65 64 20 69 6e 20 68 65 61  ly stored in hea
2ff0: 70 20 6d 65 6d 6f 72 79 2c 0a 2a 2a 20 6f 72 20  p memory,.** or 
3000: 66 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65 2e  false otherwise.
3010: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a  .*/.int sqlite3J
3020: 6f 75 72 6e 61 6c 49 73 49 6e 4d 65 6d 6f 72 79  ournalIsInMemory
3030: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
3040: 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 70  ){.  return p->p
3050: 4d 65 74 68 6f 64 73 3d 3d 26 4d 65 6d 4a 6f 75  Methods==&MemJou
3060: 72 6e 61 6c 4d 65 74 68 6f 64 73 3b 0a 7d 0a 0a  rnalMethods;.}..
3070: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
3080: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
3090: 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 73 74  s required to st
30a0: 6f 72 65 20 61 20 4a 6f 75 72 6e 61 6c 46 69 6c  ore a JournalFil
30b0: 65 20 74 68 61 74 20 75 73 65 73 20 76 66 73 0a  e that uses vfs.
30c0: 2a 2a 20 70 56 66 73 20 74 6f 20 63 72 65 61 74  ** pVfs to creat
30d0: 65 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  e the underlying
30e0: 20 6f 6e 2d 64 69 73 6b 20 66 69 6c 65 73 2e 0a   on-disk files..
30f0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4a 6f  */.int sqlite3Jo
3100: 75 72 6e 61 6c 53 69 7a 65 28 73 71 6c 69 74 65  urnalSize(sqlite
3110: 33 5f 76 66 73 20 2a 70 56 66 73 29 7b 0a 20 20  3_vfs *pVfs){.  
3120: 72 65 74 75 72 6e 20 4d 41 58 28 70 56 66 73 2d  return MAX(pVfs-
3130: 3e 73 7a 4f 73 46 69 6c 65 2c 20 73 69 7a 65 6f  >szOsFile, sizeo
3140: 66 28 4d 65 6d 4a 6f 75 72 6e 61 6c 29 29 3b 0a  f(MemJournal));.
3150: 7d 0a                                            }.