/ Check-in [5752d84d]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add new OS file method to return the sector-size of the underlying storage: sqlite3OsSectorSize() (CVS 3700)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5752d84d374205e011d49b0221d6237967fe0743
User & Date: danielk1977 2007-03-19 05:54:49
Context
2007-03-19
11:25
Changes to support medium sector sizes larger than the database page size. (CVS 3701) check-in: 3a3e8eb2 user: danielk1977 tags: trunk
05:54
Add new OS file method to return the sector-size of the underlying storage: sqlite3OsSectorSize() (CVS 3700) check-in: 5752d84d user: danielk1977 tags: trunk
2007-03-17
18:22
Add documentation of the REPLACE, TRIM, LTRIM, and RTRIM functions. (CVS 3699) check-in: d42c9636 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os.c.

71
72
73
74
75
76
77



78
79
80
81
82
83
84
}
int sqlite3OsLockState(OsFile *id){
  return id->pMethod->xLockState(id);
}
int sqlite3OsCheckReservedLock(OsFile *id){
  return id->pMethod->xCheckReservedLock(id);
}




#ifdef SQLITE_ENABLE_REDEF_IO
/*
** A function to return a pointer to the virtual function table.
** This routine really does not accomplish very much since the
** virtual function table is a global variable and anybody who
** can call this function can just as easily access the variable







>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
}
int sqlite3OsLockState(OsFile *id){
  return id->pMethod->xLockState(id);
}
int sqlite3OsCheckReservedLock(OsFile *id){
  return id->pMethod->xCheckReservedLock(id);
}
int sqlite3OsSectorSize(OsFile *id){
  return id->pMethod->xSectorSize(id);
}

#ifdef SQLITE_ENABLE_REDEF_IO
/*
** A function to return a pointer to the virtual function table.
** This routine really does not accomplish very much since the
** virtual function table is a global variable and anybody who
** can call this function can just as easily access the variable

Changes to src/os.h.

212
213
214
215
216
217
218

219
220
221
222
223
224
225
...
342
343
344
345
346
347
348

349
350
351
352
353
354
355
  void (*xSetFullSync)(OsFile *id, int setting);
  int (*xFileHandle)(OsFile *id);
  int (*xFileSize)(OsFile*, i64 *pSize);
  int (*xLock)(OsFile*, int);
  int (*xUnlock)(OsFile*, int);
  int (*xLockState)(OsFile *id);
  int (*xCheckReservedLock)(OsFile *id);

};

/*
** The OsFile object describes an open disk file in an OS-dependent way.
** The version of OsFile defined here is a generic version.  Each OS
** implementation defines its own subclass of this structure that contains
** additional information needed to handle file I/O.  But the pMethod
................................................................................
int sqlite3OsOpenExclusive(const char*, OsFile**, int);
int sqlite3OsOpenReadOnly(const char*, OsFile**);
int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
char *sqlite3OsFullPathname(const char*);
int sqlite3OsIsDirWritable(char*);
int sqlite3OsSyncDirectory(const char*);

int sqlite3OsTempFileName(char*);
int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms);
int sqlite3OsCurrentTime(double*);
void sqlite3OsEnterMutex(void);
void sqlite3OsLeaveMutex(void);
int sqlite3OsInMutex(int);







>







 







>







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  void (*xSetFullSync)(OsFile *id, int setting);
  int (*xFileHandle)(OsFile *id);
  int (*xFileSize)(OsFile*, i64 *pSize);
  int (*xLock)(OsFile*, int);
  int (*xUnlock)(OsFile*, int);
  int (*xLockState)(OsFile *id);
  int (*xCheckReservedLock)(OsFile *id);
  int (*xSectorSize)(OsFile *id);
};

/*
** The OsFile object describes an open disk file in an OS-dependent way.
** The version of OsFile defined here is a generic version.  Each OS
** implementation defines its own subclass of this structure that contains
** additional information needed to handle file I/O.  But the pMethod
................................................................................
int sqlite3OsOpenExclusive(const char*, OsFile**, int);
int sqlite3OsOpenReadOnly(const char*, OsFile**);
int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
char *sqlite3OsFullPathname(const char*);
int sqlite3OsIsDirWritable(char*);
int sqlite3OsSyncDirectory(const char*);
int sqlite3OsSectorSize(OsFile *id);
int sqlite3OsTempFileName(char*);
int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms);
int sqlite3OsCurrentTime(double*);
void sqlite3OsEnterMutex(void);
void sqlite3OsLeaveMutex(void);
int sqlite3OsInMutex(int);

Changes to src/os_common.h.

186
187
188
189
190
191
192











void sqlite3GenericFree(void *p){
  assert(p);
  free(p);
}
/* Never actually used, but needed for the linker */
int sqlite3GenericAllocationSize(void *p){ return 0; }
#endif


















