Add msync support for WRITEMAP option

vmware
Howard Chu 12 years ago
parent d8a89464cd
commit 1c733bdc4e
  1. 46
      libraries/libmdb/mdb.c
  2. 2
      libraries/libmdb/mdb.h

@ -149,6 +149,7 @@
#define UNLOCK_MUTEX_W(env) pthread_mutex_unlock((env)->me_wmutex) #define UNLOCK_MUTEX_W(env) pthread_mutex_unlock((env)->me_wmutex)
#define getpid() GetCurrentProcessId() #define getpid() GetCurrentProcessId()
#define MDB_FDATASYNC(fd) (!FlushFileBuffers(fd)) #define MDB_FDATASYNC(fd) (!FlushFileBuffers(fd))
#define MDB_MSYNC(addr,len,flags) (!FlushViewOfFile(addr,len))
#define ErrCode() GetLastError() #define ErrCode() GetLastError()
#define GET_PAGESIZE(x) {SYSTEM_INFO si; GetSystemInfo(&si); (x) = si.dwPageSize;} #define GET_PAGESIZE(x) {SYSTEM_INFO si; GetSystemInfo(&si); (x) = si.dwPageSize;}
#define close(fd) CloseHandle(fd) #define close(fd) CloseHandle(fd)
@ -232,6 +233,18 @@
*/ */
#ifndef MDB_FDATASYNC #ifndef MDB_FDATASYNC
# define MDB_FDATASYNC fdatasync # define MDB_FDATASYNC fdatasync
#endif
#ifndef MDB_MSYNC
# define MDB_MSYNC(addr,len,flags) msync(addr,len,flags)
#endif
#ifndef MS_SYNC
#define MS_SYNC 1
#endif
#ifndef MS_ASYNC
#define MS_ASYNC 0
#endif #endif
/** A page number in the database. /** A page number in the database.
@ -1464,8 +1477,18 @@ mdb_env_sync(MDB_env *env, int force)
{ {
int rc = 0; int rc = 0;
if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) { if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) {
if (MDB_FDATASYNC(env->me_fd)) if (env->me_flags & MDB_WRITEMAP) {
rc = ErrCode(); int flags = (env->me_flags & MDB_MAPSYNC) ? MS_SYNC : MS_ASYNC;
if (MDB_MSYNC(env->me_map, env->me_mapsize, flags))
rc = ErrCode();
#ifdef _WIN32
else if (flags == MS_SYNC && MDB_FDATASYNC(env->me_fd))
rc = ErrCode();
#endif
} else {
if (MDB_FDATASYNC(env->me_fd))
rc = ErrCode();
}
} }
return rc; return rc;
} }
@ -2359,6 +2382,16 @@ mdb_env_write_meta(MDB_txn *txn)
mp->mm_dbs[1] = txn->mt_dbs[1]; mp->mm_dbs[1] = txn->mt_dbs[1];
mp->mm_last_pg = txn->mt_next_pgno - 1; mp->mm_last_pg = txn->mt_next_pgno - 1;
mp->mm_txnid = txn->mt_txnid; mp->mm_txnid = txn->mt_txnid;
if (!(env->me_flags & (MDB_NOMETASYNC|MDB_NOSYNC))) {
rc = (env->me_flags & MDB_MAPSYNC) ? MS_SYNC : MS_ASYNC;
ptr = env->me_map;
if (toggle)
ptr += env->me_psize;
if (MDB_MSYNC(ptr, env->me_psize, rc)) {
rc = ErrCode();
goto fail;
}
}
goto done; goto done;
} }
metab.mm_txnid = env->me_metas[toggle]->mm_txnid; metab.mm_txnid = env->me_metas[toggle]->mm_txnid;
@ -2403,6 +2436,7 @@ mdb_env_write_meta(MDB_txn *txn)
#else #else
r2 = pwrite(env->me_fd, ptr, len, off); r2 = pwrite(env->me_fd, ptr, len, off);
#endif #endif
fail:
env->me_flags |= MDB_FATAL_ERROR; env->me_flags |= MDB_FATAL_ERROR;
return rc; return rc;
} }
@ -2530,12 +2564,14 @@ mdb_env_open2(MDB_env *env, unsigned int flags)
return ErrCode(); return ErrCode();
SetFilePointer(env->me_fd, 0, NULL, 0); SetFilePointer(env->me_fd, 0, NULL, 0);
} }
mh = CreateFileMapping(env->me_fd, NULL, PAGE_READONLY, mh = CreateFileMapping(env->me_fd, NULL, flags & MDB_WRITEMAP ?
PAGE_READWRITE : PAGE_READONLY,
sizehi, sizelo, NULL); sizehi, sizelo, NULL);
if (!mh) if (!mh)
return ErrCode(); return ErrCode();
env->me_map = MapViewOfFileEx(mh, FILE_MAP_READ, 0, 0, env->me_mapsize, env->me_map = MapViewOfFileEx(mh, flags & MDB_WRITEMAP ?
meta.mm_address); FILE_MAP_WRITE : FILE_MAP_READ,
0, 0, env->me_mapsize, meta.mm_address);
CloseHandle(mh); CloseHandle(mh);
if (!env->me_map) if (!env->me_map)
return ErrCode(); return ErrCode();

@ -163,6 +163,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
#define MDB_NOMETASYNC 0x40000 #define MDB_NOMETASYNC 0x40000
/** use writable mmap */ /** use writable mmap */
#define MDB_WRITEMAP 0x80000 #define MDB_WRITEMAP 0x80000
/** use synchronous msync */
#define MDB_MAPSYNC 0x100000
/** @} */ /** @} */
/** @defgroup mdb_open Database Flags /** @defgroup mdb_open Database Flags

Loading…
Cancel
Save