SQLite

Check-in [dce35c01a5]
Login

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

Overview
Comment:Remove unnecessary code to round the size of a memory mapping to 4KB from os_unix.c. Rename SQLITE_IOERR_MREMAP to SQLITE_IOERR_MMAP. Fix other small issues in os_unix.c.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | experimental-mmap
Files: files | file ages | folders
SHA1: dce35c01a5fe66d2970075b1e3f0376026485e4c
User & Date: dan 2013-03-25 16:28:54.437
Context
2013-03-25
17:00
Change the signature of the xUnfetch method to "int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p)". (check-in: 115b830509 user: dan tags: experimental-mmap)
16:28
Remove unnecessary code to round the size of a memory mapping to 4KB from os_unix.c. Rename SQLITE_IOERR_MREMAP to SQLITE_IOERR_MMAP. Fix other small issues in os_unix.c. (check-in: dce35c01a5 user: dan tags: experimental-mmap)
14:31
Do not return SQLITE_IOERR when the user attempts to open a small file that is not a database with mmap enabled. Instead return SQLITE_NOTADB. (check-in: bbcaab3e80 user: dan tags: experimental-mmap)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
















4515
4516
4517
4518
4519
4520
4521
# define unixShmMap     0
# define unixShmLock    0
# define unixShmBarrier 0
# define unixShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */

/*
** Arguments x and y are both integers. Argument y must be a power of 2.
** Round x up to the nearest integer multiple of y. For example:
**
**     ROUNDUP(0,  8) ->  0
**     ROUNDUP(13, 8) -> 16
**     ROUNDUP(32, 8) -> 32
*/
#define ROUNDUP(x,y)     (((x)+y-1)&~(y-1))

static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );
  if( pFd->pMapRegion ){
    munmap(pFd->pMapRegion, pFd->mmapOrigsize);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapOrigsize = 0;
  }
}

















static int unixMapfile(unixFile *pFd, i64 nByte){
  i64 nMap = nByte;
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;








|
<
<
<
<
<

<
<










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4489
4490
4491
4492
4493
4494
4495
4496





4497


4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
# define unixShmMap     0
# define unixShmLock    0
# define unixShmBarrier 0
# define unixShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */

/*
** If it is currently memory mapped, unmap file pFd.





*/


static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );
  if( pFd->pMapRegion ){
    munmap(pFd->pMapRegion, pFd->mmapOrigsize);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapOrigsize = 0;
  }
}

/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if 
** there already exists a mapping for this file, and there are still 
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of 
** the mapping to create. Otherwise, if nByte is less than zero, then the 
** requested size is the size of the file on disk. The actual size of the
** created mapping is either the requested size or the value configured 
** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
  i64 nMap = nByte;
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;

4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546

4547
4548
4549
4550
4551
4552
4553












4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570







4571
4572
4573



4574
4575
4576
4577
4578
4579
4580
  if( nMap!=pFd->mmapSize ){
    unixUnmapfile(pFd);

    if( nMap>0 ){
      void *pNew;
      int flags = PROT_READ;
      if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
      pNew = mmap(0, ROUNDUP(nMap, 4096), flags, MAP_SHARED, pFd->h, 0);
      if( pNew==MAP_FAILED ){
        return SQLITE_IOERR_MREMAP;
      }

      pFd->pMapRegion = pNew;

      pFd->mmapOrigsize = pFd->mmapSize = nMap;
    }
  }

  return SQLITE_OK;
}













static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
  *pp = 0;

  if( pFd->mmapLimit>0 ){
    if( pFd->pMapRegion==0 ){
      int rc = unixMapfile(pFd, -1);
      if( rc!=SQLITE_OK ) return rc;
    }
    if( pFd->mmapSize >= iOff+nAmt ){
      *pp = &((u8 *)pFd->pMapRegion)[iOff];
      pFd->nFetchOut++;
    }
  }
  return SQLITE_OK;
}








static int unixUnfetch(sqlite3_file *fd, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */




  assert( (p==0)==(pFd->nFetchOut==0) );

  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }







|

|



>
|






>
>
>
>
>
>
>
>
>
>
>
>

















>
>
>
>
>
>
>



>
>
>







4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
  if( nMap!=pFd->mmapSize ){
    unixUnmapfile(pFd);

    if( nMap>0 ){
      void *pNew;
      int flags = PROT_READ;
      if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
      pNew = mmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);
      if( pNew==MAP_FAILED ){
        return SQLITE_IOERR_MMAP;
      }

      pFd->pMapRegion = pNew;
      pFd->mmapSize = nMap;
      pFd->mmapOrigsize = nMap;
    }
  }

  return SQLITE_OK;
}

/*
** If possible, return a pointer to a mapping of file fd starting at offset
** iOff. The mapping must be valid for at least nAmt bytes.
**
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
** Finally, if an error does occur, return an SQLite error code. The final
** value of *pp is undefined in this case.
**
** If this function does return a pointer, the caller must eventually 
** release the reference by calling unixUnfetch().
*/
static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
  *pp = 0;

  if( pFd->mmapLimit>0 ){
    if( pFd->pMapRegion==0 ){
      int rc = unixMapfile(pFd, -1);
      if( rc!=SQLITE_OK ) return rc;
    }
    if( pFd->mmapSize >= iOff+nAmt ){
      *pp = &((u8 *)pFd->pMapRegion)[iOff];
      pFd->nFetchOut++;
    }
  }
  return SQLITE_OK;
}

/*
** If the second argument is non-NULL, then this function releases a 
** reference obtained by an earlier call to unixFetch(). Or, if the second
** argument is NULL, then this function is being called to inform the VFS
** layer that, according to POSIX, any existing mapping may now be invalid
** and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */

  /* If p==0 (unmap the entire file) then there must be no outstanding 
  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
  ** then there must be at least one outstanding.  */
  assert( (p==0)==(pFd->nFetchOut==0) );

  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }
Changes to src/sqlite.h.in.
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MREMAP            (SQLITE_IOERR | (24<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))







|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))