>
>
>
>
>
>
>
>
>
>
>
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
void sqlite3GenericFree(void *p){
  assert(p);
  free(p);
}
/* Never actually used, but needed for the linker */
int sqlite3GenericAllocationSize(void *p){ return 0; }
#endif

/*
** The default size of a disk sector
*/
#ifndef PAGER_SECTOR_SIZE
# define PAGER_SECTOR_SIZE 512
#endif
static int osGenericSectorSize(OsFile *id){
  return PAGER_SECTOR_SIZE;
}

Changes to src/os_os2.c.

747
748
749
750
751
752
753

754
755
756
757
758
759
760
  os2SetFullSync,
  os2FileHandle,
  os2FileSize,
  os2Lock,
  os2Unlock,
  os2LockState,
  os2CheckReservedLock,

};

/*
** Allocate memory for an OsFile.  Initialize the new OsFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/







>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  os2SetFullSync,
  os2FileHandle,
  os2FileSize,
  os2Lock,
  os2Unlock,
  os2LockState,
  os2CheckReservedLock,
  osGenericSectorSize,
};

/*
** Allocate memory for an OsFile.  Initialize the new OsFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/

Changes to src/os_unix.c.

2351
2352
2353
2354
2355
2356
2357

2358
2359
2360
2361
2362
2363
2364
....
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384
2385
2386
....
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404
2405
2406
2407
....
2415
2416
2417
2418
2419
2420
2421

2422
2423
2424
2425
2426
2427
2428
....
2436
2437
2438
2439
2440
2441
2442

2443
2444
2445
2446
2447
2448
2449
  unixSetFullSync,
  unixFileHandle,
  unixFileSize,
  unixLock,
  unixUnlock,
  unixLockState,
  unixCheckReservedLock,

};

#ifdef SQLITE_ENABLE_LOCKING_STYLE
/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with AFP style file locking.
 */
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    afpUnixLock,
    afpUnixUnlock,
    unixLockState,
    afpUnixCheckReservedLock,

};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with flock() style file locking.
 */
static const IoMethod sqlite3FlockLockingUnixIoMethod = {
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    flockUnixLock,
    flockUnixUnlock,
    unixLockState,
    flockUnixCheckReservedLock,

};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with dotlock style file locking.
 */
static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    dotlockUnixLock,
    dotlockUnixUnlock,
    unixLockState,
    dotlockUnixCheckReservedLock,

};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with dotlock style file locking.
 */
static const IoMethod sqlite3NolockLockingUnixIoMethod = {
................................................................................
  unixSetFullSync,
  unixFileHandle,
  unixFileSize,
  nolockUnixLock,
  nolockUnixUnlock,
  unixLockState,
  nolockUnixCheckReservedLock,

};

#endif /* SQLITE_ENABLE_LOCKING_STYLE */

/*
** Allocate memory for a new unixFile and initialize that unixFile.
** Write a pointer to the new unixFile into *pId.







>







 







>







 







>







 







>







 







>







2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
....
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
....
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
....
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
....
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
  unixSetFullSync,
  unixFileHandle,
  unixFileSize,
  unixLock,
  unixUnlock,
  unixLockState,
  unixCheckReservedLock,
  osGenericSectorSize,
};

#ifdef SQLITE_ENABLE_LOCKING_STYLE
/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with AFP style file locking.
 */
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    afpUnixLock,
    afpUnixUnlock,
    unixLockState,
    afpUnixCheckReservedLock,
    osGenericSectorSize,
};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with flock() style file locking.
 */
static const IoMethod sqlite3FlockLockingUnixIoMethod = {
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    flockUnixLock,
    flockUnixUnlock,
    unixLockState,
    flockUnixCheckReservedLock,
    osGenericSectorSize,
};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with dotlock style file locking.
 */
