Codebase list lmdb / 6354ec3
New upstream version 0.9.15 Ondřej Surý 8 years ago
24 changed file(s) with 394 addition(s) and 193 deletion(s). Raw diff Collapse all Expand all
22 testdb
33 mdb_copy
44 mdb_stat
5 mdb_dump
6 mdb_load
7 *.lo
58 *.[ao]
69 *.so
710 *.exe
00 LMDB 0.9 Change Log
1
2 LMDB 0.9.15 Release (2015/06/19)
3 Fix txn init (ITS#7961,#7987)
4 Fix MDB_PREV_DUP (ITS#7955,#7671)
5 Fix compact of empty env (ITS#7956)
6 Fix mdb_copy file mode
7 Fix mdb_env_close() after failed mdb_env_open()
8 Fix mdb_rebalance collapsing root (ITS#8062)
9 Fix mdb_load with large values (ITS#8066)
10 Fix to retry writes on EINTR (ITS#8106)
11 Fix mdb_cursor_del on empty DB (ITS#8109)
12 Fix MDB_INTEGERDUP key compare (ITS#8117)
13 Fix error handling (ITS#7959,#8157,etc.)
14 Fix race conditions (ITS#7969,7970)
15 Added workaround for fdatasync bug in ext3fs
16 Build
17 Don't use -fPIC for static lib
18 Update .gitignore (ITS#7952,#7953)
19 Cleanup for "make test" (ITS#7841), "make clean", mtest*.c
20 Misc. Android/Windows cleanup
21 Documentation
22 Fix MDB_APPEND doc
23 Fix MDB_MAXKEYSIZE doc (ITS#8156)
24 Fix mdb_cursor_put,mdb_cursor_del EACCES description
25 Fix mdb_env_sync(MDB_RDONLY env) doc (ITS#8021)
26 Clarify MDB_WRITEMAP doc (ITS#8021)
27 Clarify mdb_env_open doc
28 Clarify mdb_dbi_open doc
129
230 LMDB 0.9.14 Release (2014/09/20)
331 Fix to support 64K page size (ITS#7713)
0 Copyright 2011-2014 Howard Chu, Symas Corp.
0 Copyright 2011-2015 Howard Chu, Symas Corp.
11 All rights reserved.
22
33 Redistribution and use in source and binary forms, with or without
1010 # - MDB_USE_POSIX_SEM
1111 # - MDB_DSYNC
1212 # - MDB_FDATASYNC
13 # - MDB_FDATASYNC_WORKS
1314 # - MDB_USE_PWRITEV
1415 #
1516 # There may be other macros in mdb.c of interest. You should
4041 for f in $(IDOCS); do cp $$f $(DESTDIR)$(prefix)/man/man1; done
4142
4243 clean:
43 rm -rf $(PROGS) *.[ao] *.so *~ testdb
44 rm -rf $(PROGS) *.[ao] *.[ls]o *~ testdb
4445
4546 test: all
46 mkdir testdb
47 rm -rf testdb && mkdir testdb
4748 ./mtest && ./mdb_stat testdb
4849
4950 liblmdb.a: mdb.o midl.o
5051 ar rs $@ mdb.o midl.o
5152
52 liblmdb.so: mdb.o midl.o
53 liblmdb.so: mdb.lo midl.lo
5354 # $(CC) $(LDFLAGS) -pthread -shared -Wl,-Bsymbolic -o $@ mdb.o midl.o $(SOLIBS)
54 $(CC) $(LDFLAGS) -pthread -shared -o $@ mdb.o midl.o $(SOLIBS)
55 $(CC) $(LDFLAGS) -pthread -shared -o $@ mdb.lo midl.lo $(SOLIBS)
5556
5657 mdb_stat: mdb_stat.o liblmdb.a
5758 mdb_copy: mdb_copy.o liblmdb.a
6566 mtest6: mtest6.o liblmdb.a
6667
6768 mdb.o: mdb.c lmdb.h midl.h
68 $(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c mdb.c
69 $(CC) $(CFLAGS) $(CPPFLAGS) -c mdb.c
6970
7071 midl.o: midl.c midl.h
71 $(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c midl.c
72 $(CC) $(CFLAGS) $(CPPFLAGS) -c midl.c
73
74 mdb.lo: mdb.c lmdb.h midl.h
75 $(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c mdb.c -o $@
76
77 midl.lo: midl.c midl.h
78 $(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c midl.c -o $@
7279
7380 %: %.o
7481 $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
118118 *
119119 * @author Howard Chu, Symas Corporation.
120120 *
121 * @copyright Copyright 2011-2014 Howard Chu, Symas Corp. All rights reserved.
121 * @copyright Copyright 2011-2015 Howard Chu, Symas Corp. All rights reserved.
122122 *
123123 * Redistribution and use in source and binary forms, with or without
124124 * modification, are permitted only as authorized by the OpenLDAP
183183 /** Library minor version */
184184 #define MDB_VERSION_MINOR 9
185185 /** Library patch version */
186 #define MDB_VERSION_PATCH 14
186 #define MDB_VERSION_PATCH 15
187187
188188 /** Combine args a,b,c into a single integer for easy version comparisons */
189189 #define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))
193193 MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)
194194
195195 /** The release date of this library version */
196 #define MDB_VERSION_DATE "September 20, 2014"
196 #define MDB_VERSION_DATE "June 19, 2015"
197197
198198 /** A stringifier for the version info */
199199 #define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
295295 #define MDB_REVERSEKEY 0x02
296296 /** use sorted duplicates */
297297 #define MDB_DUPSORT 0x04
298 /** numeric keys in native byte order.
298 /** numeric keys in native byte order: either unsigned int or size_t.
299299 * The keys must all be of the same size. */
300300 #define MDB_INTEGERKEY 0x08
301301 /** with #MDB_DUPSORT, sorted dup items have fixed size */
302302 #define MDB_DUPFIXED 0x10
303 /** with #MDB_DUPSORT, dups are numeric in native byte order */
303 /** with #MDB_DUPSORT, dups are #MDB_INTEGERKEY-style integers */
304304 #define MDB_INTEGERDUP 0x20
305305 /** with #MDB_DUPSORT, use reverse string dups */
306306 #define MDB_REVERSEDUP 0x40
515515 * and uses fewer mallocs, but loses protection from application bugs
516516 * like wild pointer writes and other bad updates into the database.
517517 * Incompatible with nested transactions.
518 * Processes with and without MDB_WRITEMAP on the same environment do
519 * not cooperate well.
518 * Do not mix processes with and without MDB_WRITEMAP on the same
519 * environment. This can defeat durability (#mdb_env_sync etc).
520520 * <li>#MDB_NOMETASYNC
521521 * Flush system buffers to disk only once per transaction, omit the
522522 * metadata flush. Defer that until the system flushes files to disk,
587587 * reserved in that case.
588588 * This flag may be changed at any time using #mdb_env_set_flags().
589589 * </ul>
590 * @param[in] mode The UNIX permissions to set on created files. This parameter
591 * is ignored on Windows.
590 * @param[in] mode The UNIX permissions to set on created files and semaphores.
591 * This parameter is ignored on Windows.
592592 * @return A non-zero error value on failure and 0 on success. Some possible
593593 * errors are:
594594 * <ul>
697697 * Data is always written to disk when #mdb_txn_commit() is called,
698698 * but the operating system may keep it buffered. LMDB always flushes
699699 * the OS buffers upon commit as well, unless the environment was
700 * opened with #MDB_NOSYNC or in part #MDB_NOMETASYNC.
700 * opened with #MDB_NOSYNC or in part #MDB_NOMETASYNC. This call is
701 * not valid if the environment was opened with #MDB_RDONLY.
701702 * @param[in] env An environment handle returned by #mdb_env_create()
702703 * @param[in] force If non-zero, force a synchronous flush. Otherwise
703704 * if the environment has the #MDB_NOSYNC flag set the flushes
705706 * @return A non-zero error value on failure and 0 on success. Some possible
706707 * errors are:
707708 * <ul>
709 * <li>EACCES - the environment is read-only.
708710 * <li>EINVAL - an invalid parameter was specified.
709711 * <li>EIO - an error occurred during synchronization.
710712 * </ul>
10181020 * The database handle may be discarded by calling #mdb_dbi_close().
10191021 * The old database handle is returned if the database was already open.
10201022 * The handle may only be closed once.
1023 *
10211024 * The database handle will be private to the current transaction until
10221025 * the transaction is successfully committed. If the transaction is
10231026 * aborted the handle will be closed automatically.
1024 * After a successful commit the
1025 * handle will reside in the shared environment, and may be used
1026 * by other transactions. This function must not be called from
1027 * multiple concurrent transactions. A transaction that uses this function
1028 * must finish (either commit or abort) before any other transaction may
1029 * use this function.
1027 * After a successful commit the handle will reside in the shared
1028 * environment, and may be used by other transactions.
1029 *
1030 * This function must not be called from multiple concurrent
1031 * transactions in the same process. A transaction that uses
1032 * this function must finish (either commit or abort) before
1033 * any other transaction in the process may use this function.
10301034 *
10311035 * To use named databases (with name != NULL), #mdb_env_set_maxdbs()
10321036 * must be called before opening the environment. Database names
10471051 * keys may have multiple data items, stored in sorted order.) By default
10481052 * keys must be unique and may have only a single data item.
10491053 * <li>#MDB_INTEGERKEY
1050 * Keys are binary integers in native byte order. Setting this option
1051 * requires all keys to be the same size, typically sizeof(int)
1052 * or sizeof(size_t).
1054 * Keys are binary integers in native byte order, either unsigned int
1055 * or size_t, and will be sorted as such.
1056 * The keys must all be of the same size.
10531057 * <li>#MDB_DUPFIXED
10541058 * This flag may only be used in combination with #MDB_DUPSORT. This option
10551059 * tells the library that the data items for this database are all the same
10571061 * all data items are the same size, the #MDB_GET_MULTIPLE and #MDB_NEXT_MULTIPLE
10581062 * cursor operations may be used to retrieve multiple items at once.
10591063 * <li>#MDB_INTEGERDUP
1060 * This option specifies that duplicate data items are also integers, and
1061 * should be sorted as such.
1064 * This option specifies that duplicate data items are binary integers,
1065 * similar to #MDB_INTEGERKEY keys.
10621066 * <li>#MDB_REVERSEDUP
10631067 * This option specifies that duplicate data items should be compared as
10641068 * strings in reverse order.
12691273 * LMDB does nothing else with this memory, the caller is expected
12701274 * to modify all of the space requested.
12711275 * <li>#MDB_APPEND - append the given key/data pair to the end of the
1272 * database. No key comparisons are performed. This option allows
1273 * fast bulk loading when keys are already known to be in the
1274 * correct order. Loading unsorted keys with this flag will cause
1275 * data corruption.
1276 * database. This option allows fast bulk loading when keys are
1277 * already known to be in the correct order. Loading unsorted keys
1278 * with this flag will cause a #MDB_KEYEXIST error.
12761279 * <li>#MDB_APPENDDUP - as above, but for sorted dup data.
12771280 * </ul>
12781281 * @return A non-zero error value on failure and 0 on success. Some possible
14481451 * <ul>
14491452 * <li>#MDB_MAP_FULL - the database is full, see #mdb_env_set_mapsize().
14501453 * <li>#MDB_TXN_FULL - the transaction has too many dirty pages.
1451 * <li>EACCES - an attempt was made to modify a read-only database.
1454 * <li>EACCES - an attempt was made to write in a read-only transaction.
14521455 * <li>EINVAL - an invalid parameter was specified.
14531456 * </ul>
14541457 */
14681471 * @return A non-zero error value on failure and 0 on success. Some possible
14691472 * errors are:
14701473 * <ul>
1471 * <li>EACCES - an attempt was made to modify a read-only database.
1474 * <li>EACCES - an attempt was made to write in a read-only transaction.
14721475 * <li>EINVAL - an invalid parameter was specified.
14731476 * </ul>
14741477 */
44 * BerkeleyDB API, but much simplified.
55 */
66 /*
7 * Copyright 2011-2014 Howard Chu, Symas Corp.
7 * Copyright 2011-2015 Howard Chu, Symas Corp.
88 * All rights reserved.
99 *
1010 * Redistribution and use in source and binary forms, with or without
7878 #define CACHEFLUSH(addr, bytes, cache)
7979 #endif
8080
81 #if defined(__linux) && !defined(MDB_FDATASYNC_WORKS)
82 /** fdatasync is broken on ext3/ext4fs on older kernels, see
83 * description in #mdb_env_open2 comments. You can safely
84 * define MDB_FDATASYNC_WORKS if this code will only be run
85 * on kernels 3.6 and newer.
86 */
87 #define BROKEN_FDATASYNC
88 #endif
8189
8290 #include <errno.h>
8391 #include <limits.h>
8997 #include <time.h>
9098 #include <unistd.h>
9199
92 #if defined(__sun)
100 #if defined(__sun) || defined(ANDROID)
93101 /* Most platforms have posix_memalign, older may only have memalign */
94102 #define HAVE_MEMALIGN 1
95103 #include <malloc.h>
437445 /** The version number for a database's lockfile format. */
438446 #define MDB_LOCK_VERSION 1
439447
440 /** @brief The max size of a key we can write, or 0 for dynamic max.
448 /** @brief The max size of a key we can write, or 0 for computed max.
441449 *
442 * Define this as 0 to compute the max from the page size. 511
443 * is default for backwards compat: liblmdb <= 0.9.10 can break
444 * when modifying a DB with keys/dupsort data bigger than its max.
445 * #MDB_DEVEL sets the default to 0.
450 * This macro should normally be left alone or set to 0.
451 * Note that a database with big keys or dupsort data cannot be
452 * reliably modified by a liblmdb which uses a smaller max.
453 * The default is 511 for backwards compat, or 0 when #MDB_DEVEL.
454 *
455 * Other values are allowed, for backwards compat. However:
456 * A value bigger than the computed max can break if you do not
457 * know what you are doing, and liblmdb <= 0.9.10 can break when
458 * modifying a DB with keys/dupsort data bigger than its max.
446459 *
447460 * Data items in an #MDB_DUPSORT database are also limited to
448461 * this size, since they're actually keys of a sub-DB. Keys and
579592 * started from so we can avoid overwriting any data used in that
580593 * particular version.
581594 */
582 txnid_t mrb_txnid;
595 volatile txnid_t mrb_txnid;
583596 /** The process ID of the process owning this reader txn. */
584 MDB_PID_T mrb_pid;
597 volatile MDB_PID_T mrb_pid;
585598 /** The thread ID of the thread owning this txn. */
586 MDB_THR_T mrb_tid;
599 volatile MDB_THR_T mrb_tid;
587600 } MDB_rxbody;
588601
589602 /** The actual reader record, with cacheline padding. */
631644 * This is recorded here only for convenience; the value can always
632645 * be determined by reading the main database meta pages.
633646 */
634 txnid_t mtb_txnid;
647 volatile txnid_t mtb_txnid;
635648 /** The number of slots that have been used in the reader table.
636649 * This always records the maximum count, it is not decremented
637650 * when readers release their slots.
638651 */
639 unsigned mtb_numreaders;
652 volatile unsigned mtb_numreaders;
640653 } MDB_txbody;
641654
642655 /** The actual reader table definition. */
897910 /** Stamp identifying this as an LMDB file. It must be set
898911 * to #MDB_MAGIC. */
899912 uint32_t mm_magic;
900 /** Version number of this lock file. Must be set to #MDB_DATA_VERSION. */
913 /** Version number of this file. Must be set to #MDB_DATA_VERSION. */
901914 uint32_t mm_version;
902915 void *mm_address; /**< address for fixed mapping */
903916 size_t mm_mapsize; /**< size of mmap region */
907920 /** Any persistent environment flags. @ref mdb_env */
908921 #define mm_flags mm_dbs[0].md_flags
909922 pgno_t mm_last_pg; /**< last used page in file */
910 txnid_t mm_txnid; /**< txnid that committed this page */
923 volatile txnid_t mm_txnid; /**< txnid that committed this page */
911924 } MDB_meta;
912925
913926 /** Buffer for a stack-allocated meta page.
10951108 #define MDB_ENV_ACTIVE 0x20000000U
10961109 /** me_txkey is set */
10971110 #define MDB_ENV_TXKEY 0x10000000U
1111 /** fdatasync is unreliable */
1112 #define MDB_FSYNCONLY 0x08000000U
10981113 uint32_t me_flags; /**< @ref mdb_env */
10991114 unsigned int me_psize; /**< DB page size, inited from me_os_psize */
11001115 unsigned int me_os_psize; /**< OS page size, from #GET_PAGESIZE */
12341249 static MDB_cmp_func mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long;
12351250 /** @endcond */
12361251
1252 /** Compare two items pointing at size_t's of unknown alignment. */
1253 #ifdef MISALIGNED_OK
1254 # define mdb_cmp_clong mdb_cmp_long
1255 #else
1256 # define mdb_cmp_clong mdb_cmp_cint
1257 #endif
1258
12371259 #ifdef _WIN32
12381260 static SECURITY_DESCRIPTOR mdb_null_sd;
12391261 static SECURITY_ATTRIBUTES mdb_all_sa;
13151337 buf[0] = 0;
13161338 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
13171339 FORMAT_MESSAGE_IGNORE_INSERTS,
1318 NULL, err, 0, ptr, sizeof(buf), pad);
1340 NULL, err, 0, ptr, sizeof(buf), (va_list *)pad);
13191341 return ptr;
13201342 #else
13211343 return strerror(err);
15471569 int
15481570 mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
15491571 {
1550 return txn->mt_dbxs[dbi].md_dcmp(a, b);
1572 MDB_cmp_func *dcmp = txn->mt_dbxs[dbi].md_dcmp;
1573 #if UINT_MAX < SIZE_MAX
1574 if (dcmp == mdb_cmp_int && a->mv_size == sizeof(size_t))
1575 dcmp = mdb_cmp_clong;
1576 #endif
1577 return dcmp(a, b);
15511578 }
15521579
15531580 /** Allocate memory for a page.
23012328 mdb_env_sync(MDB_env *env, int force)
23022329 {
23032330 int rc = 0;
2331 if (env->me_flags & MDB_RDONLY)
2332 return EACCES;
23042333 if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) {
23052334 if (env->me_flags & MDB_WRITEMAP) {
23062335 int flags = ((env->me_flags & MDB_MAPASYNC) && !force)
23122341 rc = ErrCode();
23132342 #endif
23142343 } else {
2344 #ifdef BROKEN_FDATASYNC
2345 if (env->me_flags & MDB_FSYNCONLY) {
2346 if (fsync(env->me_fd))
2347 rc = ErrCode();
2348 } else
2349 #endif
23152350 if (MDB_FDATASYNC(env->me_fd))
23162351 rc = ErrCode();
23172352 }
24672502 MDB_env *env = txn->mt_env;
24682503 MDB_txninfo *ti = env->me_txns;
24692504 MDB_meta *meta;
2470 unsigned int i, nr;
2505 unsigned int i, nr, flags = txn->mt_flags;
24712506 uint16_t x;
24722507 int rc, new_notls = 0;
24732508
2474 /* Setup db info */
2475 txn->mt_numdbs = env->me_numdbs;
2476 txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */
2477
2478 if (txn->mt_flags & MDB_TXN_RDONLY) {
2509 if ((flags &= MDB_TXN_RDONLY) != 0) {
24792510 if (!ti) {
24802511 meta = env->me_metas[ mdb_env_pick_meta(env) ];
24812512 txn->mt_txnid = meta->mm_txnid;
25212552 return rc;
25222553 }
25232554 }
2524 txn->mt_txnid = r->mr_txnid = ti->mti_txnid;
2555 do /* LY: Retry on a race, ITS#7970. */
2556 r->mr_txnid = ti->mti_txnid;
2557 while(r->mr_txnid != ti->mti_txnid);
2558 txn->mt_txnid = r->mr_txnid;
25252559 txn->mt_u.reader = r;
25262560 meta = env->me_metas[txn->mt_txnid & 1];
25272561 }
2562 txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */
25282563 } else {
25292564 if (ti) {
25302565 LOCK_MUTEX_W(env);
25402575 if (txn->mt_txnid == mdb_debug_start)
25412576 mdb_debug = 1;
25422577 #endif
2578 txn->mt_child = NULL;
2579 txn->mt_loose_pgs = NULL;
2580 txn->mt_loose_count = 0;
25432581 txn->mt_dirty_room = MDB_IDL_UM_MAX;
25442582 txn->mt_u.dirty_list = env->me_dirty_list;
25452583 txn->mt_u.dirty_list[0].mid = 0;
25562594 /* Moved to here to avoid a data race in read TXNs */
25572595 txn->mt_next_pgno = meta->mm_last_pg+1;
25582596
2597 txn->mt_flags = flags;
2598
2599 /* Setup db info */
2600 txn->mt_numdbs = env->me_numdbs;
25592601 for (i=2; i<txn->mt_numdbs; i++) {
25602602 x = env->me_dbflags[i];
25612603 txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS;
26212663 }
26222664 tsize = sizeof(MDB_ntxn);
26232665 }
2624 size = tsize + env->me_maxdbs * (sizeof(MDB_db)+1);
2666 size = tsize;
26252667 if (!(flags & MDB_RDONLY)) {
26262668 if (!parent) {
2627 txn = env->me_txn0;
2628 txn->mt_flags = 0;
2669 txn = env->me_txn0; /* just reuse preallocated write txn */
26292670 goto ok;
26302671 }
2672 /* child txns use own copy of cursors */
26312673 size += env->me_maxdbs * sizeof(MDB_cursor *);
2632 /* child txns use parent's dbiseqs */
2633 if (!parent)
2634 size += env->me_maxdbs * sizeof(unsigned int);
2635 }
2674 }
2675 size += env->me_maxdbs * (sizeof(MDB_db)+1);
26362676
26372677 if ((txn = calloc(1, size)) == NULL) {
26382678 DPRINTF(("calloc: %s", strerror(errno)));
27732813 txn->mt_numdbs = 0; /* close nothing if called again */
27742814 txn->mt_dbxs = NULL; /* mark txn as reset */
27752815 } else {
2816 pgno_t *pghead = env->me_pghead;
2817
27762818 mdb_cursors_close(txn, 0);
2777
27782819 if (!(env->me_flags & MDB_WRITEMAP)) {
27792820 mdb_dlist_free(txn);
27802821 }
2781 mdb_midl_free(env->me_pghead);
2782
2783 if (txn->mt_parent) {
2822
2823 if (!txn->mt_parent) {
2824 if (mdb_midl_shrink(&txn->mt_free_pgs))
2825 env->me_free_pgs = txn->mt_free_pgs;
2826 /* me_pgstate: */
2827 env->me_pghead = NULL;
2828 env->me_pglast = 0;
2829
2830 env->me_txn = NULL;
2831 /* The writer mutex was locked in mdb_txn_begin. */
2832 if (env->me_txns)
2833 UNLOCK_MUTEX_W(env);
2834 } else {
27842835 txn->mt_parent->mt_child = NULL;
27852836 env->me_pgstate = ((MDB_ntxn *)txn)->mnt_pgstate;
27862837 mdb_midl_free(txn->mt_free_pgs);
27872838 mdb_midl_free(txn->mt_spill_pgs);
27882839 free(txn->mt_u.dirty_list);
2789 return;
2790 }
2791
2792 if (mdb_midl_shrink(&txn->mt_free_pgs))
2793 env->me_free_pgs = txn->mt_free_pgs;
2794 env->me_pghead = NULL;
2795 env->me_pglast = 0;
2796
2797 env->me_txn = NULL;
2798 /* The writer mutex was locked in mdb_txn_begin. */
2799 if (env->me_txns)
2800 UNLOCK_MUTEX_W(env);
2840 }
2841
2842 mdb_midl_free(pghead);
28012843 }
28022844 }
28032845
31053147 /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
31063148 if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
31073149 if (n) {
3150 retry_write:
31083151 /* Write previous page(s) */
31093152 #ifdef MDB_USE_PWRITEV
31103153 wres = pwritev(env->me_fd, iov, n, wpos);
31123155 if (n == 1) {
31133156 wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
31143157 } else {
3158 retry_seek:
31153159 if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
31163160 rc = ErrCode();
3161 if (rc == EINTR)
3162 goto retry_seek;
31173163 DPRINTF(("lseek: %s", strerror(rc)));
31183164 return rc;
31193165 }
31233169 if (wres != wsize) {
31243170 if (wres < 0) {
31253171 rc = ErrCode();
3172 if (rc == EINTR)
3173 goto retry_write;
31263174 DPRINTF(("Write error: %s", strerror(rc)));
31273175 } else {
31283176 rc = EIO; /* TODO: Use which error code? */
34923540 int len;
34933541 #define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \
34943542 len = pwrite(fd, ptr, size, pos); \
3495 rc = (len >= 0); } while(0)
3543 if (len == -1 && ErrCode() == EINTR) continue; \
3544 rc = (len >= 0); break; } while(1)
34963545 #endif
34973546
34983547 DPUTS("writing new meta page");
35973646 /* Write to the SYNC fd */
35983647 mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
35993648 env->me_fd : env->me_mfd;
3649 retry_write:
36003650 #ifdef _WIN32
36013651 {
36023652 memset(&ov, 0, sizeof(ov));
36093659 #endif
36103660 if (rc != len) {
36113661 rc = rc < 0 ? ErrCode() : EIO;
3662 if (rc == EINTR)
3663 goto retry_write;
36123664 DPUTS("write failed, disk error?");
36133665 /* On a failure, the pagecache still contains the new data.
36143666 * Write some old data back, to prevent it from being used.
38233875 return MDB_SUCCESS;
38243876 }
38253877
3878 static int ESECT
3879 mdb_fsize(HANDLE fd, size_t *size)
3880 {
3881 #ifdef _WIN32
3882 LARGE_INTEGER fsize;
3883
3884 if (!GetFileSizeEx(fd, &fsize))
3885 return ErrCode();
3886
3887 *size = fsize.QuadPart;
3888 #else
3889 struct stat st;
3890
3891 if (fstat(fd, &st))
3892 return ErrCode();
3893
3894 *size = st.st_size;
3895 #endif
3896 return MDB_SUCCESS;
3897 }
3898
3899 #ifdef BROKEN_FDATASYNC
3900 #include <sys/utsname.h>
3901 #include <sys/vfs.h>
3902 #endif
3903
38263904 /** Further setup required for opening an LMDB environment
38273905 */
38283906 static int ESECT
38403918 else
38413919 env->me_pidquery = PROCESS_QUERY_INFORMATION;
38423920 #endif /* _WIN32 */
3921 #ifdef BROKEN_FDATASYNC
3922 /* ext3/ext4 fdatasync is broken on some older Linux kernels.
3923 * https://lkml.org/lkml/2012/9/3/83
3924 * Kernels after 3.6-rc6 are known good.
3925 * https://lkml.org/lkml/2012/9/10/556
3926 * See if the DB is on ext3/ext4, then check for new enough kernel
3927 * Kernels 2.6.32.60, 2.6.34.15, 3.2.30, and 3.5.4 are also known
3928 * to be patched.
3929 */
3930 {
3931 struct statfs st;
3932 fstatfs(env->me_fd, &st);
3933 while (st.f_type == 0xEF53) {
3934 struct utsname uts;
3935 int i;
3936 uname(&uts);
3937 if (uts.release[0] < '3') {
3938 if (!strncmp(uts.release, "2.6.32.", 7)) {
3939 i = atoi(uts.release+7);
3940 if (i >= 60)
3941 break; /* 2.6.32.60 and newer is OK */
3942 } else if (!strncmp(uts.release, "2.6.34.", 7)) {
3943 i = atoi(uts.release+7);
3944 if (i >= 15)
3945 break; /* 2.6.34.15 and newer is OK */
3946 }
3947 } else if (uts.release[0] == '3') {
3948 i = atoi(uts.release+2);
3949 if (i > 5)
3950 break; /* 3.6 and newer is OK */
3951 if (i == 5) {
3952 i = atoi(uts.release+4);
3953 if (i >= 4)
3954 break; /* 3.5.4 and newer is OK */
3955 } else if (i == 2) {
3956 i = atoi(uts.release+4);
3957 if (i >= 30)
3958 break; /* 3.2.30 and newer is OK */
3959 }
3960 } else { /* 4.x and newer is OK */
3961 break;
3962 }
3963 env->me_flags |= MDB_FSYNCONLY;
3964 break;
3965 }
3966 }
3967 #endif
38433968
38443969 memset(&meta, 0, sizeof(meta));
38453970
39714096 extern const PIMAGE_TLS_CALLBACK mdb_tls_cbp;
39724097 const PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
39734098 #pragma const_seg()
3974 #else /* WIN32 */
4099 #else /* _WIN32 */
39754100 #pragma comment(linker, "/INCLUDE:__tls_used")
39764101 #pragma comment(linker, "/INCLUDE:_mdb_tls_cbp")
39774102 #pragma data_seg(".CRT$XLB")
40214146 return rc;
40224147 }
40234148
4024 /** Try to get exlusive lock, otherwise shared.
4149 /** Try to get exclusive lock, otherwise shared.
40254150 * Maintain *excl = -1: no/unknown lock, 0: shared, 1: exclusive.
40264151 */
40274152 static int ESECT
41624287 * @param[in] env The LMDB environment.
41634288 * @param[in] lpath The pathname of the file used for the lock region.
41644289 * @param[in] mode The Unix permissions for the file, if we create it.
4165 * @param[out] excl Resulting file lock type: -1 none, 0 shared, 1 exclusive
41664290 * @param[in,out] excl In -1, out lock type: -1 none, 0 shared, 1 exclusive
41674291 * @return 0 on success, non-zero on failure.
41684292 */
45174641 if (!(flags & MDB_RDONLY)) {
45184642 MDB_txn *txn;
45194643 int tsize = sizeof(MDB_txn), size = tsize + env->me_maxdbs *
4520 (sizeof(MDB_db)+sizeof(MDB_cursor)+sizeof(unsigned int)+1);
4644 (sizeof(MDB_db)+sizeof(MDB_cursor *)+sizeof(unsigned int)+1);
45214645 txn = calloc(1, size);
45224646 if (txn) {
45234647 txn->mt_dbs = (MDB_db *)((char *)txn + tsize);
45254649 txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
45264650 txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
45274651 txn->mt_env = env;
4652 txn->mt_dbxs = env->me_dbxs;
45284653 env->me_txn0 = txn;
45294654 } else {
45304655 rc = ENOMEM;
45504675 return;
45514676
45524677 /* Doing this here since me_dbxs may not exist during mdb_env_close */
4553 for (i = env->me_maxdbs; --i > MAIN_DBI; )
4554 free(env->me_dbxs[i].md_name.mv_data);
4678 if (env->me_dbxs) {
4679 for (i = env->me_maxdbs; --i > MAIN_DBI; )
4680 free(env->me_dbxs[i].md_name.mv_data);
4681 free(env->me_dbxs);
4682 }
45554683
45564684 free(env->me_pbuf);
45574685 free(env->me_dbiseqs);
45584686 free(env->me_dbflags);
4559 free(env->me_dbxs);
45604687 free(env->me_path);
45614688 free(env->me_dirty_list);
45624689 free(env->me_txn0);
46594786 *(size_t *)a->mv_data > *(size_t *)b->mv_data;
46604787 }
46614788
4662 /** Compare two items pointing at aligned unsigned int's */
4789 /** Compare two items pointing at aligned unsigned int's.
4790 *
4791 * This is also set as #MDB_INTEGERDUP|#MDB_DUPFIXED's #MDB_dbx.%md_dcmp,
4792 * but #mdb_cmp_clong() is called instead if the data type is size_t.
4793 */
46634794 static int
46644795 mdb_cmp_int(const MDB_val *a, const MDB_val *b)
46654796 {
46964827 return x;
46974828 #endif
46984829 }
4699
4700 /** Compare two items pointing at size_t's of unknown alignment. */
4701 #ifdef MISALIGNED_OK
4702 # define mdb_cmp_clong mdb_cmp_long
4703 #else
4704 # define mdb_cmp_clong mdb_cmp_cint
4705 #endif
47064830
47074831 /** Compare two items lexically */
47084832 static int
54235547 }
54245548 return rc;
54255549 }
5426 } else {
5427 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5428 if (op == MDB_PREV_DUP)
5429 return MDB_NOTFOUND;
5430 }
5550 }
5551 } else {
5552 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5553 if (op == MDB_PREV_DUP)
5554 return MDB_NOTFOUND;
54315555 }
54325556 }
54335557
56395763 return rc;
56405764 }
56415765 } else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) {
5642 MDB_val d2;
5643 if ((rc = mdb_node_read(mc->mc_txn, leaf, &d2)) != MDB_SUCCESS)
5766 MDB_val olddata;
5767 MDB_cmp_func *dcmp;
5768 if ((rc = mdb_node_read(mc->mc_txn, leaf, &olddata)) != MDB_SUCCESS)
56445769 return rc;
5645 rc = mc->mc_dbx->md_dcmp(data, &d2);
5770 dcmp = mc->mc_dbx->md_dcmp;
5771 #if UINT_MAX < SIZE_MAX
5772 if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
5773 dcmp = mdb_cmp_clong;
5774 #endif
5775 rc = dcmp(data, &olddata);
56465776 if (rc) {
56475777 if (op == MDB_GET_BOTH || rc > 0)
56485778 return MDB_NOTFOUND;
56495779 rc = 0;
5650 *data = d2;
5780 *data = olddata;
56515781 }
56525782
56535783 } else {
61576287
61586288 /* Was a single item before, must convert now */
61596289 if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
6290 MDB_cmp_func *dcmp;
61606291 /* Just overwrite the current item */
61616292 if (flags == MDB_CURRENT)
61626293 goto current;
6163
6294 dcmp = mc->mc_dbx->md_dcmp;
61646295 #if UINT_MAX < SIZE_MAX
6165 if (mc->mc_dbx->md_dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
6166 mc->mc_dbx->md_dcmp = mdb_cmp_clong;
6296 if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
6297 dcmp = mdb_cmp_clong;
61676298 #endif
61686299 /* does data match? */
6169 if (!mc->mc_dbx->md_dcmp(data, &olddata)) {
6300 if (!dcmp(data, &olddata)) {
61706301 if (flags & MDB_NODUPDATA)
61716302 return MDB_KEYEXIST;
61726303 /* overwrite it */
69867117 mc->mc_snum = 0;
69877118 mc->mc_top = 0;
69887119 mc->mc_pg[0] = 0;
7120 mc->mc_ki[0] = 0;
69897121 mc->mc_flags = 0;
69907122 if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
69917123 mdb_tassert(txn, mx != NULL);
73597491 cdst->mc_ki[cdst->mc_top] = 0;
73607492 rc = mdb_update_key(cdst, &nullkey);
73617493 cdst->mc_ki[cdst->mc_top] = ix;
7362 mdb_cassert(csrc, rc == MDB_SUCCESS);
7494 mdb_cassert(cdst, rc == MDB_SUCCESS);
73637495 }
73647496 }
73657497
76157747 m3 = m2;
76167748 if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
76177749 if (m3->mc_pg[0] == mp) {
7618 m3->mc_snum--;
7619 m3->mc_top--;
76207750 for (i=0; i<m3->mc_snum; i++) {
76217751 m3->mc_pg[i] = m3->mc_pg[i+1];
76227752 m3->mc_ki[i] = m3->mc_ki[i+1];
76237753 }
7754 m3->mc_snum--;
7755 m3->mc_top--;
76247756 }
76257757 }
76267758 }
76887820 if (mc->mc_ki[ptop] == 0) {
76897821 rc = mdb_page_merge(&mn, mc);
76907822 } else {
7823 MDB_cursor dummy;
76917824 oldki += NUMKEYS(mn.mc_pg[mn.mc_top]);
76927825 mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
7826 /* We want mdb_rebalance to find mn when doing fixups */
7827 if (mc->mc_flags & C_SUB) {
7828 dummy.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi];
7829 mc->mc_txn->mt_cursors[mc->mc_dbi] = &dummy;
7830 dummy.mc_xcursor = (MDB_xcursor *)&mn;
7831 } else {
7832 mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi];
7833 mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn;
7834 }
76937835 rc = mdb_page_merge(mc, &mn);
7836 if (mc->mc_flags & C_SUB)
7837 mc->mc_txn->mt_cursors[mc->mc_dbi] = dummy.mc_next;
7838 else
7839 mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next;
76947840 mdb_cursor_copy(&mn, mc);
76957841 }
76967842 mc->mc_flags &= ~C_EOF;
77167862 if (rc == MDB_SUCCESS) {
77177863 MDB_cursor *m2, *m3;
77187864 MDB_dbi dbi = mc->mc_dbi;
7865
7866 /* DB is totally empty now, just bail out.
7867 * Other cursors adjustments were already done
7868 * by mdb_rebalance and aren't needed here.
7869 */
7870 if (!mc->mc_snum)
7871 return rc;
77197872
77207873 mp = mc->mc_pg[mc->mc_top];
77217874 nkeys = NUMKEYS(mp);
85848737 /* Set metapage 1 */
85858738 mm->mm_last_pg = txn->mt_next_pgno - freecount - 1;
85868739 mm->mm_dbs[1] = txn->mt_dbs[1];
8587 mm->mm_dbs[1].md_root = mm->mm_last_pg;
8588 mm->mm_txnid = 1;
8740 if (mm->mm_last_pg > 1) {
8741 mm->mm_dbs[1].md_root = mm->mm_last_pg;
8742 mm->mm_txnid = 1;
8743 } else {
8744 mm->mm_dbs[1].md_root = P_INVALID;
8745 }
85898746 }
85908747 my.mc_wlen[0] = env->me_psize * 2;
85918748 my.mc_txn = txn;
86808837 goto leave;
86818838
86828839 w2 = txn->mt_next_pgno * env->me_psize;
8683 #ifdef WIN32
86848840 {
8685 LARGE_INTEGER fsize;
8686 GetFileSizeEx(env->me_fd, &fsize);
8687 if (w2 > fsize.QuadPart)
8688 w2 = fsize.QuadPart;
8689 }
8690 #else
8691 {
8692 struct stat st;
8693 fstat(env->me_fd, &st);
8694 if (w2 > (size_t)st.st_size)
8695 w2 = st.st_size;
8696 }
8697 #endif
8841 size_t fsize = 0;
8842 if ((rc = mdb_fsize(env->me_fd, &fsize)))
8843 goto leave;
8844 if (w2 > fsize)
8845 w2 = fsize;
8846 }
86988847 wsize = w2 - wsize;
86998848 while (wsize > 0) {
87008849 if (wsize > MAX_WRITE)
00 .TH MDB_COPY 1 "2014/06/20" "LMDB 0.9.14"
1 .\" Copyright 2012-2014 Howard Chu, Symas Corp. All Rights Reserved.
1 .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
22 .\" Copying restrictions apply. See COPYRIGHT/LICENSE.
33 .SH NAME
44 mdb_copy \- LMDB environment copy tool
00 /* mdb_copy.c - memory-mapped database backup tool */
11 /*
2 * Copyright 2012 Howard Chu, Symas Corp.
2 * Copyright 2012-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
6363 act = "opening environment";
6464 rc = mdb_env_create(&env);
6565 if (rc == MDB_SUCCESS) {
66 rc = mdb_env_open(env, argv[1], flags, 0664);
66 rc = mdb_env_open(env, argv[1], flags, 0600);
6767 }
6868 if (rc == MDB_SUCCESS) {
6969 act = "copying";
00 .TH MDB_DUMP 1 "2014/06/20" "LMDB 0.9.14"
1 .\" Copyright 2014 Howard Chu, Symas Corp. All Rights Reserved.
1 .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
22 .\" Copying restrictions apply. See COPYRIGHT/LICENSE.
33 .SH NAME
44 mdb_dump \- LMDB environment export tool
00 /* mdb_dump.c - memory-mapped database dump tool */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
00 .TH MDB_LOAD 1 "2014/06/20" "LMDB 0.9.14"
1 .\" Copyright 2014 Howard Chu, Symas Corp. All Rights Reserved.
1 .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
22 .\" Copying restrictions apply. See COPYRIGHT/LICENSE.
33 .SH NAME
44 mdb_load \- LMDB environment import tool
00 /* mdb_load.c - memory-mapped database load tool */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
175175 static int readline(MDB_val *out, MDB_val *buf)
176176 {
177177 unsigned char *c1, *c2, *end;
178 size_t len;
178 size_t len, l2;
179179 int c;
180180
181181 if (!(mode & NOHDR)) {
205205
206206 c1 = buf->mv_data;
207207 len = strlen((char *)c1);
208 l2 = len;
208209
209210 /* Is buffer too short? */
210211 while (c1[len-1] != '\n') {
216217 return EOF;
217218 }
218219 c1 = buf->mv_data;
219 c1 += buf->mv_size;
220 if (fgets((char *)c1, buf->mv_size, stdin) == NULL) {
220 c1 += l2;
221 if (fgets((char *)c1, buf->mv_size+1, stdin) == NULL) {
221222 Eof = 1;
222223 badend();
223224 return EOF;
224225 }
225226 buf->mv_size *= 2;
226227 len = strlen((char *)c1);
228 l2 += len;
227229 }
228230 c1 = c2 = buf->mv_data;
229 len = strlen((char *)c1);
231 len = l2;
230232 c1[--len] = '\0';
231233 end = c1 + len;
232234
00 .TH MDB_STAT 1 "2014/06/20" "LMDB 0.9.14"
1 .\" Copyright 2012-2014 Howard Chu, Symas Corp. All Rights Reserved.
1 .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
22 .\" Copying restrictions apply. See COPYRIGHT/LICENSE.
33 .SH NAME
44 mdb_stat \- LMDB environment status tool
00 /* mdb_stat.c - memory-mapped database status tool */
11 /*
2 * Copyright 2011-2013 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
22 /* $OpenLDAP$ */
33 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
44 *
5 * Copyright 2000-2014 The OpenLDAP Foundation.
5 * Copyright 2000-2015 The OpenLDAP Foundation.
66 * All rights reserved.
77 *
88 * Redistribution and use in source and binary forms, with or without
1010 /* $OpenLDAP$ */
1111 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
1212 *
13 * Copyright 2000-2014 The OpenLDAP Foundation.
13 * Copyright 2000-2015 The OpenLDAP Foundation.
1414 * All rights reserved.
1515 *
1616 * Redistribution and use in source and binary forms, with or without
00 /* mtest.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
4444 }
4545
4646 E(mdb_env_create(&env));
47 E(mdb_env_set_maxreaders(env, 1));
4748 E(mdb_env_set_mapsize(env, 10485760));
4849 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));
50
4951 E(mdb_txn_begin(env, NULL, 0, &txn));
50 E(mdb_open(txn, NULL, 0, &dbi));
52 E(mdb_dbi_open(txn, NULL, 0, &dbi));
5153
5254 key.mv_size = sizeof(int);
5355 key.mv_data = sval;
54 data.mv_size = sizeof(sval);
55 data.mv_data = sval;
5656
5757 printf("Adding %d values\n", count);
5858 for (i=0;i<count;i++) {
5959 sprintf(sval, "%03x %d foo bar", values[i], values[i]);
60 /* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */
61 data.mv_size = sizeof(sval);
62 data.mv_data = sval;
6063 if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {
6164 j++;
6265 data.mv_size = sizeof(sval);
6770 E(mdb_txn_commit(txn));
6871 E(mdb_env_stat(env, &mst));
6972
70 E(mdb_txn_begin(env, NULL, 1, &txn));
73 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
7174 E(mdb_cursor_open(txn, dbi, &cursor));
7275 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
7376 printf("key: %p %.*s, data: %p %.*s\n",
9699 printf("Deleted %d values\n", j);
97100
98101 E(mdb_env_stat(env, &mst));
99 E(mdb_txn_begin(env, NULL, 1, &txn));
102 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
100103 E(mdb_cursor_open(txn, dbi, &cursor));
101104 printf("Cursor next\n");
102105 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
127130 (int) key.mv_size, (char *) key.mv_data,
128131 (int) data.mv_size, (char *) data.mv_data);
129132
133 mdb_cursor_close(cursor);
130134 mdb_txn_abort(txn);
131135
132136 printf("Deleting with cursor\n");
163167 data.mv_data, (int) data.mv_size, (char *) data.mv_data);
164168 }
165169 mdb_cursor_close(cursor);
166 mdb_close(env, dbi);
170 mdb_txn_abort(txn);
167171
168 mdb_txn_abort(txn);
172 mdb_dbi_close(env, dbi);
169173 mdb_env_close(env);
170174
171175 return 0;
00 /* mtest2.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
4646 }
4747
4848 E(mdb_env_create(&env));
49 E(mdb_env_set_maxreaders(env, 1));
4950 E(mdb_env_set_mapsize(env, 10485760));
5051 E(mdb_env_set_maxdbs(env, 4));
5152 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
53
5254 E(mdb_txn_begin(env, NULL, 0, &txn));
53 E(mdb_open(txn, "id1", MDB_CREATE, &dbi));
55 E(mdb_dbi_open(txn, "id1", MDB_CREATE, &dbi));
5456
5557 key.mv_size = sizeof(int);
5658 key.mv_data = sval;
57 data.mv_size = sizeof(sval);
58 data.mv_data = sval;
5959
6060 printf("Adding %d values\n", count);
6161 for (i=0;i<count;i++) {
6262 sprintf(sval, "%03x %d foo bar", values[i], values[i]);
63 data.mv_size = sizeof(sval);
64 data.mv_data = sval;
6365 if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE)))
6466 j++;
6567 }
6769 E(mdb_txn_commit(txn));
6870 E(mdb_env_stat(env, &mst));
6971
70 E(mdb_txn_begin(env, NULL, 1, &txn));
72 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
7173 E(mdb_cursor_open(txn, dbi, &cursor));
7274 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
7375 printf("key: %p %.*s, data: %p %.*s\n",
9698 printf("Deleted %d values\n", j);
9799
98100 E(mdb_env_stat(env, &mst));
99 E(mdb_txn_begin(env, NULL, 1, &txn));
101 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
100102 E(mdb_cursor_open(txn, dbi, &cursor));
101103 printf("Cursor next\n");
102104 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
113115 }
114116 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
115117 mdb_cursor_close(cursor);
116 mdb_close(env, dbi);
118 mdb_txn_abort(txn);
117119
118 mdb_txn_abort(txn);
120 mdb_dbi_close(env, dbi);
119121 mdb_env_close(env);
120
121122 return 0;
122123 }
00 /* mtest3.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
5252 E(mdb_env_set_mapsize(env, 10485760));
5353 E(mdb_env_set_maxdbs(env, 4));
5454 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
55
5556 E(mdb_txn_begin(env, NULL, 0, &txn));
56 E(mdb_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
57 E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
5758
5859 key.mv_size = sizeof(int);
5960 key.mv_data = kval;
7273 E(mdb_txn_commit(txn));
7374 E(mdb_env_stat(env, &mst));
7475
75 E(mdb_txn_begin(env, NULL, 1, &txn));
76 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
7677 E(mdb_cursor_open(txn, dbi, &cursor));
7778 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
7879 printf("key: %p %.*s, data: %p %.*s\n",
106107 printf("Deleted %d values\n", j);
107108
108109 E(mdb_env_stat(env, &mst));
109 E(mdb_txn_begin(env, NULL, 1, &txn));
110 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
110111 E(mdb_cursor_open(txn, dbi, &cursor));
111112 printf("Cursor next\n");
112113 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
123124 }
124125 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
125126 mdb_cursor_close(cursor);
126 mdb_close(env, dbi);
127 mdb_txn_abort(txn);
127128
128 mdb_txn_abort(txn);
129 mdb_dbi_close(env, dbi);
129130 mdb_env_close(env);
130
131131 return 0;
132132 }
00 /* mtest4.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
5050 E(mdb_env_set_mapsize(env, 10485760));
5151 E(mdb_env_set_maxdbs(env, 4));
5252 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
53
5354 E(mdb_txn_begin(env, NULL, 0, &txn));
54 E(mdb_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi));
55 E(mdb_dbi_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi));
5556
5657 key.mv_size = sizeof(int);
5758 key.mv_data = kval;
7172
7273 /* there should be one full page of dups now.
7374 */
74 E(mdb_txn_begin(env, NULL, 1, &txn));
75 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
7576 E(mdb_cursor_open(txn, dbi, &cursor));
7677 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
7778 printf("key: %p %.*s, data: %p %.*s\n",
141142 printf("Deleted %d values\n", j);
142143
143144 E(mdb_env_stat(env, &mst));
144 E(mdb_txn_begin(env, NULL, 1, &txn));
145 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
145146 E(mdb_cursor_open(txn, dbi, &cursor));
146147 printf("Cursor next\n");
147148 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
158159 }
159160 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
160161 mdb_cursor_close(cursor);
161 mdb_close(env, dbi);
162 mdb_txn_abort(txn);
162163
163 mdb_txn_abort(txn);
164 mdb_dbi_close(env, dbi);
164165 mdb_env_close(env);
165
166166 return 0;
167167 }
00 /* mtest5.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
5252 E(mdb_env_set_mapsize(env, 10485760));
5353 E(mdb_env_set_maxdbs(env, 4));
5454 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
55
5556 E(mdb_txn_begin(env, NULL, 0, &txn));
56 E(mdb_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
57 E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
5758 E(mdb_cursor_open(txn, dbi, &cursor));
5859
5960 key.mv_size = sizeof(int);
7475 E(mdb_txn_commit(txn));
7576 E(mdb_env_stat(env, &mst));
7677
77 E(mdb_txn_begin(env, NULL, 1, &txn));
78 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
7879 E(mdb_cursor_open(txn, dbi, &cursor));
7980 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
8081 printf("key: %p %.*s, data: %p %.*s\n",
108109 printf("Deleted %d values\n", j);
109110
110111 E(mdb_env_stat(env, &mst));
111 E(mdb_txn_begin(env, NULL, 1, &txn));
112 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
112113 E(mdb_cursor_open(txn, dbi, &cursor));
113114 printf("Cursor next\n");
114115 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
125126 }
126127 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
127128 mdb_cursor_close(cursor);
128 mdb_close(env, dbi);
129 mdb_txn_abort(txn);
129130
130 mdb_txn_abort(txn);
131 mdb_dbi_close(env, dbi);
131132 mdb_env_close(env);
132
133133 return 0;
134134 }
00 /* mtest6.c - memory-mapped database tester/toy */
11 /*
2 * Copyright 2011-2014 Howard Chu, Symas Corp.
2 * Copyright 2011-2015 Howard Chu, Symas Corp.
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
3030 int i = 0, j = 0, rc;
3131 MDB_env *env;
3232 MDB_dbi dbi;
33 MDB_val key, data;
33 MDB_val key, data, sdata;
3434 MDB_txn *txn;
3535 MDB_stat mst;
3636 MDB_cursor *cursor;
4545 E(mdb_env_set_mapsize(env, 10485760));
4646 E(mdb_env_set_maxdbs(env, 4));
4747 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
48
4849 E(mdb_txn_begin(env, NULL, 0, &txn));
49 E(mdb_open(txn, "id6", MDB_CREATE|MDB_INTEGERKEY, &dbi));
50 E(mdb_dbi_open(txn, "id6", MDB_CREATE|MDB_INTEGERKEY, &dbi));
5051 E(mdb_cursor_open(txn, dbi, &cursor));
5152 E(mdb_stat(txn, dbi, &mst));
5253
5354 sval = calloc(1, mst.ms_psize / 4);
5455 key.mv_size = sizeof(long);
5556 key.mv_data = &kval;
56 data.mv_size = mst.ms_psize / 4 - 30;
57 data.mv_data = sval;
57 sdata.mv_size = mst.ms_psize / 4 - 30;
58 sdata.mv_data = sval;
5859
5960 printf("Adding 12 values, should yield 3 splits\n");
6061 for (i=0;i<12;i++) {
6162 kval = i*5;
6263 sprintf(sval, "%08x", kval);
64 data = sdata;
6365 (void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
6466 }
6567 printf("Adding 12 more values, should yield 3 splits\n");
6668 for (i=0;i<12;i++) {
6769 kval = i*5+4;
6870 sprintf(sval, "%08x", kval);
71 data = sdata;
6972 (void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
7073 }
7174 printf("Adding 12 more values, should yield 3 splits\n");
7275 for (i=0;i<12;i++) {
7376 kval = i*5+1;
7477 sprintf(sval, "%08x", kval);
78 data = sdata;
7579 (void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
7680 }
7781 E(mdb_cursor_get(cursor, &key, &data, MDB_FIRST));
109113 printf("Deleted %d values\n", j);
110114
111115 E(mdb_env_stat(env, &mst));
112 E(mdb_txn_begin(env, NULL, 1, &txn));
116 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
113117 E(mdb_cursor_open(txn, dbi, &cursor));
114118 printf("Cursor next\n");
115119 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
126130 }
127131 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
128132 mdb_cursor_close(cursor);
129 mdb_close(env, dbi);
133 mdb_txn_abort(txn);
130134
131 mdb_txn_abort(txn);
135 mdb_dbi_close(env, dbi);
132136 #endif
133137 mdb_env_close(env);
134138
22 * Do a line-by-line comparison of this and sample-mdb.txt
33 */
44 /*
5 * Copyright 2012 Howard Chu, Symas Corp.
5 * Copyright 2012-2015 Howard Chu, Symas Corp.
66 * All rights reserved.
77 *
88 * Redistribution and use in source and binary forms, with or without
22 * Do a line-by-line comparison of this and sample-bdb.txt
33 */
44 /*
5 * Copyright 2012 Howard Chu, Symas Corp.
5 * Copyright 2012-2015 Howard Chu, Symas Corp.
66 * All rights reserved.
77 *
88 * Redistribution and use in source and binary forms, with or without
3131 rc = mdb_env_create(&env);
3232 rc = mdb_env_open(env, "./testdb", 0, 0664);
3333 rc = mdb_txn_begin(env, NULL, 0, &txn);
34 rc = mdb_open(txn, NULL, 0, &dbi);
34 rc = mdb_dbi_open(txn, NULL, 0, &dbi);
3535
3636 key.mv_size = sizeof(int);
3737 key.mv_data = sval;
5555 mdb_cursor_close(cursor);
5656 mdb_txn_abort(txn);
5757 leave:
58 mdb_close(env, dbi);
58 mdb_dbi_close(env, dbi);
5959 mdb_env_close(env);
6060 return 0;
6161 }