------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Increase\sthe\sversion\snumber\sto\s3.7.1\sdue\sto\sthe\sAPI\senhancement\sof\sthe\sprevious\ncheck-in.
-D 2010-07-26T16:40:04
+C Add\sexperimental\sunix-only\sfile-control\sto\sgrow\sand\struncate\sthe\sdatabase\sfile\sby\sa\sconfigurable\schunk\ssize.
+D 2010-07-27T18:34:16
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
-F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
+F src/os_unix.c 77e963fbbed6a2ca9b7c9115ae06f05181729490
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
F src/pager.c 78ca1e1f3315c8227431c403c04d791dccf242fb
F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
-F src/sqlite.h.in e789728101d821fd4307208aa11e332e51eedbf9
+F src/sqlite.h.in 3b201a7aced2227339c2bba8dfbee47a823d43ad
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
F src/status.c 51f65ba9768846c071fa621624d55d6866fce28b
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4
-F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3
+F src/test1.c 0bfcda72f9f8ab5c0e90fac05cc22c1c21131ddf
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
+F test/fallocate.test 2aa524a237893aca5b2a7ad5d450ee4801b4abdd
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
F test/filefmt.test 5d271bf467e6557fe7499dcc8203069c9dc5825e
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 008368b2bd1513e2df21c2070548c6fc94abebb1
-R e0e547721eadb5865947ac95d9a5637b
-U drh
-Z b2f076ca75f409c11b1173e904fc1e43
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMTbpnoxKgR168RlERAgRsAKCEDv9PrVdoUqb+GgrX9p308vOjrgCgi4/A
-Wv1UV7AZmSjiGasHOtjRZXM=
-=082N
------END PGP SIGNATURE-----
+P 1d7571e4be6d96aec13cd8b3b7b10b8dc44d19a5
+R 06d24f984109c26ad9ccb04075848e30
+T *branch * experimental
+T *sym-experimental *
+T -sym-trunk *
+U dan
+Z 84d3b6ef35de3d3ded4f7f20ba0de5c7
-1d7571e4be6d96aec13cd8b3b7b10b8dc44d19a5
\ No newline at end of file
+7cf0e851d4c5e826ea22ed08291b7c91d7b1abc7
\ No newline at end of file
int fileFlags; /* Miscellanous flags */
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
+ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
#if SQLITE_ENABLE_LOCKING_STYLE
int openFlags; /* The flags specified at open() */
#endif
}
SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 ));
+
+ /* If the user has configured a chunk-size for this file, it could be
+ ** that the file needs to be extended at this point.
+ */
+ if( pFile->szChunk && amt==0 ){
+ i64 nSize; /* Required file size */
+ struct stat buf; /* Used to hold return values of fstat() */
+ int rc = fstat(pFile->h, &buf);
+ if( rc!=0 ) return SQLITE_IOERR_FSTAT;
+ nSize = ((offset+amt+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
+ if( nSize>(i64)buf.st_size ){
+#ifdef HAVE_POSIX_FALLOCATE
+ if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){
+ return SQLITE_IOERR_WRITE;
+ }
+#else
+ /* If the OS does not have posix_fallocate(), fake it. First use
+ ** ftruncate() to set the file size, then write a single byte to
+ ** the last byte in each block within the extended region.
+ */
+ int nBlk = buf.st_blksize; /* File-system block size */
+ i64 iWrite; /* Next offset to write to */
+
+ if( ftruncate(pFile->h, nSize) ){
+ pFile->lastErrno = errno;
+ return SQLITE_IOERR_TRUNCATE;
+ }
+ iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
+ do {
+ wrote = seekAndWrite(pFile, iWrite, "", 1);
+ iWrite += nBlk;
+ } while( wrote==1 && iWrite<nSize );
+ if( wrote!=1 ) amt = 1;
+#endif
+ }
+ }
+
if( amt>0 ){
if( wrote<0 ){
/* lastErrno set by seekAndWrite */
return SQLITE_FULL;
}
}
+
return SQLITE_OK;
}
** Truncate an open file to a specified size
*/
static int unixTruncate(sqlite3_file *id, i64 nByte){
+ unixFile *pFile = (unixFile *)id;
int rc;
- assert( id );
+ assert( pFile );
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
- rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
+
+ /* If the user has configured a chunk-size for this file, truncate the
+ ** file so that it consists of an integer number of chunks (i.e. the
+ ** actual file size after the operation may be larger than the requested
+ ** size).
+ */
+ if( pFile->szChunk ){
+ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
+ }
+
+ rc = ftruncate(pFile->h, (off_t)nByte);
if( rc ){
- ((unixFile*)id)->lastErrno = errno;
+ pFile->lastErrno = errno;
return SQLITE_IOERR_TRUNCATE;
}else{
#ifndef NDEBUG
** when restoring a database using the backup API from a zero-length
** source.
*/
- if( ((unixFile*)id)->inNormalWrite && nByte==0 ){
- ((unixFile*)id)->transCntrChng = 1;
+ if( pFile->inNormalWrite && nByte==0 ){
+ pFile->transCntrChng = 1;
}
#endif
*(int*)pArg = ((unixFile*)id)->lastErrno;
return SQLITE_OK;
}
+ case SQLITE_FCNTL_CHUNK_SIZE: {
+ ((unixFile*)id)->szChunk = *(int *)pArg;
+ return SQLITE_OK;
+ }
case SQLITE_FCNTL_SIZE_HINT: {
#if 0 /* No performance advantage seen on Linux */
sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
#define SQLITE_SET_LOCKPROXYFILE 3
#define SQLITE_LAST_ERRNO 4
#define SQLITE_FCNTL_SIZE_HINT 5
+#define SQLITE_FCNTL_CHUNK_SIZE 6
/*
** CAPI3REF: Mutex Handle
return TCL_OK;
}
+/*
+** tclcmd: file_control_chunksize_test DB DBNAME SIZE
+**
+** This TCL command runs the sqlite3_file_control interface and
+** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
+** SQLITE_SET_LOCKPROXYFILE verbs.
+*/
+static int file_control_chunksize_test(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ int nSize; /* New chunk size */
+ char *zDb; /* Db name ("main", "temp" etc.) */
+ sqlite3 *db; /* Database handle */
+ int rc; /* file_control() return code */
+
+ if( objc!=4 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
+ || Tcl_GetIntFromObj(interp, objv[3], &nSize)
+ ){
+ return TCL_ERROR;
+ }
+ zDb = Tcl_GetString(objv[2]);
+ if( zDb[0]=='\0' ) zDb = NULL;
+
+ rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
+ if( rc ){
+ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
/*
** tclcmd: file_control_lockproxy_test DB PWD
**
{ "file_control_test", file_control_test, 0 },
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
+ { "file_control_chunksize_test", file_control_chunksize_test, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
/* Functions from os.h */
--- /dev/null
+# 2010 July 28
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+if {$::tcl_platform(platform)!="unix"} {
+ finish_test
+ return
+}
+
+file_control_chunksize_test db main [expr 1024*1024]
+
+do_test fallocate-1.1 {
+ execsql {
+ PRAGMA page_size = 1024;
+ PRAGMA auto_vacuum = 1;
+ CREATE TABLE t1(a, b);
+ }
+ file size test.db
+} [expr 1*1024*1024]
+
+do_test fallocate-1.2 {
+ execsql { INSERT INTO t1 VALUES(1, zeroblob(1024*900)) }
+ file size test.db
+} [expr 1*1024*1024]
+
+do_test fallocate-1.3 {
+ execsql { INSERT INTO t1 VALUES(2, zeroblob(1024*900)) }
+ file size test.db
+} [expr 2*1024*1024]
+
+do_test fallocate-1.4 {
+ execsql { DELETE FROM t1 WHERE a = 1 }
+ file size test.db
+} [expr 1*1024*1024]
+
+do_test fallocate-1.5 {
+ execsql { DELETE FROM t1 WHERE a = 2 }
+ file size test.db
+} [expr 1*1024*1024]
+
+do_test fallocate-1.6 {
+ execsql { PRAGMA freelist_count }
+} {0}
+
+finish_test