static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
................................................................................
    unixSetFullSync,
    unixFileHandle,
    unixFileSize,
    dotlockUnixLock,
    dotlockUnixUnlock,
    unixLockState,
    dotlockUnixCheckReservedLock,
    osGenericSectorSize,
};

/*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix with dotlock style file locking.
 */
static const IoMethod sqlite3NolockLockingUnixIoMethod = {
................................................................................
  unixSetFullSync,
  unixFileHandle,
  unixFileSize,
  nolockUnixLock,
  nolockUnixUnlock,
  unixLockState,
  nolockUnixCheckReservedLock,
  osGenericSectorSize,
};

#endif /* SQLITE_ENABLE_LOCKING_STYLE */

/*
** Allocate memory for a new unixFile and initialize that unixFile.
** Write a pointer to the new unixFile into *pId.

Changes to src/os_win.c.

1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
  winSetFullSync,
  winFileHandle,
  winFileSize,
  winLock,
  winUnlock,
  winLockState,
  winCheckReservedLock,

};

/*
** Allocate memory for an OsFile.  Initialize the new OsFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/







>







1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
  winSetFullSync,
  winFileHandle,
  winFileSize,
  winLock,
  winUnlock,
  winLockState,
  winCheckReservedLock,
  osGenericSectorSize,
};

/*
** Allocate memory for an OsFile.  Initialize the new OsFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
....
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
....
1734
1735
1736
1737
1738
1739
1740


1741

1742
1743
1744
1745
1746
1747
1748
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.288 2007/03/15 12:51:16 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
*/
#ifdef SQLITE_OMIT_MEMORYDB
# define MEMDB 0
#else
# define MEMDB pPager->memDb
#endif

/*
** The default size of a disk sector
*/
#ifndef PAGER_SECTOR_SIZE
# define PAGER_SECTOR_SIZE 512
#endif

/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details.
*/
................................................................................
    sqliteFree(zMaster);
  }

  /* The Pager.sectorSize variable may have been updated while rolling
  ** back a journal created by a process with a different PAGER_SECTOR_SIZE
  ** value. Reset it to the correct value for this process.
  */
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  return rc;
}

/*
** Playback the statement journal.
**
** This is similar to playing back the transaction journal but with
................................................................................
  /* pPager->needSync = 0; */
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->fullSync = (pPager->noSync?0:1);
  /* pPager->pFirst = 0; */
  /* pPager->pFirstSynced = 0; */
  /* pPager->pLast = 0; */
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);


  pPager->sectorSize = PAGER_SECTOR_SIZE;

  /* pPager->pBusyHandler = 0; */
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  pPager->pNext = pTsd->pPager;
  pTsd->pPager = pPager;
#endif







|







 







<
<
<
<
<
<
<







 







|







 







>
>
|
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
345
346
347
348
349
350
351







352
353
354
355
356
357
358
....
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
....
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.289 2007/03/19 05:54:49 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
*/
#ifdef SQLITE_OMIT_MEMORYDB
# define MEMDB 0
#else
# define MEMDB pPager->memDb
#endif








/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details.
*/
................................................................................
    sqliteFree(zMaster);
  }

  /* The Pager.sectorSize variable may have been updated while rolling
  ** back a journal created by a process with a different PAGER_SECTOR_SIZE
  ** value. Reset it to the correct value for this process.
  */
  pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
  return rc;
}

/*
** Playback the statement journal.
**
** This is similar to playing back the transaction journal but with
................................................................................
  /* pPager->needSync = 0; */
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->fullSync = (pPager->noSync?0:1);
  /* pPager->pFirst = 0; */
  /* pPager->pFirstSynced = 0; */
  /* pPager->pLast = 0; */
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  assert(fd||memDb);
  if( !memDb ){
    pPager->sectorSize = sqlite3OsSectorSize(fd);
  }
  /* pPager->pBusyHandler = 0; */
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  pPager->pNext = pTsd->pPager;
  pTsd->pPager = pPager;
#endif

Changes to src/test6.c.

473
474
475
476
477
478
479







480
481
482
483
484
485
486
...
493
494
495
496
497
498
499

500
501
502
503
504
505
506
*/
int crashFileHandle(OsFile *id){
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  return sqlite3OsFileHandle(((crashFile*)id)->pBase);
#endif
  return 0;
}








