/ Hex Artifact Content
Login

Artifact cf11b27b129c6bd5818fa1d440176502dc27229f0db892b4479118d61993ea20:


0000: 0a 2f 2a 0a 2a 2a 20 53 55 4d 4d 41 52 59 0a 2a  ./*.** SUMMARY.*
0010: 2a 0a 2a 2a 20 20 20 54 68 69 73 20 66 69 6c 65  *.**   This file
0020: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20   implements the 
0030: 27 69 6f 27 20 73 75 62 63 6f 6d 6d 61 6e 64 20  'io' subcommand 
0040: 6f 66 20 74 68 65 20 74 65 73 74 20 70 72 6f 67  of the test prog
0050: 72 61 6d 2e 20 49 74 20 69 73 20 75 73 65 64 0a  ram. It is used.
0060: 2a 2a 20 20 20 66 6f 72 20 74 65 73 74 69 6e 67  **   for testing
0070: 20 74 68 65 20 70 65 72 66 6f 72 6d 61 6e 63 65   the performance
0080: 20 6f 66 20 76 61 72 69 6f 75 73 20 63 6f 6d 62   of various comb
0090: 69 6e 61 74 69 6f 6e 73 20 6f 66 20 77 72 69 74  inations of writ
00a0: 65 28 29 20 61 6e 64 20 66 73 79 6e 63 28 29 0a  e() and fsync().
00b0: 2a 2a 20 20 20 73 79 73 74 65 6d 20 63 61 6c 6c  **   system call
00c0: 73 2e 20 41 6c 6c 20 6f 70 65 72 61 74 69 6f 6e  s. All operation
00d0: 73 20 6f 63 63 75 72 20 6f 6e 20 61 20 73 69 6e  s occur on a sin
00e0: 67 6c 65 20 66 69 6c 65 2c 20 77 68 69 63 68 20  gle file, which 
00f0: 6d 61 79 20 6f 72 20 6d 61 79 20 6e 6f 74 0a 2a  may or may not.*
0100: 2a 20 20 20 65 78 69 73 74 20 77 68 65 6e 20 61  *   exist when a
0110: 20 74 65 73 74 20 69 73 20 73 74 61 72 74 65 64   test is started
0120: 2e 0a 2a 2a 0a 2a 2a 20 20 20 41 20 74 65 73 74  ..**.**   A test
0130: 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 73   consists of a s
0140: 65 72 69 65 73 20 6f 66 20 63 6f 6d 6d 61 6e 64  eries of command
0150: 73 2e 20 45 61 63 68 20 63 6f 6d 6d 61 6e 64 20  s. Each command 
0160: 69 73 20 65 69 74 68 65 72 20 61 20 77 72 69 74  is either a writ
0170: 65 0a 2a 2a 20 20 20 6f 72 20 61 6e 20 66 73 79  e.**   or an fsy
0180: 6e 63 2e 20 41 20 77 72 69 74 65 20 69 73 20 73  nc. A write is s
0190: 70 65 63 69 66 69 65 64 20 61 73 20 22 3c 61 6d  pecified as "<am
01a0: 6f 75 6e 74 3e 40 3c 6f 66 66 73 65 74 3e 22 2c  ount>@<offset>",
01b0: 20 77 68 65 72 65 20 3c 61 6d 6f 75 6e 74 3e 0a   where <amount>.
01c0: 2a 2a 20 20 20 69 73 20 74 68 65 20 61 6d 6f 75  **   is the amou
01d0: 6e 74 20 6f 66 20 64 61 74 61 20 77 72 69 74 74  nt of data writt
01e0: 65 6e 2c 20 61 6e 64 20 3c 6f 66 66 73 65 74 3e  en, and <offset>
01f0: 20 69 73 20 74 68 65 20 6f 66 66 73 65 74 20 6f   is the offset o
0200: 66 20 74 68 65 20 66 69 6c 65 0a 2a 2a 20 20 20  f the file.**   
0210: 74 6f 20 77 72 69 74 65 20 74 6f 2e 20 41 6e 20  to write to. An 
0220: 3c 61 6d 6f 75 6e 74 3e 20 6f 72 20 61 6e 20 3c  <amount> or an <
0230: 6f 66 66 73 65 74 3e 20 69 73 20 73 70 65 63 69  offset> is speci
0240: 66 69 65 64 20 61 73 20 61 6e 20 69 6e 74 65 67  fied as an integ
0250: 65 72 20 6e 75 6d 62 65 72 0a 2a 2a 20 20 20 6f  er number.**   o
0260: 66 20 62 79 74 65 73 2e 20 4f 72 2c 20 69 66 20  f bytes. Or, if 
0270: 70 6f 73 74 66 69 78 65 64 20 77 69 74 68 20 61  postfixed with a
0280: 20 22 4b 22 2c 20 22 4d 22 20 6f 72 20 22 47 22   "K", "M" or "G"
0290: 2c 20 61 6e 20 69 6e 74 65 67 65 72 20 6e 75 6d  , an integer num
02a0: 62 65 72 20 6f 66 0a 2a 2a 20 20 20 4b 42 2c 20  ber of.**   KB, 
02b0: 4d 42 20 6f 72 20 47 42 2c 20 72 65 73 70 65 63  MB or GB, respec
02c0: 74 69 76 65 6c 79 2e 20 41 6e 20 66 73 79 6e 63  tively. An fsync
02d0: 20 69 73 20 73 69 6d 70 6c 79 20 22 53 22 2e 20   is simply "S". 
02e0: 41 6c 6c 20 63 6f 6d 6d 61 6e 64 73 20 61 72 65  All commands are
02f0: 0a 2a 2a 20 20 20 63 61 73 65 2d 69 6e 73 65 6e  .**   case-insen
0300: 73 69 74 69 76 65 2e 0a 2a 2a 0a 2a 2a 20 20 20  sitive..**.**   
0310: 45 78 61 6d 70 6c 65 20 74 65 73 74 20 70 72 6f  Example test pro
0320: 67 72 61 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  gram:.**.**     
0330: 20 20 20 32 4d 40 36 4d 20 31 34 39 32 4b 40 34     2M@6M 1492K@4
0340: 4d 20 53 20 34 30 39 36 40 34 4b 20 53 0a 2a 2a  M S 4096@4K S.**
0350: 0a 2a 2a 20 20 20 54 68 69 73 20 70 72 6f 67 72  .**   This progr
0360: 61 6d 20 77 72 69 74 65 73 20 32 20 4d 42 20 6f  am writes 2 MB o
0370: 66 20 64 61 74 61 20 73 74 61 72 74 69 6e 67 20  f data starting 
0380: 61 74 20 74 68 65 20 6f 66 66 73 65 74 20 36 4d  at the offset 6M
0390: 42 20 6f 66 66 73 65 74 20 6f 66 0a 2a 2a 20 20  B offset of.**  
03a0: 20 74 68 65 20 66 69 6c 65 2c 20 66 6f 6c 6c 6f   the file, follo
03b0: 77 65 64 20 62 79 20 31 34 39 32 20 4b 42 20 6f  wed by 1492 KB o
03c0: 66 20 64 61 74 61 20 77 72 69 74 74 65 6e 20 61  f data written a
03d0: 74 20 74 68 65 20 34 4d 42 20 6f 66 66 73 65 74  t the 4MB offset
03e0: 20 6f 66 20 74 68 65 0a 2a 2a 20 20 20 66 69 6c   of the.**   fil
03f0: 65 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61  e, followed by a
0400: 20 63 61 6c 6c 20 74 6f 20 66 73 79 6e 63 28 29   call to fsync()
0410: 2c 20 61 20 77 72 69 74 65 20 6f 66 20 34 4b 42  , a write of 4KB
0420: 20 6f 66 20 64 61 74 61 20 61 74 20 62 79 74 65   of data at byte
0430: 0a 2a 2a 20 20 20 6f 66 66 73 65 74 20 34 30 39  .**   offset 409
0440: 36 2c 20 61 6e 64 20 66 69 6e 61 6c 6c 79 20 61  6, and finally a
0450: 6e 6f 74 68 65 72 20 63 61 6c 6c 20 74 6f 20 66  nother call to f
0460: 73 79 6e 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  sync()..**.**   
0470: 43 6f 6d 6d 61 6e 64 73 20 6d 61 79 20 65 69 74  Commands may eit
0480: 68 65 72 20 62 65 20 73 70 65 63 69 66 69 65 64  her be specified
0490: 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 20   on the command 
04a0: 6c 69 6e 65 20 28 6f 6e 65 20 63 6f 6d 6d 61 6e  line (one comman
04b0: 64 20 70 65 72 0a 2a 2a 20 20 20 63 6f 6d 6d 61  d per.**   comma
04c0: 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74  nd line argument
04d0: 29 20 6f 72 20 72 65 61 64 20 66 72 6f 6d 20 73  ) or read from s
04e0: 74 64 69 6e 2e 20 43 6f 6d 6d 61 6e 64 73 20 72  tdin. Commands r
04f0: 65 61 64 20 66 72 6f 6d 20 73 74 64 69 6e 0a 2a  ead from stdin.*
0500: 2a 20 20 20 6d 75 73 74 20 62 65 20 73 65 70 61  *   must be sepa
0510: 72 61 74 65 64 20 62 79 20 77 68 69 74 65 2d 73  rated by white-s
0520: 70 61 63 65 2e 0a 2a 2a 0a 2a 2a 20 43 4f 4d 4d  pace..**.** COMM
0530: 41 4e 44 20 4c 49 4e 45 20 49 4e 56 4f 43 41 54  AND LINE INVOCAT
0540: 49 4f 4e 0a 2a 2a 0a 2a 2a 20 20 20 54 68 65 20  ION.**.**   The 
0550: 73 75 62 2d 63 6f 6d 6d 61 6e 64 20 69 6d 70 6c  sub-command impl
0560: 65 6d 65 6e 74 65 64 20 69 6e 20 74 68 69 73 20  emented in this 
0570: 66 69 6c 65 20 6d 75 73 74 20 62 65 20 69 6e 76  file must be inv
0580: 6f 6b 65 64 20 77 69 74 68 20 61 74 20 6c 65 61  oked with at lea
0590: 73 74 0a 2a 2a 20 20 20 74 77 6f 20 61 72 67 75  st.**   two argu
05a0: 6d 65 6e 74 73 20 2d 20 74 68 65 20 70 61 74 68  ments - the path
05b0: 20 74 6f 20 74 68 65 20 66 69 6c 65 20 74 6f 20   to the file to 
05c0: 77 72 69 74 65 20 74 6f 20 61 6e 64 20 74 68 65  write to and the
05d0: 20 70 61 67 65 2d 73 69 7a 65 20 74 6f 0a 2a 2a   page-size to.**
05e0: 20 20 20 75 73 65 20 66 6f 72 20 77 72 69 74 69     use for writi
05f0: 6e 67 2e 20 49 66 20 74 68 65 72 65 20 61 72 65  ng. If there are
0600: 20 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f 20 61   more than two a
0610: 72 67 75 6d 65 6e 74 73 2c 20 74 68 65 6e 20 65  rguments, then e
0620: 61 63 68 0a 2a 2a 20 20 20 73 75 62 73 65 71 75  ach.**   subsequ
0630: 65 6e 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20  ent argument is 
0640: 61 73 73 75 6d 65 64 20 74 6f 20 62 65 20 61 20  assumed to be a 
0650: 74 65 73 74 20 63 6f 6d 6d 61 6e 64 2e 20 49 66  test command. If
0660: 20 74 68 65 72 65 20 61 72 65 20 65 78 61 63 74   there are exact
0670: 6c 79 0a 2a 2a 20 20 20 74 77 6f 20 61 72 67 75  ly.**   two argu
0680: 6d 65 6e 74 73 2c 20 74 68 65 20 74 65 73 74 20  ments, the test 
0690: 63 6f 6d 6d 61 6e 64 73 20 61 72 65 20 72 65 61  commands are rea
06a0: 64 20 66 72 6f 6d 20 73 74 64 69 6e 2e 0a 2a 2a  d from stdin..**
06b0: 0a 2a 2a 20 20 20 41 20 77 72 69 74 65 20 63 6f  .**   A write co
06c0: 6d 6d 61 6e 64 20 64 6f 65 73 20 6e 6f 74 20 72  mmand does not r
06d0: 65 73 75 6c 74 20 69 6e 20 61 20 73 69 6e 67 6c  esult in a singl
06e0: 65 20 63 61 6c 6c 20 74 6f 20 73 79 73 74 65 6d  e call to system
06f0: 20 63 61 6c 6c 20 77 72 69 74 65 28 29 2e 0a 2a   call write()..*
0700: 2a 20 20 20 49 6e 73 74 65 61 64 2c 20 74 68 65  *   Instead, the
0710: 20 73 70 65 63 69 66 69 65 64 20 72 65 67 69 6f   specified regio
0720: 6e 20 69 73 20 77 72 69 74 74 65 6e 20 73 65 71  n is written seq
0730: 75 65 6e 74 69 61 6c 6c 79 20 75 73 69 6e 67 20  uentially using 
0740: 6f 6e 65 20 6f 72 0a 2a 2a 20 20 20 6d 6f 72 65  one or.**   more
0750: 20 63 61 6c 6c 73 20 74 6f 20 77 72 69 74 65 28   calls to write(
0760: 29 2c 20 65 61 63 68 20 6f 66 20 77 68 69 63 68  ), each of which
0770: 20 77 72 69 74 65 73 20 6e 6f 74 20 6d 6f 72 65   writes not more
0780: 20 74 68 61 6e 20 6f 6e 65 20 70 61 67 65 20 6f   than one page o
0790: 66 0a 2a 2a 20 20 20 64 61 74 61 2e 20 46 6f 72  f.**   data. For
07a0: 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65   example, if the
07b0: 20 70 61 67 65 2d 73 69 7a 65 20 69 73 20 34 4b   page-size is 4K
07c0: 42 2c 20 74 68 65 20 63 6f 6d 6d 61 6e 64 20 22  B, the command "
07d0: 32 4d 40 36 4d 22 20 72 65 73 75 6c 74 73 0a 2a  2M@6M" results.*
07e0: 2a 20 20 20 69 6e 20 35 31 32 20 63 61 6c 6c 73  *   in 512 calls
07f0: 20 74 6f 20 77 72 69 74 65 28 29 2c 20 65 61 63   to write(), eac
0800: 68 20 6f 66 20 77 68 69 63 68 20 77 72 69 74 65  h of which write
0810: 73 20 34 4b 42 20 6f 66 20 64 61 74 61 2e 0a 2a  s 4KB of data..*
0820: 2a 0a 2a 2a 20 45 58 41 4d 50 4c 45 53 0a 2a 2a  *.** EXAMPLES.**
0830: 0a 2a 2a 20 20 20 54 77 6f 20 65 71 75 69 76 61  .**   Two equiva
0840: 6c 65 6e 74 20 65 78 61 6d 70 6c 65 73 3a 0a 2a  lent examples:.*
0850: 2a 0a 2a 2a 20 20 20 20 20 24 20 6c 73 6d 74 65  *.**     $ lsmte
0860: 73 74 20 69 6f 20 74 65 73 74 66 69 6c 65 2e 64  st io testfile.d
0870: 62 20 34 4b 42 20 32 4d 40 36 4d 20 31 34 39 32  b 4KB 2M@6M 1492
0880: 4b 40 34 4d 20 53 20 34 30 39 36 40 34 4b 20 53  K@4M S 4096@4K S
0890: 0a 2a 2a 20 20 20 20 20 33 35 34 34 4b 20 77 72  .**     3544K wr
08a0: 69 74 74 65 6e 20 69 6e 20 31 32 39 20 6d 73 0a  itten in 129 ms.
08b0: 2a 2a 20 20 20 20 20 24 20 65 63 68 6f 20 22 32  **     $ echo "2
08c0: 4d 40 36 4d 20 31 34 39 32 4b 40 34 4d 20 53 20  M@6M 1492K@4M S 
08d0: 34 30 39 36 40 34 4b 20 53 22 20 7c 20 6c 73 6d  4096@4K S" | lsm
08e0: 74 65 73 74 20 69 6f 20 74 65 73 74 66 69 6c 65  test io testfile
08f0: 2e 64 62 20 34 30 39 36 20 0a 2a 2a 20 20 20 20  .db 4096 .**    
0900: 20 33 35 34 34 4b 20 77 72 69 74 74 65 6e 20 69   3544K written i
0910: 6e 20 31 32 37 20 6d 73 0a 2a 2a 0a 2a 2f 0a 0a  n 127 ms.**.*/..
0920: 23 69 6e 63 6c 75 64 65 20 22 6c 73 6d 74 65 73  #include "lsmtes
0930: 74 2e 68 22 0a 0a 74 79 70 65 64 65 66 20 73 74  t.h"..typedef st
0940: 72 75 63 74 20 49 6f 43 6f 6e 74 65 78 74 20 49  ruct IoContext I
0950: 6f 43 6f 6e 74 65 78 74 3b 0a 0a 73 74 72 75 63  oContext;..struc
0960: 74 20 49 6f 43 6f 6e 74 65 78 74 20 7b 0a 20 20  t IoContext {.  
0970: 69 6e 74 20 66 64 3b 0a 20 20 69 6e 74 20 6e 57  int fd;.  int nW
0980: 72 69 74 65 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  rite;.};../*.** 
0990: 41 73 20 69 73 73 70 61 63 65 28 33 29 0a 2a 2f  As isspace(3).*/
09a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 61 66 65  .static int safe
09b0: 5f 69 73 73 70 61 63 65 28 63 68 61 72 20 63 29  _isspace(char c)
09c0: 7b 0a 20 20 69 66 28 20 63 26 30 78 38 30 29 20  {.  if( c&0x80) 
09d0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 72 65 74 75  return 0;.  retu
09e0: 72 6e 20 69 73 73 70 61 63 65 28 63 29 3b 0a 7d  rn isspace(c);.}
09f0: 0a 0a 2f 2a 0a 2a 2a 20 41 73 20 69 73 64 69 67  ../*.** As isdig
0a00: 69 74 28 33 29 0a 2a 2f 0a 73 74 61 74 69 63 20  it(3).*/.static 
0a10: 69 6e 74 20 73 61 66 65 5f 69 73 64 69 67 69 74  int safe_isdigit
0a20: 28 63 68 61 72 20 63 29 7b 0a 20 20 69 66 28 20  (char c){.  if( 
0a30: 63 26 30 78 38 30 29 20 72 65 74 75 72 6e 20 30  c&0x80) return 0
0a40: 3b 0a 20 20 72 65 74 75 72 6e 20 69 73 64 69 67  ;.  return isdig
0a50: 69 74 28 63 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  it(c);.}..static
0a60: 20 69 36 34 20 67 65 74 4e 65 78 74 53 69 7a 65   i64 getNextSize
0a70: 28 63 68 61 72 20 2a 7a 49 6e 2c 20 63 68 61 72  (char *zIn, char
0a80: 20 2a 2a 70 7a 4f 75 74 2c 20 69 6e 74 20 2a 70   **pzOut, int *p
0a90: 52 63 29 7b 0a 20 20 69 36 34 20 69 52 65 74 20  Rc){.  i64 iRet 
0aa0: 3d 20 30 3b 0a 20 20 69 66 28 20 2a 70 52 63 3d  = 0;.  if( *pRc=
0ab0: 3d 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  =0 ){.    char *
0ac0: 7a 20 3d 20 7a 49 6e 3b 0a 0a 20 20 20 20 69 66  z = zIn;..    if
0ad0: 28 20 21 73 61 66 65 5f 69 73 64 69 67 69 74 28  ( !safe_isdigit(
0ae0: 2a 7a 29 20 29 7b 0a 20 20 20 20 20 20 2a 70 52  *z) ){.      *pR
0af0: 63 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 65 74  c = 1;.      ret
0b00: 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 0a 20 20  urn 0;.    }..  
0b10: 20 20 2f 2a 20 50 72 6f 63 65 73 73 20 64 69 67    /* Process dig
0b20: 69 74 73 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65  its */.    while
0b30: 28 20 73 61 66 65 5f 69 73 64 69 67 69 74 28 2a  ( safe_isdigit(*
0b40: 7a 29 20 29 7b 0a 20 20 20 20 20 20 69 52 65 74  z) ){.      iRet
0b50: 20 3d 20 69 52 65 74 2a 31 30 20 2b 20 28 2a 7a   = iRet*10 + (*z
0b60: 20 2d 20 27 30 27 29 3b 0a 20 20 20 20 20 20 7a   - '0');.      z
0b70: 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ++;.    }..    /
0b80: 2a 20 50 72 6f 63 65 73 73 20 73 75 66 66 69 78  * Process suffix
0b90: 20 2a 2f 0a 20 20 20 20 73 77 69 74 63 68 28 20   */.    switch( 
0ba0: 2a 7a 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65  *z ){.      case
0bb0: 20 27 6b 27 3a 20 63 61 73 65 20 27 4b 27 3a 0a   'k': case 'K':.
0bc0: 20 20 20 20 20 20 20 20 69 52 65 74 20 3d 20 69          iRet = i
0bd0: 52 65 74 20 2a 20 31 30 32 34 3b 0a 20 20 20 20  Ret * 1024;.    
0be0: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 20      z++;.       
0bf0: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63   break;..      c
0c00: 61 73 65 20 27 6d 27 3a 20 63 61 73 65 20 27 4d  ase 'm': case 'M
0c10: 27 3a 0a 20 20 20 20 20 20 20 20 69 52 65 74 20  ':.        iRet 
0c20: 3d 20 69 52 65 74 20 2a 20 31 30 32 34 20 2a 20  = iRet * 1024 * 
0c30: 31 30 32 34 3b 0a 20 20 20 20 20 20 20 20 7a 2b  1024;.        z+
0c40: 2b 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  +;.        break
0c50: 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20 27 67  ;..      case 'g
0c60: 27 3a 20 63 61 73 65 20 27 47 27 3a 0a 20 20 20  ': case 'G':.   
0c70: 20 20 20 20 20 69 52 65 74 20 3d 20 69 52 65 74       iRet = iRet
0c80: 20 2a 20 31 30 32 34 20 2a 20 31 30 32 34 20 2a   * 1024 * 1024 *
0c90: 20 31 30 32 34 3b 0a 20 20 20 20 20 20 20 20 7a   1024;.        z
0ca0: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  ++;.        brea
0cb0: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  k;.    }..    if
0cc0: 28 20 70 7a 4f 75 74 20 29 20 2a 70 7a 4f 75 74  ( pzOut ) *pzOut
0cd0: 20 3d 20 7a 3b 0a 20 20 7d 0a 20 20 72 65 74 75   = z;.  }.  retu
0ce0: 72 6e 20 69 52 65 74 3b 0a 7d 0a 0a 73 74 61 74  rn iRet;.}..stat
0cf0: 69 63 20 69 6e 74 20 64 6f 4f 6e 65 43 6d 64 28  ic int doOneCmd(
0d00: 0a 20 20 49 6f 43 6f 6e 74 65 78 74 20 2a 70 43  .  IoContext *pC
0d10: 74 78 2c 0a 20 20 75 38 20 2a 61 44 61 74 61 2c  tx,.  u8 *aData,
0d20: 0a 20 20 69 6e 74 20 70 67 73 7a 2c 0a 20 20 63  .  int pgsz,.  c
0d30: 68 61 72 20 2a 7a 43 6d 64 2c 0a 20 20 63 68 61  har *zCmd,.  cha
0d40: 72 20 2a 2a 70 7a 4f 75 74 0a 29 7b 0a 20 20 63  r **pzOut.){.  c
0d50: 68 61 72 20 63 3b 0a 20 20 63 68 61 72 20 2a 7a  har c;.  char *z
0d60: 20 3d 20 7a 43 6d 64 3b 0a 0a 20 20 77 68 69 6c   = zCmd;..  whil
0d70: 65 28 20 73 61 66 65 5f 69 73 73 70 61 63 65 28  e( safe_isspace(
0d80: 2a 7a 29 20 29 20 7a 2b 2b 3b 0a 20 20 63 20 3d  *z) ) z++;.  c =
0d90: 20 2a 7a 3b 0a 0a 20 20 69 66 28 20 63 3d 3d 30   *z;..  if( c==0
0da0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 7a 4f 75   ){.    if( pzOu
0db0: 74 20 29 20 2a 70 7a 4f 75 74 20 3d 20 7a 3b 0a  t ) *pzOut = z;.
0dc0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
0dd0: 7d 0a 0a 20 20 69 66 28 20 63 3d 3d 27 73 27 20  }..  if( c=='s' 
0de0: 7c 7c 20 63 3d 3d 27 53 27 20 29 7b 0a 20 20 20  || c=='S' ){.   
0df0: 20 69 66 28 20 70 7a 4f 75 74 20 29 20 2a 70 7a   if( pzOut ) *pz
0e00: 4f 75 74 20 3d 20 26 7a 5b 31 5d 3b 0a 20 20 20  Out = &z[1];.   
0e10: 20 72 65 74 75 72 6e 20 66 64 61 74 61 73 79 6e   return fdatasyn
0e20: 63 28 70 43 74 78 2d 3e 66 64 29 3b 0a 20 20 7d  c(pCtx->fd);.  }
0e30: 0a 0a 20 20 69 66 28 20 73 61 66 65 5f 69 73 64  ..  if( safe_isd
0e40: 69 67 69 74 28 63 29 20 29 7b 0a 20 20 20 20 69  igit(c) ){.    i
0e50: 36 34 20 69 4f 66 66 20 3d 20 30 3b 0a 20 20 20  64 iOff = 0;.   
0e60: 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 30 3b 0a   int nByte = 0;.
0e70: 20 20 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a      int rc = 0;.
0e80: 20 20 20 20 69 6e 74 20 6e 50 67 3b 0a 20 20 20      int nPg;.   
0e90: 20 69 6e 74 20 69 50 67 3b 0a 0a 20 20 20 20 6e   int iPg;..    n
0ea0: 42 79 74 65 20 3d 20 28 69 6e 74 29 67 65 74 4e  Byte = (int)getN
0eb0: 65 78 74 53 69 7a 65 28 7a 2c 20 26 7a 2c 20 26  extSize(z, &z, &
0ec0: 72 63 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20  rc);.    if( rc 
0ed0: 7c 7c 20 2a 7a 21 3d 27 40 27 20 29 20 67 6f 74  || *z!='@' ) got
0ee0: 6f 20 62 61 64 5f 63 6f 6d 6d 61 6e 64 3b 0a 20  o bad_command;. 
0ef0: 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 69 4f 66 66     z++;.    iOff
0f00: 20 3d 20 67 65 74 4e 65 78 74 53 69 7a 65 28 7a   = getNextSize(z
0f10: 2c 20 26 7a 2c 20 26 72 63 29 3b 0a 20 20 20 20  , &z, &rc);.    
0f20: 69 66 28 20 72 63 20 7c 7c 20 28 73 61 66 65 5f  if( rc || (safe_
0f30: 69 73 73 70 61 63 65 28 2a 7a 29 3d 3d 30 20 26  isspace(*z)==0 &
0f40: 26 20 2a 7a 21 3d 27 5c 30 27 29 20 29 20 67 6f  & *z!='\0') ) go
0f50: 74 6f 20 62 61 64 5f 63 6f 6d 6d 61 6e 64 3b 0a  to bad_command;.
0f60: 20 20 20 20 69 66 28 20 70 7a 4f 75 74 20 29 20      if( pzOut ) 
0f70: 2a 70 7a 4f 75 74 20 3d 20 7a 3b 0a 0a 20 20 20  *pzOut = z;..   
0f80: 20 6e 50 67 20 3d 20 28 6e 42 79 74 65 2b 70 67   nPg = (nByte+pg
0f90: 73 7a 2d 31 29 20 2f 20 70 67 73 7a 3b 0a 20 20  sz-1) / pgsz;.  
0fa0: 20 20 6c 73 65 65 6b 28 70 43 74 78 2d 3e 66 64    lseek(pCtx->fd
0fb0: 2c 20 28 6f 66 66 5f 74 29 69 4f 66 66 2c 20 53  , (off_t)iOff, S
0fc0: 45 45 4b 5f 53 45 54 29 3b 0a 20 20 20 20 66 6f  EEK_SET);.    fo
0fd0: 72 28 69 50 67 3d 30 3b 20 69 50 67 3c 6e 50 67  r(iPg=0; iPg<nPg
0fe0: 3b 20 69 50 67 2b 2b 29 7b 0a 20 20 20 20 20 20  ; iPg++){.      
0ff0: 77 72 69 74 65 28 70 43 74 78 2d 3e 66 64 2c 20  write(pCtx->fd, 
1000: 61 44 61 74 61 2c 20 70 67 73 7a 29 3b 0a 20 20  aData, pgsz);.  
1010: 20 20 7d 0a 20 20 20 20 70 43 74 78 2d 3e 6e 57    }.    pCtx->nW
1020: 72 69 74 65 20 2b 3d 20 6e 42 79 74 65 2f 31 30  rite += nByte/10
1030: 32 34 3b 0a 0a 20 20 20 20 72 65 74 75 72 6e 20  24;..    return 
1040: 30 3b 0a 20 20 7d 0a 0a 20 62 61 64 5f 63 6f 6d  0;.  }.. bad_com
1050: 6d 61 6e 64 3a 0a 20 20 74 65 73 74 50 72 69 6e  mand:.  testPrin
1060: 74 45 72 72 6f 72 28 22 75 6e 72 65 63 6f 67 6e  tError("unrecogn
1070: 69 7a 65 64 20 63 6f 6d 6d 61 6e 64 3a 20 25 73  ized command: %s
1080: 22 2c 20 7a 43 6d 64 29 3b 0a 20 20 72 65 74 75  ", zCmd);.  retu
1090: 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 1;.}..static 
10a0: 69 6e 74 20 72 65 61 64 53 74 64 69 6e 28 63 68  int readStdin(ch
10b0: 61 72 20 2a 2a 70 7a 4f 75 74 29 7b 0a 20 20 69  ar **pzOut){.  i
10c0: 6e 74 20 6e 41 6c 6c 6f 63 20 3d 20 31 32 38 3b  nt nAlloc = 128;
10d0: 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 20 3d 20  .  char *zOut = 
10e0: 30 3b 0a 20 20 69 6e 74 20 6e 4f 75 74 20 3d 20  0;.  int nOut = 
10f0: 30 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 66 65  0;..  while( !fe
1100: 6f 66 28 73 74 64 69 6e 29 20 29 7b 0a 20 20 20  of(stdin) ){.   
1110: 20 69 6e 74 20 6e 52 65 61 64 3b 0a 0a 20 20 20   int nRead;..   
1120: 20 6e 41 6c 6c 6f 63 20 3d 20 6e 41 6c 6c 6f 63   nAlloc = nAlloc
1130: 2a 32 3b 0a 20 20 20 20 7a 4f 75 74 20 3d 20 72  *2;.    zOut = r
1140: 65 61 6c 6c 6f 63 28 7a 4f 75 74 2c 20 6e 41 6c  ealloc(zOut, nAl
1150: 6c 6f 63 29 3b 0a 20 20 20 20 6e 52 65 61 64 20  loc);.    nRead 
1160: 3d 20 66 72 65 61 64 28 26 7a 4f 75 74 5b 6e 4f  = fread(&zOut[nO
1170: 75 74 5d 2c 20 31 2c 20 6e 41 6c 6c 6f 63 2d 6e  ut], 1, nAlloc-n
1180: 4f 75 74 2d 31 2c 20 73 74 64 69 6e 29 3b 0a 0a  Out-1, stdin);..
1190: 20 20 20 20 69 66 28 20 6e 52 65 61 64 3d 3d 30      if( nRead==0
11a0: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 6e 4f   ) break;.    nO
11b0: 75 74 20 2b 3d 20 6e 52 65 61 64 3b 0a 20 20 20  ut += nRead;.   
11c0: 20 7a 4f 75 74 5b 6e 4f 75 74 5d 20 3d 20 27 5c   zOut[nOut] = '\
11d0: 30 27 3b 0a 20 20 7d 0a 0a 20 20 2a 70 7a 4f 75  0';.  }..  *pzOu
11e0: 74 20 3d 20 7a 4f 75 74 3b 0a 20 20 72 65 74 75  t = zOut;.  retu
11f0: 72 6e 20 30 3b 0a 7d 0a 0a 69 6e 74 20 64 6f 5f  rn 0;.}..int do_
1200: 69 6f 28 69 6e 74 20 6e 41 72 67 2c 20 63 68 61  io(int nArg, cha
1210: 72 20 2a 2a 61 7a 41 72 67 29 7b 0a 20 20 49 6f  r **azArg){.  Io
1220: 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20 69  Context ctx;.  i
1230: 6e 74 20 70 67 73 7a 3b 0a 20 20 63 68 61 72 20  nt pgsz;.  char 
1240: 2a 7a 46 69 6c 65 3b 0a 20 20 63 68 61 72 20 2a  *zFile;.  char *
1250: 7a 50 67 73 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a  zPgsz;.  int i;.
1260: 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a 0a 20    int rc = 0;.. 
1270: 20 63 68 61 72 20 2a 7a 53 74 64 69 6e 20 3d 20   char *zStdin = 
1280: 30 3b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 0a 20  0;.  char *z;.. 
1290: 20 75 38 20 2a 61 44 61 74 61 3b 0a 0a 20 20 6d   u8 *aData;..  m
12a0: 65 6d 73 65 74 28 26 63 74 78 2c 20 30 2c 20 73  emset(&ctx, 0, s
12b0: 69 7a 65 6f 66 28 49 6f 43 6f 6e 74 65 78 74 29  izeof(IoContext)
12c0: 29 3b 0a 20 20 69 66 28 20 6e 41 72 67 3c 32 20  );.  if( nArg<2 
12d0: 29 7b 0a 20 20 20 20 74 65 73 74 50 72 69 6e 74  ){.    testPrint
12e0: 55 73 61 67 65 28 22 46 49 4c 45 20 50 47 53 5a  Usage("FILE PGSZ
12f0: 20 3f 43 4d 44 2d 31 20 2e 2e 2e 3f 22 29 3b 0a   ?CMD-1 ...?");.
1300: 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20      return -1;. 
1310: 20 7d 0a 20 20 7a 46 69 6c 65 20 3d 20 61 7a 41   }.  zFile = azA
1320: 72 67 5b 30 5d 3b 0a 20 20 7a 50 67 73 7a 20 3d  rg[0];.  zPgsz =
1330: 20 61 7a 41 72 67 5b 31 5d 3b 0a 0a 20 20 70 67   azArg[1];..  pg
1340: 73 7a 20 3d 20 28 69 6e 74 29 67 65 74 4e 65 78  sz = (int)getNex
1350: 74 53 69 7a 65 28 7a 50 67 73 7a 2c 20 30 2c 20  tSize(zPgsz, 0, 
1360: 26 72 63 29 3b 0a 20 20 69 66 28 20 70 67 73 7a  &rc);.  if( pgsz
1370: 3c 3d 30 20 29 7b 0a 20 20 20 20 74 65 73 74 50  <=0 ){.    testP
1380: 72 69 6e 74 45 72 72 6f 72 28 22 52 69 64 69 63  rintError("Ridic
1390: 75 6c 6f 75 73 20 70 61 67 65 20 73 69 7a 65 3a  ulous page size:
13a0: 20 25 64 22 2c 20 70 67 73 7a 29 3b 0a 20 20 20   %d", pgsz);.   
13b0: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a   return -1;.  }.
13c0: 20 20 61 44 61 74 61 20 3d 20 6d 61 6c 6c 6f 63    aData = malloc
13d0: 28 70 67 73 7a 29 3b 0a 20 20 6d 65 6d 73 65 74  (pgsz);.  memset
13e0: 28 61 44 61 74 61 2c 20 30 78 37 37 2c 20 70 67  (aData, 0x77, pg
13f0: 73 7a 29 3b 0a 0a 20 20 63 74 78 2e 66 64 20 3d  sz);..  ctx.fd =
1400: 20 6f 70 65 6e 28 7a 46 69 6c 65 2c 20 4f 5f 52   open(zFile, O_R
1410: 44 57 52 7c 4f 5f 43 52 45 41 54 7c 5f 4f 5f 42  DWR|O_CREAT|_O_B
1420: 49 4e 41 52 59 2c 20 30 36 34 34 29 3b 0a 20 20  INARY, 0644);.  
1430: 69 66 28 20 63 74 78 2e 66 64 3c 30 20 29 7b 0a  if( ctx.fd<0 ){.
1440: 20 20 20 20 70 65 72 72 6f 72 28 22 6f 70 65 6e      perror("open
1450: 3a 20 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  : ");.    return
1460: 20 2d 31 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20   -1;.  }..  if( 
1470: 6e 41 72 67 3d 3d 32 20 29 7b 0a 20 20 20 20 72  nArg==2 ){.    r
1480: 65 61 64 53 74 64 69 6e 28 26 7a 53 74 64 69 6e  eadStdin(&zStdin
1490: 29 3b 0a 20 20 20 20 74 65 73 74 54 69 6d 65 49  );.    testTimeI
14a0: 6e 69 74 28 29 3b 0a 20 20 20 20 7a 20 3d 20 7a  nit();.    z = z
14b0: 53 74 64 69 6e 3b 0a 20 20 20 20 77 68 69 6c 65  Stdin;.    while
14c0: 28 20 2a 7a 20 26 26 20 72 63 3d 3d 30 20 29 7b  ( *z && rc==0 ){
14d0: 0a 20 20 20 20 20 20 72 63 20 3d 20 64 6f 4f 6e  .      rc = doOn
14e0: 65 43 6d 64 28 26 63 74 78 2c 20 61 44 61 74 61  eCmd(&ctx, aData
14f0: 2c 20 70 67 73 7a 2c 20 7a 2c 20 26 7a 29 3b 0a  , pgsz, z, &z);.
1500: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
1510: 20 20 20 74 65 73 74 54 69 6d 65 49 6e 69 74 28     testTimeInit(
1520: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20  );.    for(i=2; 
1530: 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20  i<nArg; i++){.  
1540: 20 20 20 20 72 63 20 3d 20 64 6f 4f 6e 65 43 6d      rc = doOneCm
1550: 64 28 26 63 74 78 2c 20 61 44 61 74 61 2c 20 70  d(&ctx, aData, p
1560: 67 73 7a 2c 20 61 7a 41 72 67 5b 69 5d 2c 20 30  gsz, azArg[i], 0
1570: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
1580: 70 72 69 6e 74 66 28 22 25 64 4b 20 77 72 69 74  printf("%dK writ
1590: 74 65 6e 20 69 6e 20 25 64 20 6d 73 5c 6e 22 2c  ten in %d ms\n",
15a0: 20 63 74 78 2e 6e 57 72 69 74 65 2c 20 74 65 73   ctx.nWrite, tes
15b0: 74 54 69 6d 65 47 65 74 28 29 29 3b 0a 0a 20 20  tTimeGet());..  
15c0: 66 72 65 65 28 7a 53 74 64 69 6e 29 3b 0a 20 20  free(zStdin);.  
15d0: 63 6c 6f 73 65 28 63 74 78 2e 66 64 29 3b 0a 0a  close(ctx.fd);..
15e0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a          return 0;.}.