/*
** This vector defines all the methods that can operate on an OsFile
** for the crash tester.
*/
static const IoMethod crashIoMethod = {
  crashClose,
................................................................................
  crashSetFullSync,
  crashFileHandle,
  crashFileSize,
  crashLock,
  crashUnlock,
  crashLockState,
  crashCheckReservedLock,

};


/*
** Initialise the os_test.c specific fields of pFile.
*/
static void initFile(OsFile **pId, char const *zName, OsFile *pBase){







>
>
>
>
>
>
>







 







>







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
*/
int crashFileHandle(OsFile *id){
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  return sqlite3OsFileHandle(((crashFile*)id)->pBase);
#endif
  return 0;
}

/*
** Return the simulated file-system sector size.
*/
int crashSectorSize(OsFile *id){
  return BLOCKSIZE;
}

/*
** This vector defines all the methods that can operate on an OsFile
** for the crash tester.
*/
static const IoMethod crashIoMethod = {
  crashClose,
................................................................................
  crashSetFullSync,
  crashFileHandle,
  crashFileSize,
  crashLock,
  crashUnlock,
  crashLockState,
  crashCheckReservedLock,
  crashSectorSize,
};


/*
** Initialise the os_test.c specific fields of pFile.
*/
static void initFile(OsFile **pId, char const *zName, OsFile *pBase){

Changes to src/test_async.c.

645
646
647
648
649
650
651







652
653
654
655
656
657
658
...
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
  int rc;
  pthread_mutex_lock(&async.lockMutex);
  rc = (int)sqlite3HashFind(&async.aLock, pFile->zName, pFile->nName);
  pthread_mutex_unlock(&async.lockMutex);
  TRACE(("CHECK-LOCK %d (%s)\n", rc, pFile->zName));
  return rc>SHARED_LOCK;
}








/* 
** This is broken. But sqlite3OsLockState() is only used for testing anyway.
*/
static int asyncLockState(OsFile *id){
  return SQLITE_OK;
}
................................................................................
    asyncSync,
    asyncSetFullSync,
    asyncFileHandle,
    asyncFileSize,
    asyncLock,
    asyncUnlock,
    asyncLockState,
    asyncCheckReservedLock

  };

  if( openForWriting && SQLITE_ASYNC_TWO_FILEHANDLES ){
    int dummy;
    rc = xOrigOpenReadWrite(zName, &pBaseWrite, &dummy);
    if( rc!=SQLITE_OK ){
      goto error_out;







>
>
>
>
>
>
>







 







|
>







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
...
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
  int rc;
  pthread_mutex_lock(&async.lockMutex);
  rc = (int)sqlite3HashFind(&async.aLock, pFile->zName, pFile->nName);
  pthread_mutex_unlock(&async.lockMutex);
  TRACE(("CHECK-LOCK %d (%s)\n", rc, pFile->zName));
  return rc>SHARED_LOCK;
}

static int asyncSectorSize(OsFile *id){
  /* TODO: This is tricky to implement, as this backend might not have
  ** an open file handle at this point.
  */
  return 512;
}

/* 
** This is broken. But sqlite3OsLockState() is only used for testing anyway.
*/
static int asyncLockState(OsFile *id){
  return SQLITE_OK;
}
................................................................................
    asyncSync,
    asyncSetFullSync,
    asyncFileHandle,
    asyncFileSize,
    asyncLock,
    asyncUnlock,
    asyncLockState,
    asyncCheckReservedLock,
    asyncSectorSize,
  };

  if( openForWriting && SQLITE_ASYNC_TWO_FILEHANDLES ){
    int dummy;
    rc = xOrigOpenReadWrite(zName, &pBaseWrite, &dummy);
    if( rc!=SQLITE_OK ){
      goto error_out;

Changes to test/crash2.test.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#
# The focus of this file is testing the ability of the database to
# uses its rollback journal to recover intact (no database corruption)
# from a power failure during the middle of a COMMIT. Even more
# specifically, the tests in this file verify this functionality
# for storage mediums with various sector sizes.
#
# $Id: crash2.test,v 1.1 2007/03/17 10:28:05 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !crashtest {
  finish_test
  return







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#
# The focus of this file is testing the ability of the database to
# uses its rollback journal to recover intact (no database corruption)
# from a power failure during the middle of a COMMIT. Even more
# specifically, the tests in this file verify this functionality
# for storage mediums with various sector sizes.
#
# $Id: crash2.test,v 1.2 2007/03/19 05:54:50 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !crashtest {
  finish_test
  return