]> git.sur5r.net Git - openldap/blob - libraries/liblmdb/mdb.c
Hack for potential ext3/ext4 corruption issue
[openldap] / libraries / liblmdb / mdb.c
1 /** @file mdb.c
2  *      @brief Lightning memory-mapped database library
3  *
4  *      A Btree-based database management library modeled loosely on the
5  *      BerkeleyDB API, but much simplified.
6  */
7 /*
8  * Copyright 2011-2014 Howard Chu, Symas Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted only as authorized by the OpenLDAP
13  * Public License.
14  *
15  * A copy of this license is available in the file LICENSE in the
16  * top-level directory of the distribution or, alternatively, at
17  * <http://www.OpenLDAP.org/license.html>.
18  *
19  * This code is derived from btree.c written by Martin Hedenfalk.
20  *
21  * Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
22  *
23  * Permission to use, copy, modify, and distribute this software for any
24  * purpose with or without fee is hereby granted, provided that the above
25  * copyright notice and this permission notice appear in all copies.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
28  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
29  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
30  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
32  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
33  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34  */
35 #ifndef _GNU_SOURCE
36 #define _GNU_SOURCE 1
37 #endif
38 #ifdef _WIN32
39 #include <malloc.h>
40 #include <windows.h>
41 /** getpid() returns int; MinGW defines pid_t but MinGW64 typedefs it
42  *  as int64 which is wrong. MSVC doesn't define it at all, so just
43  *  don't use it.
44  */
45 #define MDB_PID_T       int
46 #define MDB_THR_T       DWORD
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #ifdef __GNUC__
50 # include <sys/param.h>
51 #else
52 # define LITTLE_ENDIAN  1234
53 # define BIG_ENDIAN     4321
54 # define BYTE_ORDER     LITTLE_ENDIAN
55 # ifndef SSIZE_MAX
56 #  define SSIZE_MAX     INT_MAX
57 # endif
58 #endif
59 #else
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #define MDB_PID_T       pid_t
63 #define MDB_THR_T       pthread_t
64 #include <sys/param.h>
65 #include <sys/uio.h>
66 #include <sys/mman.h>
67 #ifdef HAVE_SYS_FILE_H
68 #include <sys/file.h>
69 #endif
70 #include <fcntl.h>
71 #endif
72
73 #if defined(__mips) && defined(__linux)
74 /* MIPS has cache coherency issues, requires explicit cache control */
75 #include <asm/cachectl.h>
76 extern int cacheflush(char *addr, int nbytes, int cache);
77 #define CACHEFLUSH(addr, bytes, cache)  cacheflush(addr, bytes, cache)
78 #else
79 #define CACHEFLUSH(addr, bytes, cache)
80 #endif
81
82
83 #include <errno.h>
84 #include <limits.h>
85 #include <stddef.h>
86 #include <inttypes.h>
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <time.h>
91 #include <unistd.h>
92
93 #if defined(__sun) || defined(ANDROID)
94 /* Most platforms have posix_memalign, older may only have memalign */
95 #define HAVE_MEMALIGN   1
96 #include <malloc.h>
97 #endif
98
99 #if !(defined(BYTE_ORDER) || defined(__BYTE_ORDER))
100 #include <netinet/in.h>
101 #include <resolv.h>     /* defines BYTE_ORDER on HPUX and Solaris */
102 #endif
103
104 #if defined(__APPLE__) || defined (BSD)
105 # define MDB_USE_POSIX_SEM      1
106 # define MDB_FDATASYNC          fsync
107 #elif defined(ANDROID)
108 # define MDB_FDATASYNC          fsync
109 #endif
110
111 #ifndef _WIN32
112 #include <pthread.h>
113 #ifdef MDB_USE_POSIX_SEM
114 # define MDB_USE_HASH           1
115 #include <semaphore.h>
116 #endif
117 #endif
118
119 #ifdef USE_VALGRIND
120 #include <valgrind/memcheck.h>
121 #define VGMEMP_CREATE(h,r,z)    VALGRIND_CREATE_MEMPOOL(h,r,z)
122 #define VGMEMP_ALLOC(h,a,s) VALGRIND_MEMPOOL_ALLOC(h,a,s)
123 #define VGMEMP_FREE(h,a) VALGRIND_MEMPOOL_FREE(h,a)
124 #define VGMEMP_DESTROY(h)       VALGRIND_DESTROY_MEMPOOL(h)
125 #define VGMEMP_DEFINED(a,s)     VALGRIND_MAKE_MEM_DEFINED(a,s)
126 #else
127 #define VGMEMP_CREATE(h,r,z)
128 #define VGMEMP_ALLOC(h,a,s)
129 #define VGMEMP_FREE(h,a)
130 #define VGMEMP_DESTROY(h)
131 #define VGMEMP_DEFINED(a,s)
132 #endif
133
134 #ifndef BYTE_ORDER
135 # if (defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN))
136 /* Solaris just defines one or the other */
137 #  define LITTLE_ENDIAN 1234
138 #  define BIG_ENDIAN    4321
139 #  ifdef _LITTLE_ENDIAN
140 #   define BYTE_ORDER  LITTLE_ENDIAN
141 #  else
142 #   define BYTE_ORDER  BIG_ENDIAN
143 #  endif
144 # else
145 #  define BYTE_ORDER   __BYTE_ORDER
146 # endif
147 #endif
148
149 #ifndef LITTLE_ENDIAN
150 #define LITTLE_ENDIAN   __LITTLE_ENDIAN
151 #endif
152 #ifndef BIG_ENDIAN
153 #define BIG_ENDIAN      __BIG_ENDIAN
154 #endif
155
156 #if defined(__i386) || defined(__x86_64) || defined(_M_IX86)
157 #define MISALIGNED_OK   1
158 #endif
159
160 #include "lmdb.h"
161 #include "midl.h"
162
163 #if (BYTE_ORDER == LITTLE_ENDIAN) == (BYTE_ORDER == BIG_ENDIAN)
164 # error "Unknown or unsupported endianness (BYTE_ORDER)"
165 #elif (-6 & 5) || CHAR_BIT != 8 || UINT_MAX < 0xffffffff || ULONG_MAX % 0xFFFF
166 # error "Two's complement, reasonably sized integer types, please"
167 #endif
168
169 #ifdef __GNUC__
170 /** Put infrequently used env functions in separate section */
171 # ifdef __APPLE__
172 #  define       ESECT   __attribute__ ((section("__TEXT,text_env")))
173 # else
174 #  define       ESECT   __attribute__ ((section("text_env")))
175 # endif
176 #else
177 #define ESECT
178 #endif
179
180 /** @defgroup internal  LMDB Internals
181  *      @{
182  */
183 /** @defgroup compat    Compatibility Macros
184  *      A bunch of macros to minimize the amount of platform-specific ifdefs
185  *      needed throughout the rest of the code. When the features this library
186  *      needs are similar enough to POSIX to be hidden in a one-or-two line
187  *      replacement, this macro approach is used.
188  *      @{
189  */
190
191         /** Features under development */
192 #ifndef MDB_DEVEL
193 #define MDB_DEVEL 0
194 #endif
195
196         /** Wrapper around __func__, which is a C99 feature */
197 #if __STDC_VERSION__ >= 199901L
198 # define mdb_func_      __func__
199 #elif __GNUC__ >= 2 || _MSC_VER >= 1300
200 # define mdb_func_      __FUNCTION__
201 #else
202 /* If a debug message says <mdb_unknown>(), update the #if statements above */
203 # define mdb_func_      "<mdb_unknown>"
204 #endif
205
206 #ifdef _WIN32
207 #define MDB_USE_HASH    1
208 #define MDB_PIDLOCK     0
209 #define THREAD_RET      DWORD
210 #define pthread_t       HANDLE
211 #define pthread_mutex_t HANDLE
212 #define pthread_cond_t  HANDLE
213 #define pthread_key_t   DWORD
214 #define pthread_self()  GetCurrentThreadId()
215 #define pthread_key_create(x,y) \
216         ((*(x) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? ErrCode() : 0)
217 #define pthread_key_delete(x)   TlsFree(x)
218 #define pthread_getspecific(x)  TlsGetValue(x)
219 #define pthread_setspecific(x,y)        (TlsSetValue(x,y) ? 0 : ErrCode())
220 #define pthread_mutex_unlock(x) ReleaseMutex(*x)
221 #define pthread_mutex_lock(x)   WaitForSingleObject(*x, INFINITE)
222 #define pthread_cond_signal(x)  SetEvent(*x)
223 #define pthread_cond_wait(cond,mutex)   do{SignalObjectAndWait(*mutex, *cond, INFINITE, FALSE); WaitForSingleObject(*mutex, INFINITE);}while(0)
224 #define THREAD_CREATE(thr,start,arg)    thr=CreateThread(NULL,0,start,arg,0,NULL)
225 #define THREAD_FINISH(thr)      WaitForSingleObject(thr, INFINITE)
226 #define LOCK_MUTEX_R(env)       pthread_mutex_lock(&(env)->me_rmutex)
227 #define UNLOCK_MUTEX_R(env)     pthread_mutex_unlock(&(env)->me_rmutex)
228 #define LOCK_MUTEX_W(env)       pthread_mutex_lock(&(env)->me_wmutex)
229 #define UNLOCK_MUTEX_W(env)     pthread_mutex_unlock(&(env)->me_wmutex)
230 #define getpid()        GetCurrentProcessId()
231 #define MDB_FDATASYNC(fd)       (!FlushFileBuffers(fd))
232 #define MDB_MSYNC(addr,len,flags)       (!FlushViewOfFile(addr,len))
233 #define ErrCode()       GetLastError()
234 #define GET_PAGESIZE(x) {SYSTEM_INFO si; GetSystemInfo(&si); (x) = si.dwPageSize;}
235 #define close(fd)       (CloseHandle(fd) ? 0 : -1)
236 #define munmap(ptr,len) UnmapViewOfFile(ptr)
237 #ifdef PROCESS_QUERY_LIMITED_INFORMATION
238 #define MDB_PROCESS_QUERY_LIMITED_INFORMATION PROCESS_QUERY_LIMITED_INFORMATION
239 #else
240 #define MDB_PROCESS_QUERY_LIMITED_INFORMATION 0x1000
241 #endif
242 #define Z       "I"
243 #else
244 #define THREAD_RET      void *
245 #define THREAD_CREATE(thr,start,arg)    pthread_create(&thr,NULL,start,arg)
246 #define THREAD_FINISH(thr)      pthread_join(thr,NULL)
247 #define Z       "z"                     /**< printf format modifier for size_t */
248
249         /** For MDB_LOCK_FORMAT: True if readers take a pid lock in the lockfile */
250 #define MDB_PIDLOCK                     1
251
252 #ifdef MDB_USE_POSIX_SEM
253
254 #define LOCK_MUTEX_R(env)       mdb_sem_wait((env)->me_rmutex)
255 #define UNLOCK_MUTEX_R(env)     sem_post((env)->me_rmutex)
256 #define LOCK_MUTEX_W(env)       mdb_sem_wait((env)->me_wmutex)
257 #define UNLOCK_MUTEX_W(env)     sem_post((env)->me_wmutex)
258
259 static int
260 mdb_sem_wait(sem_t *sem)
261 {
262    int rc;
263    while ((rc = sem_wait(sem)) && (rc = errno) == EINTR) ;
264    return rc;
265 }
266
267 #else
268         /** Lock the reader mutex.
269          */
270 #define LOCK_MUTEX_R(env)       pthread_mutex_lock(&(env)->me_txns->mti_mutex)
271         /** Unlock the reader mutex.
272          */
273 #define UNLOCK_MUTEX_R(env)     pthread_mutex_unlock(&(env)->me_txns->mti_mutex)
274
275         /** Lock the writer mutex.
276          *      Only a single write transaction is allowed at a time. Other writers
277          *      will block waiting for this mutex.
278          */
279 #define LOCK_MUTEX_W(env)       pthread_mutex_lock(&(env)->me_txns->mti_wmutex)
280         /** Unlock the writer mutex.
281          */
282 #define UNLOCK_MUTEX_W(env)     pthread_mutex_unlock(&(env)->me_txns->mti_wmutex)
283 #endif  /* MDB_USE_POSIX_SEM */
284
285         /** Get the error code for the last failed system function.
286          */
287 #define ErrCode()       errno
288
289         /** An abstraction for a file handle.
290          *      On POSIX systems file handles are small integers. On Windows
291          *      they're opaque pointers.
292          */
293 #define HANDLE  int
294
295         /**     A value for an invalid file handle.
296          *      Mainly used to initialize file variables and signify that they are
297          *      unused.
298          */
299 #define INVALID_HANDLE_VALUE    (-1)
300
301         /** Get the size of a memory page for the system.
302          *      This is the basic size that the platform's memory manager uses, and is
303          *      fundamental to the use of memory-mapped files.
304          */
305 #define GET_PAGESIZE(x) ((x) = sysconf(_SC_PAGE_SIZE))
306 #endif
307
308 #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
309 #define MNAME_LEN       32
310 #else
311 #define MNAME_LEN       (sizeof(pthread_mutex_t))
312 #endif
313
314 /** @} */
315
316 #ifndef _WIN32
317 /**     A flag for opening a file and requesting synchronous data writes.
318  *      This is only used when writing a meta page. It's not strictly needed;
319  *      we could just do a normal write and then immediately perform a flush.
320  *      But if this flag is available it saves us an extra system call.
321  *
322  *      @note If O_DSYNC is undefined but exists in /usr/include,
323  * preferably set some compiler flag to get the definition.
324  * Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC.
325  */
326 #ifndef MDB_DSYNC
327 # define MDB_DSYNC      O_DSYNC
328 #endif
329 #endif
330
331 /** Function for flushing the data of a file. Define this to fsync
332  *      if fdatasync() is not supported.
333  */
334 #ifndef MDB_FDATASYNC
335 # define MDB_FDATASYNC  fdatasync
336 # define HAVE_FDATASYNC 1
337 #endif
338
339 #ifndef MDB_MSYNC
340 # define MDB_MSYNC(addr,len,flags)      msync(addr,len,flags)
341 #endif
342
343 #ifndef MS_SYNC
344 #define MS_SYNC 1
345 #endif
346
347 #ifndef MS_ASYNC
348 #define MS_ASYNC        0
349 #endif
350
351         /** A page number in the database.
352          *      Note that 64 bit page numbers are overkill, since pages themselves
353          *      already represent 12-13 bits of addressable memory, and the OS will
354          *      always limit applications to a maximum of 63 bits of address space.
355          *
356          *      @note In the #MDB_node structure, we only store 48 bits of this value,
357          *      which thus limits us to only 60 bits of addressable data.
358          */
359 typedef MDB_ID  pgno_t;
360
361         /** A transaction ID.
362          *      See struct MDB_txn.mt_txnid for details.
363          */
364 typedef MDB_ID  txnid_t;
365
366 /** @defgroup debug     Debug Macros
367  *      @{
368  */
369 #ifndef MDB_DEBUG
370         /**     Enable debug output.  Needs variable argument macros (a C99 feature).
371          *      Set this to 1 for copious tracing. Set to 2 to add dumps of all IDLs
372          *      read from and written to the database (used for free space management).
373          */
374 #define MDB_DEBUG 0
375 #endif
376
377 #if MDB_DEBUG
378 static int mdb_debug;
379 static txnid_t mdb_debug_start;
380
381         /**     Print a debug message with printf formatting.
382          *      Requires double parenthesis around 2 or more args.
383          */
384 # define DPRINTF(args) ((void) ((mdb_debug) && DPRINTF0 args))
385 # define DPRINTF0(fmt, ...) \
386         fprintf(stderr, "%s:%d " fmt "\n", mdb_func_, __LINE__, __VA_ARGS__)
387 #else
388 # define DPRINTF(args)  ((void) 0)
389 #endif
390         /**     Print a debug string.
391          *      The string is printed literally, with no format processing.
392          */
393 #define DPUTS(arg)      DPRINTF(("%s", arg))
394         /** Debuging output value of a cursor DBI: Negative in a sub-cursor. */
395 #define DDBI(mc) \
396         (((mc)->mc_flags & C_SUB) ? -(int)(mc)->mc_dbi : (int)(mc)->mc_dbi)
397 /** @} */
398
399         /**     @brief The maximum size of a database page.
400          *
401          *      It is 32k or 64k, since value-PAGEBASE must fit in
402          *      #MDB_page.%mp_upper.
403          *
404          *      LMDB will use database pages < OS pages if needed.
405          *      That causes more I/O in write transactions: The OS must
406          *      know (read) the whole page before writing a partial page.
407          *
408          *      Note that we don't currently support Huge pages. On Linux,
409          *      regular data files cannot use Huge pages, and in general
410          *      Huge pages aren't actually pageable. We rely on the OS
411          *      demand-pager to read our data and page it out when memory
412          *      pressure from other processes is high. So until OSs have
413          *      actual paging support for Huge pages, they're not viable.
414          */
415 #define MAX_PAGESIZE     (PAGEBASE ? 0x10000 : 0x8000)
416
417         /** The minimum number of keys required in a database page.
418          *      Setting this to a larger value will place a smaller bound on the
419          *      maximum size of a data item. Data items larger than this size will
420          *      be pushed into overflow pages instead of being stored directly in
421          *      the B-tree node. This value used to default to 4. With a page size
422          *      of 4096 bytes that meant that any item larger than 1024 bytes would
423          *      go into an overflow page. That also meant that on average 2-3KB of
424          *      each overflow page was wasted space. The value cannot be lower than
425          *      2 because then there would no longer be a tree structure. With this
426          *      value, items larger than 2KB will go into overflow pages, and on
427          *      average only 1KB will be wasted.
428          */
429 #define MDB_MINKEYS      2
430
431         /**     A stamp that identifies a file as an LMDB file.
432          *      There's nothing special about this value other than that it is easily
433          *      recognizable, and it will reflect any byte order mismatches.
434          */
435 #define MDB_MAGIC        0xBEEFC0DE
436
437         /**     The version number for a database's datafile format. */
438 #define MDB_DATA_VERSION         ((MDB_DEVEL) ? 999 : 1)
439         /**     The version number for a database's lockfile format. */
440 #define MDB_LOCK_VERSION         1
441
442         /**     @brief The max size of a key we can write, or 0 for dynamic max.
443          *
444          *      Define this as 0 to compute the max from the page size.  511
445          *      is default for backwards compat: liblmdb <= 0.9.10 can break
446          *      when modifying a DB with keys/dupsort data bigger than its max.
447          *      #MDB_DEVEL sets the default to 0.
448          *
449          *      Data items in an #MDB_DUPSORT database are also limited to
450          *      this size, since they're actually keys of a sub-DB.  Keys and
451          *      #MDB_DUPSORT data items must fit on a node in a regular page.
452          */
453 #ifndef MDB_MAXKEYSIZE
454 #define MDB_MAXKEYSIZE   ((MDB_DEVEL) ? 0 : 511)
455 #endif
456
457         /**     The maximum size of a key we can write to the environment. */
458 #if MDB_MAXKEYSIZE
459 #define ENV_MAXKEY(env) (MDB_MAXKEYSIZE)
460 #else
461 #define ENV_MAXKEY(env) ((env)->me_maxkey)
462 #endif
463
464         /**     @brief The maximum size of a data item.
465          *
466          *      We only store a 32 bit value for node sizes.
467          */
468 #define MAXDATASIZE     0xffffffffUL
469
470 #if MDB_DEBUG
471         /**     Key size which fits in a #DKBUF.
472          *      @ingroup debug
473          */
474 #define DKBUF_MAXKEYSIZE ((MDB_MAXKEYSIZE) > 0 ? (MDB_MAXKEYSIZE) : 511)
475         /**     A key buffer.
476          *      @ingroup debug
477          *      This is used for printing a hex dump of a key's contents.
478          */
479 #define DKBUF   char kbuf[DKBUF_MAXKEYSIZE*2+1]
480         /**     Display a key in hex.
481          *      @ingroup debug
482          *      Invoke a function to display a key in hex.
483          */
484 #define DKEY(x) mdb_dkey(x, kbuf)
485 #else
486 #define DKBUF
487 #define DKEY(x) 0
488 #endif
489
490         /** An invalid page number.
491          *      Mainly used to denote an empty tree.
492          */
493 #define P_INVALID        (~(pgno_t)0)
494
495         /** Test if the flags \b f are set in a flag word \b w. */
496 #define F_ISSET(w, f)    (((w) & (f)) == (f))
497
498         /** Round \b n up to an even number. */
499 #define EVEN(n)         (((n) + 1U) & -2) /* sign-extending -2 to match n+1U */
500
501         /**     Used for offsets within a single page.
502          *      Since memory pages are typically 4 or 8KB in size, 12-13 bits,
503          *      this is plenty.
504          */
505 typedef uint16_t         indx_t;
506
507         /**     Default size of memory map.
508          *      This is certainly too small for any actual applications. Apps should always set
509          *      the size explicitly using #mdb_env_set_mapsize().
510          */
511 #define DEFAULT_MAPSIZE 1048576
512
513 /**     @defgroup readers       Reader Lock Table
514  *      Readers don't acquire any locks for their data access. Instead, they
515  *      simply record their transaction ID in the reader table. The reader
516  *      mutex is needed just to find an empty slot in the reader table. The
517  *      slot's address is saved in thread-specific data so that subsequent read
518  *      transactions started by the same thread need no further locking to proceed.
519  *
520  *      If #MDB_NOTLS is set, the slot address is not saved in thread-specific data.
521  *
522  *      No reader table is used if the database is on a read-only filesystem, or
523  *      if #MDB_NOLOCK is set.
524  *
525  *      Since the database uses multi-version concurrency control, readers don't
526  *      actually need any locking. This table is used to keep track of which
527  *      readers are using data from which old transactions, so that we'll know
528  *      when a particular old transaction is no longer in use. Old transactions
529  *      that have discarded any data pages can then have those pages reclaimed
530  *      for use by a later write transaction.
531  *
532  *      The lock table is constructed such that reader slots are aligned with the
533  *      processor's cache line size. Any slot is only ever used by one thread.
534  *      This alignment guarantees that there will be no contention or cache
535  *      thrashing as threads update their own slot info, and also eliminates
536  *      any need for locking when accessing a slot.
537  *
538  *      A writer thread will scan every slot in the table to determine the oldest
539  *      outstanding reader transaction. Any freed pages older than this will be
540  *      reclaimed by the writer. The writer doesn't use any locks when scanning
541  *      this table. This means that there's no guarantee that the writer will
542  *      see the most up-to-date reader info, but that's not required for correct
543  *      operation - all we need is to know the upper bound on the oldest reader,
544  *      we don't care at all about the newest reader. So the only consequence of
545  *      reading stale information here is that old pages might hang around a
546  *      while longer before being reclaimed. That's actually good anyway, because
547  *      the longer we delay reclaiming old pages, the more likely it is that a
548  *      string of contiguous pages can be found after coalescing old pages from
549  *      many old transactions together.
550  *      @{
551  */
552         /**     Number of slots in the reader table.
553          *      This value was chosen somewhat arbitrarily. 126 readers plus a
554          *      couple mutexes fit exactly into 8KB on my development machine.
555          *      Applications should set the table size using #mdb_env_set_maxreaders().
556          */
557 #define DEFAULT_READERS 126
558
559         /**     The size of a CPU cache line in bytes. We want our lock structures
560          *      aligned to this size to avoid false cache line sharing in the
561          *      lock table.
562          *      This value works for most CPUs. For Itanium this should be 128.
563          */
564 #ifndef CACHELINE
565 #define CACHELINE       64
566 #endif
567
568         /**     The information we store in a single slot of the reader table.
569          *      In addition to a transaction ID, we also record the process and
570          *      thread ID that owns a slot, so that we can detect stale information,
571          *      e.g. threads or processes that went away without cleaning up.
572          *      @note We currently don't check for stale records. We simply re-init
573          *      the table when we know that we're the only process opening the
574          *      lock file.
575          */
576 typedef struct MDB_rxbody {
577         /**     Current Transaction ID when this transaction began, or (txnid_t)-1.
578          *      Multiple readers that start at the same time will probably have the
579          *      same ID here. Again, it's not important to exclude them from
580          *      anything; all we need to know is which version of the DB they
581          *      started from so we can avoid overwriting any data used in that
582          *      particular version.
583          */
584         txnid_t         mrb_txnid;
585         /** The process ID of the process owning this reader txn. */
586         MDB_PID_T       mrb_pid;
587         /** The thread ID of the thread owning this txn. */
588         MDB_THR_T       mrb_tid;
589 } MDB_rxbody;
590
591         /** The actual reader record, with cacheline padding. */
592 typedef struct MDB_reader {
593         union {
594                 MDB_rxbody mrx;
595                 /** shorthand for mrb_txnid */
596 #define mr_txnid        mru.mrx.mrb_txnid
597 #define mr_pid  mru.mrx.mrb_pid
598 #define mr_tid  mru.mrx.mrb_tid
599                 /** cache line alignment */
600                 char pad[(sizeof(MDB_rxbody)+CACHELINE-1) & ~(CACHELINE-1)];
601         } mru;
602 } MDB_reader;
603
604         /** The header for the reader table.
605          *      The table resides in a memory-mapped file. (This is a different file
606          *      than is used for the main database.)
607          *
608          *      For POSIX the actual mutexes reside in the shared memory of this
609          *      mapped file. On Windows, mutexes are named objects allocated by the
610          *      kernel; we store the mutex names in this mapped file so that other
611          *      processes can grab them. This same approach is also used on
612          *      MacOSX/Darwin (using named semaphores) since MacOSX doesn't support
613          *      process-shared POSIX mutexes. For these cases where a named object
614          *      is used, the object name is derived from a 64 bit FNV hash of the
615          *      environment pathname. As such, naming collisions are extremely
616          *      unlikely. If a collision occurs, the results are unpredictable.
617          */
618 typedef struct MDB_txbody {
619                 /** Stamp identifying this as an LMDB file. It must be set
620                  *      to #MDB_MAGIC. */
621         uint32_t        mtb_magic;
622                 /** Format of this lock file. Must be set to #MDB_LOCK_FORMAT. */
623         uint32_t        mtb_format;
624 #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
625         char    mtb_rmname[MNAME_LEN];
626 #else
627                 /** Mutex protecting access to this table.
628                  *      This is the reader lock that #LOCK_MUTEX_R acquires.
629                  */
630         pthread_mutex_t mtb_mutex;
631 #endif
632                 /**     The ID of the last transaction committed to the database.
633                  *      This is recorded here only for convenience; the value can always
634                  *      be determined by reading the main database meta pages.
635                  */
636         txnid_t         mtb_txnid;
637                 /** The number of slots that have been used in the reader table.
638                  *      This always records the maximum count, it is not decremented
639                  *      when readers release their slots.
640                  */
641         unsigned        mtb_numreaders;
642 } MDB_txbody;
643
644         /** The actual reader table definition. */
645 typedef struct MDB_txninfo {
646         union {
647                 MDB_txbody mtb;
648 #define mti_magic       mt1.mtb.mtb_magic
649 #define mti_format      mt1.mtb.mtb_format
650 #define mti_mutex       mt1.mtb.mtb_mutex
651 #define mti_rmname      mt1.mtb.mtb_rmname
652 #define mti_txnid       mt1.mtb.mtb_txnid
653 #define mti_numreaders  mt1.mtb.mtb_numreaders
654                 char pad[(sizeof(MDB_txbody)+CACHELINE-1) & ~(CACHELINE-1)];
655         } mt1;
656         union {
657 #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
658                 char mt2_wmname[MNAME_LEN];
659 #define mti_wmname      mt2.mt2_wmname
660 #else
661                 pthread_mutex_t mt2_wmutex;
662 #define mti_wmutex      mt2.mt2_wmutex
663 #endif
664                 char pad[(MNAME_LEN+CACHELINE-1) & ~(CACHELINE-1)];
665         } mt2;
666         MDB_reader      mti_readers[1];
667 } MDB_txninfo;
668
669         /** Lockfile format signature: version, features and field layout */
670 #define MDB_LOCK_FORMAT \
671         ((uint32_t) \
672          ((MDB_LOCK_VERSION) \
673           /* Flags which describe functionality */ \
674           + (((MDB_PIDLOCK) != 0) << 16)))
675 /** @} */
676
677 /** Common header for all page types.
678  * Overflow records occupy a number of contiguous pages with no
679  * headers on any page after the first.
680  */
681 typedef struct MDB_page {
682 #define mp_pgno mp_p.p_pgno
683 #define mp_next mp_p.p_next
684         union {
685                 pgno_t          p_pgno; /**< page number */
686                 struct MDB_page *p_next; /**< for in-memory list of freed pages */
687         } mp_p;
688         uint16_t        mp_pad;
689 /**     @defgroup mdb_page      Page Flags
690  *      @ingroup internal
691  *      Flags for the page headers.
692  *      @{
693  */
694 #define P_BRANCH         0x01           /**< branch page */
695 #define P_LEAF           0x02           /**< leaf page */
696 #define P_OVERFLOW       0x04           /**< overflow page */
697 #define P_META           0x08           /**< meta page */
698 #define P_DIRTY          0x10           /**< dirty page, also set for #P_SUBP pages */
699 #define P_LEAF2          0x20           /**< for #MDB_DUPFIXED records */
700 #define P_SUBP           0x40           /**< for #MDB_DUPSORT sub-pages */
701 #define P_LOOSE          0x4000         /**< page was dirtied then freed, can be reused */
702 #define P_KEEP           0x8000         /**< leave this page alone during spill */
703 /** @} */
704         uint16_t        mp_flags;               /**< @ref mdb_page */
705 #define mp_lower        mp_pb.pb.pb_lower
706 #define mp_upper        mp_pb.pb.pb_upper
707 #define mp_pages        mp_pb.pb_pages
708         union {
709                 struct {
710                         indx_t          pb_lower;               /**< lower bound of free space */
711                         indx_t          pb_upper;               /**< upper bound of free space */
712                 } pb;
713                 uint32_t        pb_pages;       /**< number of overflow pages */
714         } mp_pb;
715         indx_t          mp_ptrs[1];             /**< dynamic size */
716 } MDB_page;
717
718         /** Size of the page header, excluding dynamic data at the end */
719 #define PAGEHDRSZ        ((unsigned) offsetof(MDB_page, mp_ptrs))
720
721         /** Address of first usable data byte in a page, after the header */
722 #define METADATA(p)      ((void *)((char *)(p) + PAGEHDRSZ))
723
724         /** ITS#7713, change PAGEBASE to handle 65536 byte pages */
725 #define PAGEBASE        ((MDB_DEVEL) ? PAGEHDRSZ : 0)
726
727         /** Number of nodes on a page */
728 #define NUMKEYS(p)       (((p)->mp_lower - (PAGEHDRSZ-PAGEBASE)) >> 1)
729
730         /** The amount of space remaining in the page */
731 #define SIZELEFT(p)      (indx_t)((p)->mp_upper - (p)->mp_lower)
732
733         /** The percentage of space used in the page, in tenths of a percent. */
734 #define PAGEFILL(env, p) (1000L * ((env)->me_psize - PAGEHDRSZ - SIZELEFT(p)) / \
735                                 ((env)->me_psize - PAGEHDRSZ))
736         /** The minimum page fill factor, in tenths of a percent.
737          *      Pages emptier than this are candidates for merging.
738          */
739 #define FILL_THRESHOLD   250
740
741         /** Test if a page is a leaf page */
742 #define IS_LEAF(p)       F_ISSET((p)->mp_flags, P_LEAF)
743         /** Test if a page is a LEAF2 page */
744 #define IS_LEAF2(p)      F_ISSET((p)->mp_flags, P_LEAF2)
745         /** Test if a page is a branch page */
746 #define IS_BRANCH(p)     F_ISSET((p)->mp_flags, P_BRANCH)
747         /** Test if a page is an overflow page */
748 #define IS_OVERFLOW(p)   F_ISSET((p)->mp_flags, P_OVERFLOW)
749         /** Test if a page is a sub page */
750 #define IS_SUBP(p)       F_ISSET((p)->mp_flags, P_SUBP)
751
752         /** The number of overflow pages needed to store the given size. */
753 #define OVPAGES(size, psize)    ((PAGEHDRSZ-1 + (size)) / (psize) + 1)
754
755         /** Link in #MDB_txn.%mt_loose_pgs list */
756 #define NEXT_LOOSE_PAGE(p)              (*(MDB_page **)((p) + 2))
757
758         /** Header for a single key/data pair within a page.
759          * Used in pages of type #P_BRANCH and #P_LEAF without #P_LEAF2.
760          * We guarantee 2-byte alignment for 'MDB_node's.
761          */
762 typedef struct MDB_node {
763         /** lo and hi are used for data size on leaf nodes and for
764          * child pgno on branch nodes. On 64 bit platforms, flags
765          * is also used for pgno. (Branch nodes have no flags).
766          * They are in host byte order in case that lets some
767          * accesses be optimized into a 32-bit word access.
768          */
769 #if BYTE_ORDER == LITTLE_ENDIAN
770         unsigned short  mn_lo, mn_hi;   /**< part of data size or pgno */
771 #else
772         unsigned short  mn_hi, mn_lo;
773 #endif
774 /** @defgroup mdb_node Node Flags
775  *      @ingroup internal
776  *      Flags for node headers.
777  *      @{
778  */
779 #define F_BIGDATA        0x01                   /**< data put on overflow page */
780 #define F_SUBDATA        0x02                   /**< data is a sub-database */
781 #define F_DUPDATA        0x04                   /**< data has duplicates */
782
783 /** valid flags for #mdb_node_add() */
784 #define NODE_ADD_FLAGS  (F_DUPDATA|F_SUBDATA|MDB_RESERVE|MDB_APPEND)
785
786 /** @} */
787         unsigned short  mn_flags;               /**< @ref mdb_node */
788         unsigned short  mn_ksize;               /**< key size */
789         char            mn_data[1];                     /**< key and data are appended here */
790 } MDB_node;
791
792         /** Size of the node header, excluding dynamic data at the end */
793 #define NODESIZE         offsetof(MDB_node, mn_data)
794
795         /** Bit position of top word in page number, for shifting mn_flags */
796 #define PGNO_TOPWORD ((pgno_t)-1 > 0xffffffffu ? 32 : 0)
797
798         /** Size of a node in a branch page with a given key.
799          *      This is just the node header plus the key, there is no data.
800          */
801 #define INDXSIZE(k)      (NODESIZE + ((k) == NULL ? 0 : (k)->mv_size))
802
803         /** Size of a node in a leaf page with a given key and data.
804          *      This is node header plus key plus data size.
805          */
806 #define LEAFSIZE(k, d)   (NODESIZE + (k)->mv_size + (d)->mv_size)
807
808         /** Address of node \b i in page \b p */
809 #define NODEPTR(p, i)    ((MDB_node *)((char *)(p) + (p)->mp_ptrs[i] + PAGEBASE))
810
811         /** Address of the key for the node */
812 #define NODEKEY(node)    (void *)((node)->mn_data)
813
814         /** Address of the data for a node */
815 #define NODEDATA(node)   (void *)((char *)(node)->mn_data + (node)->mn_ksize)
816
817         /** Get the page number pointed to by a branch node */
818 #define NODEPGNO(node) \
819         ((node)->mn_lo | ((pgno_t) (node)->mn_hi << 16) | \
820          (PGNO_TOPWORD ? ((pgno_t) (node)->mn_flags << PGNO_TOPWORD) : 0))
821         /** Set the page number in a branch node */
822 #define SETPGNO(node,pgno)      do { \
823         (node)->mn_lo = (pgno) & 0xffff; (node)->mn_hi = (pgno) >> 16; \
824         if (PGNO_TOPWORD) (node)->mn_flags = (pgno) >> PGNO_TOPWORD; } while(0)
825
826         /** Get the size of the data in a leaf node */
827 #define NODEDSZ(node)    ((node)->mn_lo | ((unsigned)(node)->mn_hi << 16))
828         /** Set the size of the data for a leaf node */
829 #define SETDSZ(node,size)       do { \
830         (node)->mn_lo = (size) & 0xffff; (node)->mn_hi = (size) >> 16;} while(0)
831         /** The size of a key in a node */
832 #define NODEKSZ(node)    ((node)->mn_ksize)
833
834         /** Copy a page number from src to dst */
835 #ifdef MISALIGNED_OK
836 #define COPY_PGNO(dst,src)      dst = src
837 #else
838 #if SIZE_MAX > 4294967295UL
839 #define COPY_PGNO(dst,src)      do { \
840         unsigned short *s, *d;  \
841         s = (unsigned short *)&(src);   \
842         d = (unsigned short *)&(dst);   \
843         *d++ = *s++;    \
844         *d++ = *s++;    \
845         *d++ = *s++;    \
846         *d = *s;        \
847 } while (0)
848 #else
849 #define COPY_PGNO(dst,src)      do { \
850         unsigned short *s, *d;  \
851         s = (unsigned short *)&(src);   \
852         d = (unsigned short *)&(dst);   \
853         *d++ = *s++;    \
854         *d = *s;        \
855 } while (0)
856 #endif
857 #endif
858         /** The address of a key in a LEAF2 page.
859          *      LEAF2 pages are used for #MDB_DUPFIXED sorted-duplicate sub-DBs.
860          *      There are no node headers, keys are stored contiguously.
861          */
862 #define LEAF2KEY(p, i, ks)      ((char *)(p) + PAGEHDRSZ + ((i)*(ks)))
863
864         /** Set the \b node's key into \b keyptr, if requested. */
865 #define MDB_GET_KEY(node, keyptr)       { if ((keyptr) != NULL) { \
866         (keyptr)->mv_size = NODEKSZ(node); (keyptr)->mv_data = NODEKEY(node); } }
867
868         /** Set the \b node's key into \b key. */
869 #define MDB_GET_KEY2(node, key) { key.mv_size = NODEKSZ(node); key.mv_data = NODEKEY(node); }
870
871         /** Information about a single database in the environment. */
872 typedef struct MDB_db {
873         uint32_t        md_pad;         /**< also ksize for LEAF2 pages */
874         uint16_t        md_flags;       /**< @ref mdb_dbi_open */
875         uint16_t        md_depth;       /**< depth of this tree */
876         pgno_t          md_branch_pages;        /**< number of internal pages */
877         pgno_t          md_leaf_pages;          /**< number of leaf pages */
878         pgno_t          md_overflow_pages;      /**< number of overflow pages */
879         size_t          md_entries;             /**< number of data items */
880         pgno_t          md_root;                /**< the root page of this tree */
881 } MDB_db;
882
883         /** mdb_dbi_open flags */
884 #define MDB_VALID       0x8000          /**< DB handle is valid, for me_dbflags */
885 #define PERSISTENT_FLAGS        (0xffff & ~(MDB_VALID))
886 #define VALID_FLAGS     (MDB_REVERSEKEY|MDB_DUPSORT|MDB_INTEGERKEY|MDB_DUPFIXED|\
887         MDB_INTEGERDUP|MDB_REVERSEDUP|MDB_CREATE)
888
889         /** Handle for the DB used to track free pages. */
890 #define FREE_DBI        0
891         /** Handle for the default DB. */
892 #define MAIN_DBI        1
893
894         /** Meta page content.
895          *      A meta page is the start point for accessing a database snapshot.
896          *      Pages 0-1 are meta pages. Transaction N writes meta page #(N % 2).
897          */
898 typedef struct MDB_meta {
899                 /** Stamp identifying this as an LMDB file. It must be set
900                  *      to #MDB_MAGIC. */
901         uint32_t        mm_magic;
902                 /** Version number of this file. Must be set to #MDB_DATA_VERSION. */
903         uint32_t        mm_version;
904         void            *mm_address;            /**< address for fixed mapping */
905         size_t          mm_mapsize;                     /**< size of mmap region */
906         MDB_db          mm_dbs[2];                      /**< first is free space, 2nd is main db */
907         /** The size of pages used in this DB */
908 #define mm_psize        mm_dbs[0].md_pad
909         /** Any persistent environment flags. @ref mdb_env */
910 #define mm_flags        mm_dbs[0].md_flags
911         pgno_t          mm_last_pg;                     /**< last used page in file */
912         txnid_t         mm_txnid;                       /**< txnid that committed this page */
913 } MDB_meta;
914
915         /** Buffer for a stack-allocated meta page.
916          *      The members define size and alignment, and silence type
917          *      aliasing warnings.  They are not used directly; that could
918          *      mean incorrectly using several union members in parallel.
919          */
920 typedef union MDB_metabuf {
921         MDB_page        mb_page;
922         struct {
923                 char            mm_pad[PAGEHDRSZ];
924                 MDB_meta        mm_meta;
925         } mb_metabuf;
926 } MDB_metabuf;
927
928         /** Auxiliary DB info.
929          *      The information here is mostly static/read-only. There is
930          *      only a single copy of this record in the environment.
931          */
932 typedef struct MDB_dbx {
933         MDB_val         md_name;                /**< name of the database */
934         MDB_cmp_func    *md_cmp;        /**< function for comparing keys */
935         MDB_cmp_func    *md_dcmp;       /**< function for comparing data items */
936         MDB_rel_func    *md_rel;        /**< user relocate function */
937         void            *md_relctx;             /**< user-provided context for md_rel */
938 } MDB_dbx;
939
940         /** A database transaction.
941          *      Every operation requires a transaction handle.
942          */
943 struct MDB_txn {
944         MDB_txn         *mt_parent;             /**< parent of a nested txn */
945         MDB_txn         *mt_child;              /**< nested txn under this txn */
946         pgno_t          mt_next_pgno;   /**< next unallocated page */
947         /** The ID of this transaction. IDs are integers incrementing from 1.
948          *      Only committed write transactions increment the ID. If a transaction
949          *      aborts, the ID may be re-used by the next writer.
950          */
951         txnid_t         mt_txnid;
952         MDB_env         *mt_env;                /**< the DB environment */
953         /** The list of pages that became unused during this transaction.
954          */
955         MDB_IDL         mt_free_pgs;
956         /** The list of loose pages that became unused and may be reused
957          *      in this transaction, linked through #NEXT_LOOSE_PAGE(page).
958          */
959         MDB_page        *mt_loose_pgs;
960         /* #Number of loose pages (#mt_loose_pgs) */
961         int                     mt_loose_count;
962         /** The sorted list of dirty pages we temporarily wrote to disk
963          *      because the dirty list was full. page numbers in here are
964          *      shifted left by 1, deleted slots have the LSB set.
965          */
966         MDB_IDL         mt_spill_pgs;
967         union {
968                 /** For write txns: Modified pages. Sorted when not MDB_WRITEMAP. */
969                 MDB_ID2L        dirty_list;
970                 /** For read txns: This thread/txn's reader table slot, or NULL. */
971                 MDB_reader      *reader;
972         } mt_u;
973         /** Array of records for each DB known in the environment. */
974         MDB_dbx         *mt_dbxs;
975         /** Array of MDB_db records for each known DB */
976         MDB_db          *mt_dbs;
977         /** Array of sequence numbers for each DB handle */
978         unsigned int    *mt_dbiseqs;
979 /** @defgroup mt_dbflag Transaction DB Flags
980  *      @ingroup internal
981  * @{
982  */
983 #define DB_DIRTY        0x01            /**< DB was modified or is DUPSORT data */
984 #define DB_STALE        0x02            /**< Named-DB record is older than txnID */
985 #define DB_NEW          0x04            /**< Named-DB handle opened in this txn */
986 #define DB_VALID        0x08            /**< DB handle is valid, see also #MDB_VALID */
987 /** @} */
988         /** In write txns, array of cursors for each DB */
989         MDB_cursor      **mt_cursors;
990         /** Array of flags for each DB */
991         unsigned char   *mt_dbflags;
992         /**     Number of DB records in use. This number only ever increments;
993          *      we don't decrement it when individual DB handles are closed.
994          */
995         MDB_dbi         mt_numdbs;
996
997 /** @defgroup mdb_txn   Transaction Flags
998  *      @ingroup internal
999  *      @{
1000  */
1001 #define MDB_TXN_RDONLY          0x01            /**< read-only transaction */
1002 #define MDB_TXN_ERROR           0x02            /**< txn is unusable after an error */
1003 #define MDB_TXN_DIRTY           0x04            /**< must write, even if dirty list is empty */
1004 #define MDB_TXN_SPILLS          0x08            /**< txn or a parent has spilled pages */
1005 /** @} */
1006         unsigned int    mt_flags;               /**< @ref mdb_txn */
1007         /** #dirty_list room: Array size - \#dirty pages visible to this txn.
1008          *      Includes ancestor txns' dirty pages not hidden by other txns'
1009          *      dirty/spilled pages. Thus commit(nested txn) has room to merge
1010          *      dirty_list into mt_parent after freeing hidden mt_parent pages.
1011          */
1012         unsigned int    mt_dirty_room;
1013 };
1014
1015 /** Enough space for 2^32 nodes with minimum of 2 keys per node. I.e., plenty.
1016  * At 4 keys per node, enough for 2^64 nodes, so there's probably no need to
1017  * raise this on a 64 bit machine.
1018  */
1019 #define CURSOR_STACK             32
1020
1021 struct MDB_xcursor;
1022
1023         /** Cursors are used for all DB operations.
1024          *      A cursor holds a path of (page pointer, key index) from the DB
1025          *      root to a position in the DB, plus other state. #MDB_DUPSORT
1026          *      cursors include an xcursor to the current data item. Write txns
1027          *      track their cursors and keep them up to date when data moves.
1028          *      Exception: An xcursor's pointer to a #P_SUBP page can be stale.
1029          *      (A node with #F_DUPDATA but no #F_SUBDATA contains a subpage).
1030          */
1031 struct MDB_cursor {
1032         /** Next cursor on this DB in this txn */
1033         MDB_cursor      *mc_next;
1034         /** Backup of the original cursor if this cursor is a shadow */
1035         MDB_cursor      *mc_backup;
1036         /** Context used for databases with #MDB_DUPSORT, otherwise NULL */
1037         struct MDB_xcursor      *mc_xcursor;
1038         /** The transaction that owns this cursor */
1039         MDB_txn         *mc_txn;
1040         /** The database handle this cursor operates on */
1041         MDB_dbi         mc_dbi;
1042         /** The database record for this cursor */
1043         MDB_db          *mc_db;
1044         /** The database auxiliary record for this cursor */
1045         MDB_dbx         *mc_dbx;
1046         /** The @ref mt_dbflag for this database */
1047         unsigned char   *mc_dbflag;
1048         unsigned short  mc_snum;        /**< number of pushed pages */
1049         unsigned short  mc_top;         /**< index of top page, normally mc_snum-1 */
1050 /** @defgroup mdb_cursor        Cursor Flags
1051  *      @ingroup internal
1052  *      Cursor state flags.
1053  *      @{
1054  */
1055 #define C_INITIALIZED   0x01    /**< cursor has been initialized and is valid */
1056 #define C_EOF   0x02                    /**< No more data */
1057 #define C_SUB   0x04                    /**< Cursor is a sub-cursor */
1058 #define C_DEL   0x08                    /**< last op was a cursor_del */
1059 #define C_SPLITTING     0x20            /**< Cursor is in page_split */
1060 #define C_UNTRACK       0x40            /**< Un-track cursor when closing */
1061 /** @} */
1062         unsigned int    mc_flags;       /**< @ref mdb_cursor */
1063         MDB_page        *mc_pg[CURSOR_STACK];   /**< stack of pushed pages */
1064         indx_t          mc_ki[CURSOR_STACK];    /**< stack of page indices */
1065 };
1066
1067         /** Context for sorted-dup records.
1068          *      We could have gone to a fully recursive design, with arbitrarily
1069          *      deep nesting of sub-databases. But for now we only handle these
1070          *      levels - main DB, optional sub-DB, sorted-duplicate DB.
1071          */
1072 typedef struct MDB_xcursor {
1073         /** A sub-cursor for traversing the Dup DB */
1074         MDB_cursor mx_cursor;
1075         /** The database record for this Dup DB */
1076         MDB_db  mx_db;
1077         /**     The auxiliary DB record for this Dup DB */
1078         MDB_dbx mx_dbx;
1079         /** The @ref mt_dbflag for this Dup DB */
1080         unsigned char mx_dbflag;
1081 } MDB_xcursor;
1082
1083         /** State of FreeDB old pages, stored in the MDB_env */
1084 typedef struct MDB_pgstate {
1085         pgno_t          *mf_pghead;     /**< Reclaimed freeDB pages, or NULL before use */
1086         txnid_t         mf_pglast;      /**< ID of last used record, or 0 if !mf_pghead */
1087 } MDB_pgstate;
1088
1089         /** The database environment. */
1090 struct MDB_env {
1091         HANDLE          me_fd;          /**< The main data file */
1092         HANDLE          me_lfd;         /**< The lock file */
1093         HANDLE          me_mfd;                 /**< just for writing the meta pages */
1094         /** Failed to update the meta page. Probably an I/O error. */
1095 #define MDB_FATAL_ERROR 0x80000000U
1096         /** Some fields are initialized. */
1097 #define MDB_ENV_ACTIVE  0x20000000U
1098         /** me_txkey is set */
1099 #define MDB_ENV_TXKEY   0x10000000U
1100         uint32_t        me_flags;               /**< @ref mdb_env */
1101         unsigned int    me_psize;       /**< DB page size, inited from me_os_psize */
1102         unsigned int    me_os_psize;    /**< OS page size, from #GET_PAGESIZE */
1103         unsigned int    me_maxreaders;  /**< size of the reader table */
1104         unsigned int    me_numreaders;  /**< max numreaders set by this env */
1105         MDB_dbi         me_numdbs;              /**< number of DBs opened */
1106         MDB_dbi         me_maxdbs;              /**< size of the DB table */
1107         MDB_PID_T       me_pid;         /**< process ID of this env */
1108         char            *me_path;               /**< path to the DB files */
1109         char            *me_map;                /**< the memory map of the data file */
1110         MDB_txninfo     *me_txns;               /**< the memory map of the lock file or NULL */
1111         MDB_meta        *me_metas[2];   /**< pointers to the two meta pages */
1112         void            *me_pbuf;               /**< scratch area for DUPSORT put() */
1113         MDB_txn         *me_txn;                /**< current write transaction */
1114         MDB_txn         *me_txn0;               /**< prealloc'd write transaction */
1115         size_t          me_mapsize;             /**< size of the data memory map */
1116         size_t          me_size;                /**< current file size */
1117         pgno_t          me_maxpg;               /**< me_mapsize / me_psize */
1118         MDB_dbx         *me_dbxs;               /**< array of static DB info */
1119         uint16_t        *me_dbflags;    /**< array of flags from MDB_db.md_flags */
1120         unsigned int    *me_dbiseqs;    /**< array of dbi sequence numbers */
1121         pthread_key_t   me_txkey;       /**< thread-key for readers */
1122         txnid_t         me_pgoldest;    /**< ID of oldest reader last time we looked */
1123         MDB_pgstate     me_pgstate;             /**< state of old pages from freeDB */
1124 #       define          me_pglast       me_pgstate.mf_pglast
1125 #       define          me_pghead       me_pgstate.mf_pghead
1126         MDB_page        *me_dpages;             /**< list of malloc'd blocks for re-use */
1127         /** IDL of pages that became unused in a write txn */
1128         MDB_IDL         me_free_pgs;
1129         /** ID2L of pages written during a write txn. Length MDB_IDL_UM_SIZE. */
1130         MDB_ID2L        me_dirty_list;
1131         /** Max number of freelist items that can fit in a single overflow page */
1132         int                     me_maxfree_1pg;
1133         /** Max size of a node on a page */
1134         unsigned int    me_nodemax;
1135 #if !(MDB_MAXKEYSIZE)
1136         unsigned int    me_maxkey;      /**< max size of a key */
1137 #endif
1138         int             me_live_reader;         /**< have liveness lock in reader table */
1139 #ifdef _WIN32
1140         int             me_pidquery;            /**< Used in OpenProcess */
1141         HANDLE          me_rmutex;              /* Windows mutexes don't reside in shared mem */
1142         HANDLE          me_wmutex;
1143 #elif defined(MDB_USE_POSIX_SEM)
1144         sem_t           *me_rmutex;             /* Shared mutexes are not supported */
1145         sem_t           *me_wmutex;
1146 #endif
1147         void            *me_userctx;     /**< User-settable context */
1148         MDB_assert_func *me_assert_func; /**< Callback for assertion failures */
1149 };
1150
1151         /** Nested transaction */
1152 typedef struct MDB_ntxn {
1153         MDB_txn         mnt_txn;                /**< the transaction */
1154         MDB_pgstate     mnt_pgstate;    /**< parent transaction's saved freestate */
1155 } MDB_ntxn;
1156
1157         /** max number of pages to commit in one writev() call */
1158 #define MDB_COMMIT_PAGES         64
1159 #if defined(IOV_MAX) && IOV_MAX < MDB_COMMIT_PAGES
1160 #undef MDB_COMMIT_PAGES
1161 #define MDB_COMMIT_PAGES        IOV_MAX
1162 #endif
1163
1164         /** max bytes to write in one call */
1165 #define MAX_WRITE               (0x80000000U >> (sizeof(ssize_t) == 4))
1166
1167         /** Check \b txn and \b dbi arguments to a function */
1168 #define TXN_DBI_EXIST(txn, dbi) \
1169         ((txn) && (dbi) < (txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & DB_VALID))
1170
1171         /** Check for misused \b dbi handles */
1172 #define TXN_DBI_CHANGED(txn, dbi) \
1173         ((txn)->mt_dbiseqs[dbi] != (txn)->mt_env->me_dbiseqs[dbi])
1174
1175 static int  mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp);
1176 static int  mdb_page_new(MDB_cursor *mc, uint32_t flags, int num, MDB_page **mp);
1177 static int  mdb_page_touch(MDB_cursor *mc);
1178
1179 static int  mdb_page_get(MDB_txn *txn, pgno_t pgno, MDB_page **mp, int *lvl);
1180 static int  mdb_page_search_root(MDB_cursor *mc,
1181                             MDB_val *key, int modify);
1182 #define MDB_PS_MODIFY   1
1183 #define MDB_PS_ROOTONLY 2
1184 #define MDB_PS_FIRST    4
1185 #define MDB_PS_LAST             8
1186 static int  mdb_page_search(MDB_cursor *mc,
1187                             MDB_val *key, int flags);
1188 static int      mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst);
1189
1190 #define MDB_SPLIT_REPLACE       MDB_APPENDDUP   /**< newkey is not new */
1191 static int      mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata,
1192                                 pgno_t newpgno, unsigned int nflags);
1193
1194 static int  mdb_env_read_header(MDB_env *env, MDB_meta *meta);
1195 static int  mdb_env_pick_meta(const MDB_env *env);
1196 static int  mdb_env_write_meta(MDB_txn *txn);
1197 #if !(defined(_WIN32) || defined(MDB_USE_POSIX_SEM)) /* Drop unused excl arg */
1198 # define mdb_env_close0(env, excl) mdb_env_close1(env)
1199 #endif
1200 static void mdb_env_close0(MDB_env *env, int excl);
1201
1202 static MDB_node *mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp);
1203 static int  mdb_node_add(MDB_cursor *mc, indx_t indx,
1204                             MDB_val *key, MDB_val *data, pgno_t pgno, unsigned int flags);
1205 static void mdb_node_del(MDB_cursor *mc, int ksize);
1206 static void mdb_node_shrink(MDB_page *mp, indx_t indx);
1207 static int      mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst);
1208 static int  mdb_node_read(MDB_txn *txn, MDB_node *leaf, MDB_val *data);
1209 static size_t   mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data);
1210 static size_t   mdb_branch_size(MDB_env *env, MDB_val *key);
1211
1212 static int      mdb_rebalance(MDB_cursor *mc);
1213 static int      mdb_update_key(MDB_cursor *mc, MDB_val *key);
1214
1215 static void     mdb_cursor_pop(MDB_cursor *mc);
1216 static int      mdb_cursor_push(MDB_cursor *mc, MDB_page *mp);
1217
1218 static int      mdb_cursor_del0(MDB_cursor *mc);
1219 static int      mdb_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned flags);
1220 static int      mdb_cursor_sibling(MDB_cursor *mc, int move_right);
1221 static int      mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op);
1222 static int      mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op);
1223 static int      mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op,
1224                                 int *exactp);
1225 static int      mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data);
1226 static int      mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data);
1227
1228 static void     mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx);
1229 static void     mdb_xcursor_init0(MDB_cursor *mc);
1230 static void     mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node);
1231
1232 static int      mdb_drop0(MDB_cursor *mc, int subs);
1233 static void mdb_default_cmp(MDB_txn *txn, MDB_dbi dbi);
1234
1235 /** @cond */
1236 static MDB_cmp_func     mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long;
1237 /** @endcond */
1238
1239 #ifdef _WIN32
1240 static SECURITY_DESCRIPTOR mdb_null_sd;
1241 static SECURITY_ATTRIBUTES mdb_all_sa;
1242 static int mdb_sec_inited;
1243 #endif
1244
1245 /** Return the library version info. */
1246 char *
1247 mdb_version(int *major, int *minor, int *patch)
1248 {
1249         if (major) *major = MDB_VERSION_MAJOR;
1250         if (minor) *minor = MDB_VERSION_MINOR;
1251         if (patch) *patch = MDB_VERSION_PATCH;
1252         return MDB_VERSION_STRING;
1253 }
1254
1255 /** Table of descriptions for LMDB @ref errors */
1256 static char *const mdb_errstr[] = {
1257         "MDB_KEYEXIST: Key/data pair already exists",
1258         "MDB_NOTFOUND: No matching key/data pair found",
1259         "MDB_PAGE_NOTFOUND: Requested page not found",
1260         "MDB_CORRUPTED: Located page was wrong type",
1261         "MDB_PANIC: Update of meta page failed",
1262         "MDB_VERSION_MISMATCH: Database environment version mismatch",
1263         "MDB_INVALID: File is not an LMDB file",
1264         "MDB_MAP_FULL: Environment mapsize limit reached",
1265         "MDB_DBS_FULL: Environment maxdbs limit reached",
1266         "MDB_READERS_FULL: Environment maxreaders limit reached",
1267         "MDB_TLS_FULL: Thread-local storage keys full - too many environments open",
1268         "MDB_TXN_FULL: Transaction has too many dirty pages - transaction too big",
1269         "MDB_CURSOR_FULL: Internal error - cursor stack limit reached",
1270         "MDB_PAGE_FULL: Internal error - page has no more space",
1271         "MDB_MAP_RESIZED: Database contents grew beyond environment mapsize",
1272         "MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed",
1273         "MDB_BAD_RSLOT: Invalid reuse of reader locktable slot",
1274         "MDB_BAD_TXN: Transaction cannot recover - it must be aborted",
1275         "MDB_BAD_VALSIZE: Unsupported size of key/DB name/data, or wrong DUPFIXED size",
1276         "MDB_BAD_DBI: The specified DBI handle was closed/changed unexpectedly",
1277 };
1278
1279 char *
1280 mdb_strerror(int err)
1281 {
1282 #ifdef _WIN32
1283         /** HACK: pad 4KB on stack over the buf. Return system msgs in buf.
1284          *      This works as long as no function between the call to mdb_strerror
1285          *      and the actual use of the message uses more than 4K of stack.
1286          */
1287         char pad[4096];
1288         char buf[1024], *ptr = buf;
1289 #endif
1290         int i;
1291         if (!err)
1292                 return ("Successful return: 0");
1293
1294         if (err >= MDB_KEYEXIST && err <= MDB_LAST_ERRCODE) {
1295                 i = err - MDB_KEYEXIST;
1296                 return mdb_errstr[i];
1297         }
1298
1299 #ifdef _WIN32
1300         /* These are the C-runtime error codes we use. The comment indicates
1301          * their numeric value, and the Win32 error they would correspond to
1302          * if the error actually came from a Win32 API. A major mess, we should
1303          * have used LMDB-specific error codes for everything.
1304          */
1305         switch(err) {
1306         case ENOENT:    /* 2, FILE_NOT_FOUND */
1307         case EIO:               /* 5, ACCESS_DENIED */
1308         case ENOMEM:    /* 12, INVALID_ACCESS */
1309         case EACCES:    /* 13, INVALID_DATA */
1310         case EBUSY:             /* 16, CURRENT_DIRECTORY */
1311         case EINVAL:    /* 22, BAD_COMMAND */
1312         case ENOSPC:    /* 28, OUT_OF_PAPER */
1313                 return strerror(err);
1314         default:
1315                 ;
1316         }
1317         buf[0] = 0;
1318         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
1319                 FORMAT_MESSAGE_IGNORE_INSERTS,
1320                 NULL, err, 0, ptr, sizeof(buf), (va_list *)pad);
1321         return ptr;
1322 #else
1323         return strerror(err);
1324 #endif
1325 }
1326
1327 /** assert(3) variant in cursor context */
1328 #define mdb_cassert(mc, expr)   mdb_assert0((mc)->mc_txn->mt_env, expr, #expr)
1329 /** assert(3) variant in transaction context */
1330 #define mdb_tassert(mc, expr)   mdb_assert0((txn)->mt_env, expr, #expr)
1331 /** assert(3) variant in environment context */
1332 #define mdb_eassert(env, expr)  mdb_assert0(env, expr, #expr)
1333
1334 #ifndef NDEBUG
1335 # define mdb_assert0(env, expr, expr_txt) ((expr) ? (void)0 : \
1336                 mdb_assert_fail(env, expr_txt, mdb_func_, __FILE__, __LINE__))
1337
1338 static void
1339 mdb_assert_fail(MDB_env *env, const char *expr_txt,
1340         const char *func, const char *file, int line)
1341 {
1342         char buf[400];
1343         sprintf(buf, "%.100s:%d: Assertion '%.200s' failed in %.40s()",
1344                 file, line, expr_txt, func);
1345         if (env->me_assert_func)
1346                 env->me_assert_func(env, buf);
1347         fprintf(stderr, "%s\n", buf);
1348         abort();
1349 }
1350 #else
1351 # define mdb_assert0(env, expr, expr_txt) ((void) 0)
1352 #endif /* NDEBUG */
1353
1354 #if MDB_DEBUG
1355 /** Return the page number of \b mp which may be sub-page, for debug output */
1356 static pgno_t
1357 mdb_dbg_pgno(MDB_page *mp)
1358 {
1359         pgno_t ret;
1360         COPY_PGNO(ret, mp->mp_pgno);
1361         return ret;
1362 }
1363
1364 /** Display a key in hexadecimal and return the address of the result.
1365  * @param[in] key the key to display
1366  * @param[in] buf the buffer to write into. Should always be #DKBUF.
1367  * @return The key in hexadecimal form.
1368  */
1369 char *
1370 mdb_dkey(MDB_val *key, char *buf)
1371 {
1372         char *ptr = buf;
1373         unsigned char *c = key->mv_data;
1374         unsigned int i;
1375
1376         if (!key)
1377                 return "";
1378
1379         if (key->mv_size > DKBUF_MAXKEYSIZE)
1380                 return "MDB_MAXKEYSIZE";
1381         /* may want to make this a dynamic check: if the key is mostly
1382          * printable characters, print it as-is instead of converting to hex.
1383          */
1384 #if 1
1385         buf[0] = '\0';
1386         for (i=0; i<key->mv_size; i++)
1387                 ptr += sprintf(ptr, "%02x", *c++);
1388 #else
1389         sprintf(buf, "%.*s", key->mv_size, key->mv_data);
1390 #endif
1391         return buf;
1392 }
1393
1394 static const char *
1395 mdb_leafnode_type(MDB_node *n)
1396 {
1397         static char *const tp[2][2] = {{"", ": DB"}, {": sub-page", ": sub-DB"}};
1398         return F_ISSET(n->mn_flags, F_BIGDATA) ? ": overflow page" :
1399                 tp[F_ISSET(n->mn_flags, F_DUPDATA)][F_ISSET(n->mn_flags, F_SUBDATA)];
1400 }
1401
1402 /** Display all the keys in the page. */
1403 void
1404 mdb_page_list(MDB_page *mp)
1405 {
1406         pgno_t pgno = mdb_dbg_pgno(mp);
1407         const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : "";
1408         MDB_node *node;
1409         unsigned int i, nkeys, nsize, total = 0;
1410         MDB_val key;
1411         DKBUF;
1412
1413         switch (mp->mp_flags & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) {
1414         case P_BRANCH:              type = "Branch page";               break;
1415         case P_LEAF:                type = "Leaf page";                 break;
1416         case P_LEAF|P_SUBP:         type = "Sub-page";                  break;
1417         case P_LEAF|P_LEAF2:        type = "LEAF2 page";                break;
1418         case P_LEAF|P_LEAF2|P_SUBP: type = "LEAF2 sub-page";    break;
1419         case P_OVERFLOW:
1420                 fprintf(stderr, "Overflow page %"Z"u pages %u%s\n",
1421                         pgno, mp->mp_pages, state);
1422                 return;
1423         case P_META:
1424                 fprintf(stderr, "Meta-page %"Z"u txnid %"Z"u\n",
1425                         pgno, ((MDB_meta *)METADATA(mp))->mm_txnid);
1426                 return;
1427         default:
1428                 fprintf(stderr, "Bad page %"Z"u flags 0x%u\n", pgno, mp->mp_flags);
1429                 return;
1430         }
1431
1432         nkeys = NUMKEYS(mp);
1433         fprintf(stderr, "%s %"Z"u numkeys %d%s\n", type, pgno, nkeys, state);
1434
1435         for (i=0; i<nkeys; i++) {
1436                 if (IS_LEAF2(mp)) {     /* LEAF2 pages have no mp_ptrs[] or node headers */
1437                         key.mv_size = nsize = mp->mp_pad;
1438                         key.mv_data = LEAF2KEY(mp, i, nsize);
1439                         total += nsize;
1440                         fprintf(stderr, "key %d: nsize %d, %s\n", i, nsize, DKEY(&key));
1441                         continue;
1442                 }
1443                 node = NODEPTR(mp, i);
1444                 key.mv_size = node->mn_ksize;
1445                 key.mv_data = node->mn_data;
1446                 nsize = NODESIZE + key.mv_size;
1447                 if (IS_BRANCH(mp)) {
1448                         fprintf(stderr, "key %d: page %"Z"u, %s\n", i, NODEPGNO(node),
1449                                 DKEY(&key));
1450                         total += nsize;
1451                 } else {
1452                         if (F_ISSET(node->mn_flags, F_BIGDATA))
1453                                 nsize += sizeof(pgno_t);
1454                         else
1455                                 nsize += NODEDSZ(node);
1456                         total += nsize;
1457                         nsize += sizeof(indx_t);
1458                         fprintf(stderr, "key %d: nsize %d, %s%s\n",
1459                                 i, nsize, DKEY(&key), mdb_leafnode_type(node));
1460                 }
1461                 total = EVEN(total);
1462         }
1463         fprintf(stderr, "Total: header %d + contents %d + unused %d\n",
1464                 IS_LEAF2(mp) ? PAGEHDRSZ : PAGEBASE + mp->mp_lower, total, SIZELEFT(mp));
1465 }
1466
1467 void
1468 mdb_cursor_chk(MDB_cursor *mc)
1469 {
1470         unsigned int i;
1471         MDB_node *node;
1472         MDB_page *mp;
1473
1474         if (!mc->mc_snum && !(mc->mc_flags & C_INITIALIZED)) return;
1475         for (i=0; i<mc->mc_top; i++) {
1476                 mp = mc->mc_pg[i];
1477                 node = NODEPTR(mp, mc->mc_ki[i]);
1478                 if (NODEPGNO(node) != mc->mc_pg[i+1]->mp_pgno)
1479                         printf("oops!\n");
1480         }
1481         if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i]))
1482                 printf("ack!\n");
1483 }
1484 #endif
1485
1486 #if (MDB_DEBUG) > 2
1487 /** Count all the pages in each DB and in the freelist
1488  *  and make sure it matches the actual number of pages
1489  *  being used.
1490  *  All named DBs must be open for a correct count.
1491  */
1492 static void mdb_audit(MDB_txn *txn)
1493 {
1494         MDB_cursor mc;
1495         MDB_val key, data;
1496         MDB_ID freecount, count;
1497         MDB_dbi i;
1498         int rc;
1499
1500         freecount = 0;
1501         mdb_cursor_init(&mc, txn, FREE_DBI, NULL);
1502         while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0)
1503                 freecount += *(MDB_ID *)data.mv_data;
1504         mdb_tassert(txn, rc == MDB_NOTFOUND);
1505
1506         count = 0;
1507         for (i = 0; i<txn->mt_numdbs; i++) {
1508                 MDB_xcursor mx;
1509                 if (!(txn->mt_dbflags[i] & DB_VALID))
1510                         continue;
1511                 mdb_cursor_init(&mc, txn, i, &mx);
1512                 if (txn->mt_dbs[i].md_root == P_INVALID)
1513                         continue;
1514                 count += txn->mt_dbs[i].md_branch_pages +
1515                         txn->mt_dbs[i].md_leaf_pages +
1516                         txn->mt_dbs[i].md_overflow_pages;
1517                 if (txn->mt_dbs[i].md_flags & MDB_DUPSORT) {
1518                         rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST);
1519                         for (; rc == MDB_SUCCESS; rc = mdb_cursor_sibling(&mc, 1)) {
1520                                 unsigned j;
1521                                 MDB_page *mp;
1522                                 mp = mc.mc_pg[mc.mc_top];
1523                                 for (j=0; j<NUMKEYS(mp); j++) {
1524                                         MDB_node *leaf = NODEPTR(mp, j);
1525                                         if (leaf->mn_flags & F_SUBDATA) {
1526                                                 MDB_db db;
1527                                                 memcpy(&db, NODEDATA(leaf), sizeof(db));
1528                                                 count += db.md_branch_pages + db.md_leaf_pages +
1529                                                         db.md_overflow_pages;
1530                                         }
1531                                 }
1532                         }
1533                         mdb_tassert(txn, rc == MDB_NOTFOUND);
1534                 }
1535         }
1536         if (freecount + count + 2 /* metapages */ != txn->mt_next_pgno) {
1537                 fprintf(stderr, "audit: %lu freecount: %lu count: %lu total: %lu next_pgno: %lu\n",
1538                         txn->mt_txnid, freecount, count+2, freecount+count+2, txn->mt_next_pgno);
1539         }
1540 }
1541 #endif
1542
1543 int
1544 mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
1545 {
1546         return txn->mt_dbxs[dbi].md_cmp(a, b);
1547 }
1548
1549 int
1550 mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
1551 {
1552         return txn->mt_dbxs[dbi].md_dcmp(a, b);
1553 }
1554
1555 /** Allocate memory for a page.
1556  * Re-use old malloc'd pages first for singletons, otherwise just malloc.
1557  */
1558 static MDB_page *
1559 mdb_page_malloc(MDB_txn *txn, unsigned num)
1560 {
1561         MDB_env *env = txn->mt_env;
1562         MDB_page *ret = env->me_dpages;
1563         size_t psize = env->me_psize, sz = psize, off;
1564         /* For ! #MDB_NOMEMINIT, psize counts how much to init.
1565          * For a single page alloc, we init everything after the page header.
1566          * For multi-page, we init the final page; if the caller needed that
1567          * many pages they will be filling in at least up to the last page.
1568          */
1569         if (num == 1) {
1570                 if (ret) {
1571                         VGMEMP_ALLOC(env, ret, sz);
1572                         VGMEMP_DEFINED(ret, sizeof(ret->mp_next));
1573                         env->me_dpages = ret->mp_next;
1574                         return ret;
1575                 }
1576                 psize -= off = PAGEHDRSZ;
1577         } else {
1578                 sz *= num;
1579                 off = sz - psize;
1580         }
1581         if ((ret = malloc(sz)) != NULL) {
1582                 VGMEMP_ALLOC(env, ret, sz);
1583                 if (!(env->me_flags & MDB_NOMEMINIT)) {
1584                         memset((char *)ret + off, 0, psize);
1585                         ret->mp_pad = 0;
1586                 }
1587         } else {
1588                 txn->mt_flags |= MDB_TXN_ERROR;
1589         }
1590         return ret;
1591 }
1592 /** Free a single page.
1593  * Saves single pages to a list, for future reuse.
1594  * (This is not used for multi-page overflow pages.)
1595  */
1596 static void
1597 mdb_page_free(MDB_env *env, MDB_page *mp)
1598 {
1599         mp->mp_next = env->me_dpages;
1600         VGMEMP_FREE(env, mp);
1601         env->me_dpages = mp;
1602 }
1603
1604 /** Free a dirty page */
1605 static void
1606 mdb_dpage_free(MDB_env *env, MDB_page *dp)
1607 {
1608         if (!IS_OVERFLOW(dp) || dp->mp_pages == 1) {
1609                 mdb_page_free(env, dp);
1610         } else {
1611                 /* large pages just get freed directly */
1612                 VGMEMP_FREE(env, dp);
1613                 free(dp);
1614         }
1615 }
1616
1617 /**     Return all dirty pages to dpage list */
1618 static void
1619 mdb_dlist_free(MDB_txn *txn)
1620 {
1621         MDB_env *env = txn->mt_env;
1622         MDB_ID2L dl = txn->mt_u.dirty_list;
1623         unsigned i, n = dl[0].mid;
1624
1625         for (i = 1; i <= n; i++) {
1626                 mdb_dpage_free(env, dl[i].mptr);
1627         }
1628         dl[0].mid = 0;
1629 }
1630
1631 /** Loosen or free a single page.
1632  * Saves single pages to a list for future reuse
1633  * in this same txn. It has been pulled from the freeDB
1634  * and already resides on the dirty list, but has been
1635  * deleted. Use these pages first before pulling again
1636  * from the freeDB.
1637  *
1638  * If the page wasn't dirtied in this txn, just add it
1639  * to this txn's free list.
1640  */
1641 static int
1642 mdb_page_loose(MDB_cursor *mc, MDB_page *mp)
1643 {
1644         int loose = 0;
1645         pgno_t pgno = mp->mp_pgno;
1646         MDB_txn *txn = mc->mc_txn;
1647
1648         if ((mp->mp_flags & P_DIRTY) && mc->mc_dbi != FREE_DBI) {
1649                 if (txn->mt_parent) {
1650                         MDB_ID2 *dl = txn->mt_u.dirty_list;
1651                         /* If txn has a parent, make sure the page is in our
1652                          * dirty list.
1653                          */
1654                         if (dl[0].mid) {
1655                                 unsigned x = mdb_mid2l_search(dl, pgno);
1656                                 if (x <= dl[0].mid && dl[x].mid == pgno) {
1657                                         if (mp != dl[x].mptr) { /* bad cursor? */
1658                                                 mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
1659                                                 txn->mt_flags |= MDB_TXN_ERROR;
1660                                                 return MDB_CORRUPTED;
1661                                         }
1662                                         /* ok, it's ours */
1663                                         loose = 1;
1664                                 }
1665                         }
1666                 } else {
1667                         /* no parent txn, so it's just ours */
1668                         loose = 1;
1669                 }
1670         }
1671         if (loose) {
1672                 DPRINTF(("loosen db %d page %"Z"u", DDBI(mc),
1673                         mp->mp_pgno));
1674                 NEXT_LOOSE_PAGE(mp) = txn->mt_loose_pgs;
1675                 txn->mt_loose_pgs = mp;
1676                 txn->mt_loose_count++;
1677                 mp->mp_flags |= P_LOOSE;
1678         } else {
1679                 int rc = mdb_midl_append(&txn->mt_free_pgs, pgno);
1680                 if (rc)
1681                         return rc;
1682         }
1683
1684         return MDB_SUCCESS;
1685 }
1686
1687 /** Set or clear P_KEEP in dirty, non-overflow, non-sub pages watched by txn.
1688  * @param[in] mc A cursor handle for the current operation.
1689  * @param[in] pflags Flags of the pages to update:
1690  * P_DIRTY to set P_KEEP, P_DIRTY|P_KEEP to clear it.
1691  * @param[in] all No shortcuts. Needed except after a full #mdb_page_flush().
1692  * @return 0 on success, non-zero on failure.
1693  */
1694 static int
1695 mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
1696 {
1697         enum { Mask = P_SUBP|P_DIRTY|P_LOOSE|P_KEEP };
1698         MDB_txn *txn = mc->mc_txn;
1699         MDB_cursor *m3;
1700         MDB_xcursor *mx;
1701         MDB_page *dp, *mp;
1702         MDB_node *leaf;
1703         unsigned i, j;
1704         int rc = MDB_SUCCESS, level;
1705
1706         /* Mark pages seen by cursors */
1707         if (mc->mc_flags & C_UNTRACK)
1708                 mc = NULL;                              /* will find mc in mt_cursors */
1709         for (i = txn->mt_numdbs;; mc = txn->mt_cursors[--i]) {
1710                 for (; mc; mc=mc->mc_next) {
1711                         if (!(mc->mc_flags & C_INITIALIZED))
1712                                 continue;
1713                         for (m3 = mc;; m3 = &mx->mx_cursor) {
1714                                 mp = NULL;
1715                                 for (j=0; j<m3->mc_snum; j++) {
1716                                         mp = m3->mc_pg[j];
1717                                         if ((mp->mp_flags & Mask) == pflags)
1718                                                 mp->mp_flags ^= P_KEEP;
1719                                 }
1720                                 mx = m3->mc_xcursor;
1721                                 /* Proceed to mx if it is at a sub-database */
1722                                 if (! (mx && (mx->mx_cursor.mc_flags & C_INITIALIZED)))
1723                                         break;
1724                                 if (! (mp && (mp->mp_flags & P_LEAF)))
1725                                         break;
1726                                 leaf = NODEPTR(mp, m3->mc_ki[j-1]);
1727                                 if (!(leaf->mn_flags & F_SUBDATA))
1728                                         break;
1729                         }
1730                 }
1731                 if (i == 0)
1732                         break;
1733         }
1734
1735         if (all) {
1736                 /* Mark dirty root pages */
1737                 for (i=0; i<txn->mt_numdbs; i++) {
1738                         if (txn->mt_dbflags[i] & DB_DIRTY) {
1739                                 pgno_t pgno = txn->mt_dbs[i].md_root;
1740                                 if (pgno == P_INVALID)
1741                                         continue;
1742                                 if ((rc = mdb_page_get(txn, pgno, &dp, &level)) != MDB_SUCCESS)
1743                                         break;
1744                                 if ((dp->mp_flags & Mask) == pflags && level <= 1)
1745                                         dp->mp_flags ^= P_KEEP;
1746                         }
1747                 }
1748         }
1749
1750         return rc;
1751 }
1752
1753 static int mdb_page_flush(MDB_txn *txn, int keep);
1754
1755 /**     Spill pages from the dirty list back to disk.
1756  * This is intended to prevent running into #MDB_TXN_FULL situations,
1757  * but note that they may still occur in a few cases:
1758  *      1) our estimate of the txn size could be too small. Currently this
1759  *       seems unlikely, except with a large number of #MDB_MULTIPLE items.
1760  *      2) child txns may run out of space if their parents dirtied a
1761  *       lot of pages and never spilled them. TODO: we probably should do
1762  *       a preemptive spill during #mdb_txn_begin() of a child txn, if
1763  *       the parent's dirty_room is below a given threshold.
1764  *
1765  * Otherwise, if not using nested txns, it is expected that apps will
1766  * not run into #MDB_TXN_FULL any more. The pages are flushed to disk
1767  * the same way as for a txn commit, e.g. their P_DIRTY flag is cleared.
1768  * If the txn never references them again, they can be left alone.
1769  * If the txn only reads them, they can be used without any fuss.
1770  * If the txn writes them again, they can be dirtied immediately without
1771  * going thru all of the work of #mdb_page_touch(). Such references are
1772  * handled by #mdb_page_unspill().
1773  *
1774  * Also note, we never spill DB root pages, nor pages of active cursors,
1775  * because we'll need these back again soon anyway. And in nested txns,
1776  * we can't spill a page in a child txn if it was already spilled in a
1777  * parent txn. That would alter the parent txns' data even though
1778  * the child hasn't committed yet, and we'd have no way to undo it if
1779  * the child aborted.
1780  *
1781  * @param[in] m0 cursor A cursor handle identifying the transaction and
1782  *      database for which we are checking space.
1783  * @param[in] key For a put operation, the key being stored.
1784  * @param[in] data For a put operation, the data being stored.
1785  * @return 0 on success, non-zero on failure.
1786  */
1787 static int
1788 mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data)
1789 {
1790         MDB_txn *txn = m0->mc_txn;
1791         MDB_page *dp;
1792         MDB_ID2L dl = txn->mt_u.dirty_list;
1793         unsigned int i, j, need;
1794         int rc;
1795
1796         if (m0->mc_flags & C_SUB)
1797                 return MDB_SUCCESS;
1798
1799         /* Estimate how much space this op will take */
1800         i = m0->mc_db->md_depth;
1801         /* Named DBs also dirty the main DB */
1802         if (m0->mc_dbi > MAIN_DBI)
1803                 i += txn->mt_dbs[MAIN_DBI].md_depth;
1804         /* For puts, roughly factor in the key+data size */
1805         if (key)
1806                 i += (LEAFSIZE(key, data) + txn->mt_env->me_psize) / txn->mt_env->me_psize;
1807         i += i; /* double it for good measure */
1808         need = i;
1809
1810         if (txn->mt_dirty_room > i)
1811                 return MDB_SUCCESS;
1812
1813         if (!txn->mt_spill_pgs) {
1814                 txn->mt_spill_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX);
1815                 if (!txn->mt_spill_pgs)
1816                         return ENOMEM;
1817         } else {
1818                 /* purge deleted slots */
1819                 MDB_IDL sl = txn->mt_spill_pgs;
1820                 unsigned int num = sl[0];
1821                 j=0;
1822                 for (i=1; i<=num; i++) {
1823                         if (!(sl[i] & 1))
1824                                 sl[++j] = sl[i];
1825                 }
1826                 sl[0] = j;
1827         }
1828
1829         /* Preserve pages which may soon be dirtied again */
1830         if ((rc = mdb_pages_xkeep(m0, P_DIRTY, 1)) != MDB_SUCCESS)
1831                 goto done;
1832
1833         /* Less aggressive spill - we originally spilled the entire dirty list,
1834          * with a few exceptions for cursor pages and DB root pages. But this
1835          * turns out to be a lot of wasted effort because in a large txn many
1836          * of those pages will need to be used again. So now we spill only 1/8th
1837          * of the dirty pages. Testing revealed this to be a good tradeoff,
1838          * better than 1/2, 1/4, or 1/10.
1839          */
1840         if (need < MDB_IDL_UM_MAX / 8)
1841                 need = MDB_IDL_UM_MAX / 8;
1842
1843         /* Save the page IDs of all the pages we're flushing */
1844         /* flush from the tail forward, this saves a lot of shifting later on. */
1845         for (i=dl[0].mid; i && need; i--) {
1846                 MDB_ID pn = dl[i].mid << 1;
1847                 dp = dl[i].mptr;
1848                 if (dp->mp_flags & (P_LOOSE|P_KEEP))
1849                         continue;
1850                 /* Can't spill twice, make sure it's not already in a parent's
1851                  * spill list.
1852                  */
1853                 if (txn->mt_parent) {
1854                         MDB_txn *tx2;
1855                         for (tx2 = txn->mt_parent; tx2; tx2 = tx2->mt_parent) {
1856                                 if (tx2->mt_spill_pgs) {
1857                                         j = mdb_midl_search(tx2->mt_spill_pgs, pn);
1858                                         if (j <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[j] == pn) {
1859                                                 dp->mp_flags |= P_KEEP;
1860                                                 break;
1861                                         }
1862                                 }
1863                         }
1864                         if (tx2)
1865                                 continue;
1866                 }
1867                 if ((rc = mdb_midl_append(&txn->mt_spill_pgs, pn)))
1868                         goto done;
1869                 need--;
1870         }
1871         mdb_midl_sort(txn->mt_spill_pgs);
1872
1873         /* Flush the spilled part of dirty list */
1874         if ((rc = mdb_page_flush(txn, i)) != MDB_SUCCESS)
1875                 goto done;
1876
1877         /* Reset any dirty pages we kept that page_flush didn't see */
1878         rc = mdb_pages_xkeep(m0, P_DIRTY|P_KEEP, i);
1879
1880 done:
1881         txn->mt_flags |= rc ? MDB_TXN_ERROR : MDB_TXN_SPILLS;
1882         return rc;
1883 }
1884
1885 /** Find oldest txnid still referenced. Expects txn->mt_txnid > 0. */
1886 static txnid_t
1887 mdb_find_oldest(MDB_txn *txn)
1888 {
1889         int i;
1890         txnid_t mr, oldest = txn->mt_txnid - 1;
1891         if (txn->mt_env->me_txns) {
1892                 MDB_reader *r = txn->mt_env->me_txns->mti_readers;
1893                 for (i = txn->mt_env->me_txns->mti_numreaders; --i >= 0; ) {
1894                         if (r[i].mr_pid) {
1895                                 mr = r[i].mr_txnid;
1896                                 if (oldest > mr)
1897                                         oldest = mr;
1898                         }
1899                 }
1900         }
1901         return oldest;
1902 }
1903
1904 /** Add a page to the txn's dirty list */
1905 static void
1906 mdb_page_dirty(MDB_txn *txn, MDB_page *mp)
1907 {
1908         MDB_ID2 mid;
1909         int rc, (*insert)(MDB_ID2L, MDB_ID2 *);
1910
1911         if (txn->mt_env->me_flags & MDB_WRITEMAP) {
1912                 insert = mdb_mid2l_append;
1913         } else {
1914                 insert = mdb_mid2l_insert;
1915         }
1916         mid.mid = mp->mp_pgno;
1917         mid.mptr = mp;
1918         rc = insert(txn->mt_u.dirty_list, &mid);
1919         mdb_tassert(txn, rc == 0);
1920         txn->mt_dirty_room--;
1921 }
1922
1923 /** Allocate page numbers and memory for writing.  Maintain me_pglast,
1924  * me_pghead and mt_next_pgno.
1925  *
1926  * If there are free pages available from older transactions, they
1927  * are re-used first. Otherwise allocate a new page at mt_next_pgno.
1928  * Do not modify the freedB, just merge freeDB records into me_pghead[]
1929  * and move me_pglast to say which records were consumed.  Only this
1930  * function can create me_pghead and move me_pglast/mt_next_pgno.
1931  * @param[in] mc cursor A cursor handle identifying the transaction and
1932  *      database for which we are allocating.
1933  * @param[in] num the number of pages to allocate.
1934  * @param[out] mp Address of the allocated page(s). Requests for multiple pages
1935  *  will always be satisfied by a single contiguous chunk of memory.
1936  * @return 0 on success, non-zero on failure.
1937  */
1938 static int
1939 mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
1940 {
1941 #ifdef MDB_PARANOID     /* Seems like we can ignore this now */
1942         /* Get at most <Max_retries> more freeDB records once me_pghead
1943          * has enough pages.  If not enough, use new pages from the map.
1944          * If <Paranoid> and mc is updating the freeDB, only get new
1945          * records if me_pghead is empty. Then the freelist cannot play
1946          * catch-up with itself by growing while trying to save it.
1947          */
1948         enum { Paranoid = 1, Max_retries = 500 };
1949 #else
1950         enum { Paranoid = 0, Max_retries = INT_MAX /*infinite*/ };
1951 #endif
1952         int rc, retry = num * 60;
1953         MDB_txn *txn = mc->mc_txn;
1954         MDB_env *env = txn->mt_env;
1955         pgno_t pgno, *mop = env->me_pghead;
1956         unsigned i, j, mop_len = mop ? mop[0] : 0, n2 = num-1;
1957         MDB_page *np;
1958         txnid_t oldest = 0, last;
1959         MDB_cursor_op op;
1960         MDB_cursor m2;
1961         int found_old = 0;
1962
1963         /* If there are any loose pages, just use them */
1964         if (num == 1 && txn->mt_loose_pgs) {
1965                 np = txn->mt_loose_pgs;
1966                 txn->mt_loose_pgs = NEXT_LOOSE_PAGE(np);
1967                 txn->mt_loose_count--;
1968                 DPRINTF(("db %d use loose page %"Z"u", DDBI(mc),
1969                                 np->mp_pgno));
1970                 *mp = np;
1971                 return MDB_SUCCESS;
1972         }
1973
1974         *mp = NULL;
1975
1976         /* If our dirty list is already full, we can't do anything */
1977         if (txn->mt_dirty_room == 0) {
1978                 rc = MDB_TXN_FULL;
1979                 goto fail;
1980         }
1981
1982         for (op = MDB_FIRST;; op = MDB_NEXT) {
1983                 MDB_val key, data;
1984                 MDB_node *leaf;
1985                 pgno_t *idl;
1986
1987                 /* Seek a big enough contiguous page range. Prefer
1988                  * pages at the tail, just truncating the list.
1989                  */
1990                 if (mop_len > n2) {
1991                         i = mop_len;
1992                         do {
1993                                 pgno = mop[i];
1994                                 if (mop[i-n2] == pgno+n2)
1995                                         goto search_done;
1996                         } while (--i > n2);
1997                         if (--retry < 0)
1998                                 break;
1999                 }
2000
2001                 if (op == MDB_FIRST) {  /* 1st iteration */
2002                         /* Prepare to fetch more and coalesce */
2003                         last = env->me_pglast;
2004                         oldest = env->me_pgoldest;
2005                         mdb_cursor_init(&m2, txn, FREE_DBI, NULL);
2006                         if (last) {
2007                                 op = MDB_SET_RANGE;
2008                                 key.mv_data = &last; /* will look up last+1 */
2009                                 key.mv_size = sizeof(last);
2010                         }
2011                         if (Paranoid && mc->mc_dbi == FREE_DBI)
2012                                 retry = -1;
2013                 }
2014                 if (Paranoid && retry < 0 && mop_len)
2015                         break;
2016
2017                 last++;
2018                 /* Do not fetch more if the record will be too recent */
2019                 if (oldest <= last) {
2020                         if (!found_old) {
2021                                 oldest = mdb_find_oldest(txn);
2022                                 env->me_pgoldest = oldest;
2023                                 found_old = 1;
2024                         }
2025                         if (oldest <= last)
2026                                 break;
2027                 }
2028                 rc = mdb_cursor_get(&m2, &key, NULL, op);
2029                 if (rc) {
2030                         if (rc == MDB_NOTFOUND)
2031                                 break;
2032                         goto fail;
2033                 }
2034                 last = *(txnid_t*)key.mv_data;
2035                 if (oldest <= last) {
2036                         if (!found_old) {
2037                                 oldest = mdb_find_oldest(txn);
2038                                 env->me_pgoldest = oldest;
2039                                 found_old = 1;
2040                         }
2041                         if (oldest <= last)
2042                                 break;
2043                 }
2044                 np = m2.mc_pg[m2.mc_top];
2045                 leaf = NODEPTR(np, m2.mc_ki[m2.mc_top]);
2046                 if ((rc = mdb_node_read(txn, leaf, &data)) != MDB_SUCCESS)
2047                         return rc;
2048
2049                 idl = (MDB_ID *) data.mv_data;
2050                 i = idl[0];
2051                 if (!mop) {
2052                         if (!(env->me_pghead = mop = mdb_midl_alloc(i))) {
2053                                 rc = ENOMEM;
2054                                 goto fail;
2055                         }
2056                 } else {
2057                         if ((rc = mdb_midl_need(&env->me_pghead, i)) != 0)
2058                                 goto fail;
2059                         mop = env->me_pghead;
2060                 }
2061                 env->me_pglast = last;
2062 #if (MDB_DEBUG) > 1
2063                 DPRINTF(("IDL read txn %"Z"u root %"Z"u num %u",
2064                         last, txn->mt_dbs[FREE_DBI].md_root, i));
2065                 for (j = i; j; j--)
2066                         DPRINTF(("IDL %"Z"u", idl[j]));
2067 #endif
2068                 /* Merge in descending sorted order */
2069                 mdb_midl_xmerge(mop, idl);
2070                 mop_len = mop[0];
2071         }
2072
2073         /* Use new pages from the map when nothing suitable in the freeDB */
2074         i = 0;
2075         pgno = txn->mt_next_pgno;
2076         if (pgno + num >= env->me_maxpg) {
2077                         DPUTS("DB size maxed out");
2078                         rc = MDB_MAP_FULL;
2079                         goto fail;
2080         }
2081
2082 search_done:
2083         if (env->me_flags & MDB_WRITEMAP) {
2084                 np = (MDB_page *)(env->me_map + env->me_psize * pgno);
2085         } else {
2086                 if (!(np = mdb_page_malloc(txn, num))) {
2087                         rc = ENOMEM;
2088                         goto fail;
2089                 }
2090         }
2091         if (i) {
2092                 mop[0] = mop_len -= num;
2093                 /* Move any stragglers down */
2094                 for (j = i-num; j < mop_len; )
2095                         mop[++j] = mop[++i];
2096         } else {
2097                 txn->mt_next_pgno = pgno + num;
2098         }
2099         np->mp_pgno = pgno;
2100         mdb_page_dirty(txn, np);
2101         *mp = np;
2102
2103         return MDB_SUCCESS;
2104
2105 fail:
2106         txn->mt_flags |= MDB_TXN_ERROR;
2107         return rc;
2108 }
2109
2110 /** Copy the used portions of a non-overflow page.
2111  * @param[in] dst page to copy into
2112  * @param[in] src page to copy from
2113  * @param[in] psize size of a page
2114  */
2115 static void
2116 mdb_page_copy(MDB_page *dst, MDB_page *src, unsigned int psize)
2117 {
2118         enum { Align = sizeof(pgno_t) };
2119         indx_t upper = src->mp_upper, lower = src->mp_lower, unused = upper-lower;
2120
2121         /* If page isn't full, just copy the used portion. Adjust
2122          * alignment so memcpy may copy words instead of bytes.
2123          */
2124         if ((unused &= -Align) && !IS_LEAF2(src)) {
2125                 upper = (upper + PAGEBASE) & -Align;
2126                 memcpy(dst, src, (lower + PAGEBASE + (Align-1)) & -Align);
2127                 memcpy((pgno_t *)((char *)dst+upper), (pgno_t *)((char *)src+upper),
2128                         psize - upper);
2129         } else {
2130                 memcpy(dst, src, psize - unused);
2131         }
2132 }
2133
2134 /** Pull a page off the txn's spill list, if present.
2135  * If a page being referenced was spilled to disk in this txn, bring
2136  * it back and make it dirty/writable again.
2137  * @param[in] txn the transaction handle.
2138  * @param[in] mp the page being referenced. It must not be dirty.
2139  * @param[out] ret the writable page, if any. ret is unchanged if
2140  * mp wasn't spilled.
2141  */
2142 static int
2143 mdb_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret)
2144 {
2145         MDB_env *env = txn->mt_env;
2146         const MDB_txn *tx2;
2147         unsigned x;
2148         pgno_t pgno = mp->mp_pgno, pn = pgno << 1;
2149
2150         for (tx2 = txn; tx2; tx2=tx2->mt_parent) {
2151                 if (!tx2->mt_spill_pgs)
2152                         continue;
2153                 x = mdb_midl_search(tx2->mt_spill_pgs, pn);
2154                 if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) {
2155                         MDB_page *np;
2156                         int num;
2157                         if (txn->mt_dirty_room == 0)
2158                                 return MDB_TXN_FULL;
2159                         if (IS_OVERFLOW(mp))
2160                                 num = mp->mp_pages;
2161                         else
2162                                 num = 1;
2163                         if (env->me_flags & MDB_WRITEMAP) {
2164                                 np = mp;
2165                         } else {
2166                                 np = mdb_page_malloc(txn, num);
2167                                 if (!np)
2168                                         return ENOMEM;
2169                                 if (num > 1)
2170                                         memcpy(np, mp, num * env->me_psize);
2171                                 else
2172                                         mdb_page_copy(np, mp, env->me_psize);
2173                         }
2174                         if (tx2 == txn) {
2175                                 /* If in current txn, this page is no longer spilled.
2176                                  * If it happens to be the last page, truncate the spill list.
2177                                  * Otherwise mark it as deleted by setting the LSB.
2178                                  */
2179                                 if (x == txn->mt_spill_pgs[0])
2180                                         txn->mt_spill_pgs[0]--;
2181                                 else
2182                                         txn->mt_spill_pgs[x] |= 1;
2183                         }       /* otherwise, if belonging to a parent txn, the
2184                                  * page remains spilled until child commits
2185                                  */
2186
2187                         mdb_page_dirty(txn, np);
2188                         np->mp_flags |= P_DIRTY;
2189                         *ret = np;
2190                         break;
2191                 }
2192         }
2193         return MDB_SUCCESS;
2194 }
2195
2196 /** Touch a page: make it dirty and re-insert into tree with updated pgno.
2197  * @param[in] mc cursor pointing to the page to be touched
2198  * @return 0 on success, non-zero on failure.
2199  */
2200 static int
2201 mdb_page_touch(MDB_cursor *mc)
2202 {
2203         MDB_page *mp = mc->mc_pg[mc->mc_top], *np;
2204         MDB_txn *txn = mc->mc_txn;
2205         MDB_cursor *m2, *m3;
2206         pgno_t  pgno;
2207         int rc;
2208
2209         if (!F_ISSET(mp->mp_flags, P_DIRTY)) {
2210                 if (txn->mt_flags & MDB_TXN_SPILLS) {
2211                         np = NULL;
2212                         rc = mdb_page_unspill(txn, mp, &np);
2213                         if (rc)
2214                                 goto fail;
2215                         if (np)
2216                                 goto done;
2217                 }
2218                 if ((rc = mdb_midl_need(&txn->mt_free_pgs, 1)) ||
2219                         (rc = mdb_page_alloc(mc, 1, &np)))
2220                         goto fail;
2221                 pgno = np->mp_pgno;
2222                 DPRINTF(("touched db %d page %"Z"u -> %"Z"u", DDBI(mc),
2223                         mp->mp_pgno, pgno));
2224                 mdb_cassert(mc, mp->mp_pgno != pgno);
2225                 mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
2226                 /* Update the parent page, if any, to point to the new page */
2227                 if (mc->mc_top) {
2228                         MDB_page *parent = mc->mc_pg[mc->mc_top-1];
2229                         MDB_node *node = NODEPTR(parent, mc->mc_ki[mc->mc_top-1]);
2230                         SETPGNO(node, pgno);
2231                 } else {
2232                         mc->mc_db->md_root = pgno;
2233                 }
2234         } else if (txn->mt_parent && !IS_SUBP(mp)) {
2235                 MDB_ID2 mid, *dl = txn->mt_u.dirty_list;
2236                 pgno = mp->mp_pgno;
2237                 /* If txn has a parent, make sure the page is in our
2238                  * dirty list.
2239                  */
2240                 if (dl[0].mid) {
2241                         unsigned x = mdb_mid2l_search(dl, pgno);
2242                         if (x <= dl[0].mid && dl[x].mid == pgno) {
2243                                 if (mp != dl[x].mptr) { /* bad cursor? */
2244                                         mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
2245                                         txn->mt_flags |= MDB_TXN_ERROR;
2246                                         return MDB_CORRUPTED;
2247                                 }
2248                                 return 0;
2249                         }
2250                 }
2251                 mdb_cassert(mc, dl[0].mid < MDB_IDL_UM_MAX);
2252                 /* No - copy it */
2253                 np = mdb_page_malloc(txn, 1);
2254                 if (!np)
2255                         return ENOMEM;
2256                 mid.mid = pgno;
2257                 mid.mptr = np;
2258                 rc = mdb_mid2l_insert(dl, &mid);
2259                 mdb_cassert(mc, rc == 0);
2260         } else {
2261                 return 0;
2262         }
2263
2264         mdb_page_copy(np, mp, txn->mt_env->me_psize);
2265         np->mp_pgno = pgno;
2266         np->mp_flags |= P_DIRTY;
2267
2268 done:
2269         /* Adjust cursors pointing to mp */
2270         mc->mc_pg[mc->mc_top] = np;
2271         m2 = txn->mt_cursors[mc->mc_dbi];
2272         if (mc->mc_flags & C_SUB) {
2273                 for (; m2; m2=m2->mc_next) {
2274                         m3 = &m2->mc_xcursor->mx_cursor;
2275                         if (m3->mc_snum < mc->mc_snum) continue;
2276                         if (m3->mc_pg[mc->mc_top] == mp)
2277                                 m3->mc_pg[mc->mc_top] = np;
2278                 }
2279         } else {
2280                 for (; m2; m2=m2->mc_next) {
2281                         if (m2->mc_snum < mc->mc_snum) continue;
2282                         if (m2->mc_pg[mc->mc_top] == mp) {
2283                                 m2->mc_pg[mc->mc_top] = np;
2284                                 if ((mc->mc_db->md_flags & MDB_DUPSORT) &&
2285                                         IS_LEAF(np) &&
2286                                         m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top])
2287                                 {
2288                                         MDB_node *leaf = NODEPTR(np, mc->mc_ki[mc->mc_top]);
2289                                         if (!(leaf->mn_flags & F_SUBDATA))
2290                                                 m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
2291                                 }
2292                         }
2293                 }
2294         }
2295         return 0;
2296
2297 fail:
2298         txn->mt_flags |= MDB_TXN_ERROR;
2299         return rc;
2300 }
2301
2302 /* internal env_sync flags: */
2303 #define FORCE   1               /* as before, force a flush */
2304 #define FGREW   0x8000  /* file has grown, do a full fsync instead of just
2305            fdatasync. We shouldn't have to do this, according to the POSIX spec.
2306            But common Linux FSs violate the spec and won't sync required metadata
2307            correctly when the file grows. This only makes a difference if the
2308            platform actually distinguishes fdatasync from fsync.
2309            http://www.openldap.org/lists/openldap-devel/201411/msg00000.html */
2310
2311 static int
2312 mdb_env_sync0(MDB_env *env, int flag)
2313 {
2314         int rc = 0, force = flag & FORCE;
2315         if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) {
2316                 if (env->me_flags & MDB_WRITEMAP) {
2317                         int flags = ((env->me_flags & MDB_MAPASYNC) && !force)
2318                                 ? MS_ASYNC : MS_SYNC;
2319                         if (MDB_MSYNC(env->me_map, env->me_mapsize, flags))
2320                                 rc = ErrCode();
2321 #ifdef _WIN32
2322                         else if (flags == MS_SYNC && MDB_FDATASYNC(env->me_fd))
2323                                 rc = ErrCode();
2324 #endif
2325                 } else {
2326 #ifdef HAVE_FDATASYNC
2327                         if (flag & FGREW) {
2328                                 if (fsync(env->me_fd))  /* Avoid ext-fs bugs, do full sync */
2329                                         rc = ErrCode();
2330                         } else
2331 #endif
2332                         if (MDB_FDATASYNC(env->me_fd))
2333                                 rc = ErrCode();
2334                 }
2335         }
2336         return rc;
2337 }
2338
2339 int
2340 mdb_env_sync(MDB_env *env, int force)
2341 {
2342         return mdb_env_sync0(env, force != 0);
2343 }
2344
2345 /** Back up parent txn's cursors, then grab the originals for tracking */
2346 static int
2347 mdb_cursor_shadow(MDB_txn *src, MDB_txn *dst)
2348 {
2349         MDB_cursor *mc, *bk;
2350         MDB_xcursor *mx;
2351         size_t size;
2352         int i;
2353
2354         for (i = src->mt_numdbs; --i >= 0; ) {
2355                 if ((mc = src->mt_cursors[i]) != NULL) {
2356                         size = sizeof(MDB_cursor);
2357                         if (mc->mc_xcursor)
2358                                 size += sizeof(MDB_xcursor);
2359                         for (; mc; mc = bk->mc_next) {
2360                                 bk = malloc(size);
2361                                 if (!bk)
2362                                         return ENOMEM;
2363                                 *bk = *mc;
2364                                 mc->mc_backup = bk;
2365                                 mc->mc_db = &dst->mt_dbs[i];
2366                                 /* Kill pointers into src - and dst to reduce abuse: The
2367                                  * user may not use mc until dst ends. Otherwise we'd...
2368                                  */
2369                                 mc->mc_txn    = NULL;   /* ...set this to dst */
2370                                 mc->mc_dbflag = NULL;   /* ...and &dst->mt_dbflags[i] */
2371                                 if ((mx = mc->mc_xcursor) != NULL) {
2372                                         *(MDB_xcursor *)(bk+1) = *mx;
2373                                         mx->mx_cursor.mc_txn = NULL; /* ...and dst. */
2374                                 }
2375                                 mc->mc_next = dst->mt_cursors[i];
2376                                 dst->mt_cursors[i] = mc;
2377                         }
2378                 }
2379         }
2380         return MDB_SUCCESS;
2381 }
2382
2383 /** Close this write txn's cursors, give parent txn's cursors back to parent.
2384  * @param[in] txn the transaction handle.
2385  * @param[in] merge true to keep changes to parent cursors, false to revert.
2386  * @return 0 on success, non-zero on failure.
2387  */
2388 static void
2389 mdb_cursors_close(MDB_txn *txn, unsigned merge)
2390 {
2391         MDB_cursor **cursors = txn->mt_cursors, *mc, *next, *bk;
2392         MDB_xcursor *mx;
2393         int i;
2394
2395         for (i = txn->mt_numdbs; --i >= 0; ) {
2396                 for (mc = cursors[i]; mc; mc = next) {
2397                         next = mc->mc_next;
2398                         if ((bk = mc->mc_backup) != NULL) {
2399                                 if (merge) {
2400                                         /* Commit changes to parent txn */
2401                                         mc->mc_next = bk->mc_next;
2402                                         mc->mc_backup = bk->mc_backup;
2403                                         mc->mc_txn = bk->mc_txn;
2404                                         mc->mc_db = bk->mc_db;
2405                                         mc->mc_dbflag = bk->mc_dbflag;
2406                                         if ((mx = mc->mc_xcursor) != NULL)
2407                                                 mx->mx_cursor.mc_txn = bk->mc_txn;
2408                                 } else {
2409                                         /* Abort nested txn */
2410                                         *mc = *bk;
2411                                         if ((mx = mc->mc_xcursor) != NULL)
2412                                                 *mx = *(MDB_xcursor *)(bk+1);
2413                                 }
2414                                 mc = bk;
2415                         }
2416                         /* Only malloced cursors are permanently tracked. */
2417                         free(mc);
2418                 }
2419                 cursors[i] = NULL;
2420         }
2421 }
2422
2423 #if !(MDB_DEBUG)
2424 #define mdb_txn_reset0(txn, act) mdb_txn_reset0(txn)
2425 #endif
2426 static void
2427 mdb_txn_reset0(MDB_txn *txn, const char *act);
2428
2429 #if !(MDB_PIDLOCK)              /* Currently the same as defined(_WIN32) */
2430 enum Pidlock_op {
2431         Pidset, Pidcheck
2432 };
2433 #else
2434 enum Pidlock_op {
2435         Pidset = F_SETLK, Pidcheck = F_GETLK
2436 };
2437 #endif
2438
2439 /** Set or check a pid lock. Set returns 0 on success.
2440  * Check returns 0 if the process is certainly dead, nonzero if it may
2441  * be alive (the lock exists or an error happened so we do not know).
2442  *
2443  * On Windows Pidset is a no-op, we merely check for the existence
2444  * of the process with the given pid. On POSIX we use a single byte
2445  * lock on the lockfile, set at an offset equal to the pid.
2446  */
2447 static int
2448 mdb_reader_pid(MDB_env *env, enum Pidlock_op op, MDB_PID_T pid)
2449 {
2450 #if !(MDB_PIDLOCK)              /* Currently the same as defined(_WIN32) */
2451         int ret = 0;
2452         HANDLE h;
2453         if (op == Pidcheck) {
2454                 h = OpenProcess(env->me_pidquery, FALSE, pid);
2455                 /* No documented "no such process" code, but other program use this: */
2456                 if (!h)
2457                         return ErrCode() != ERROR_INVALID_PARAMETER;
2458                 /* A process exists until all handles to it close. Has it exited? */
2459                 ret = WaitForSingleObject(h, 0) != 0;
2460                 CloseHandle(h);
2461         }
2462         return ret;
2463 #else
2464         for (;;) {
2465                 int rc;
2466                 struct flock lock_info;
2467                 memset(&lock_info, 0, sizeof(lock_info));
2468                 lock_info.l_type = F_WRLCK;
2469                 lock_info.l_whence = SEEK_SET;
2470                 lock_info.l_start = pid;
2471                 lock_info.l_len = 1;
2472                 if ((rc = fcntl(env->me_lfd, op, &lock_info)) == 0) {
2473                         if (op == F_GETLK && lock_info.l_type != F_UNLCK)
2474                                 rc = -1;
2475                 } else if ((rc = ErrCode()) == EINTR) {
2476                         continue;
2477                 }
2478                 return rc;
2479         }
2480 #endif
2481 }
2482
2483 /** Common code for #mdb_txn_begin() and #mdb_txn_renew().
2484  * @param[in] txn the transaction handle to initialize
2485  * @return 0 on success, non-zero on failure.
2486  */
2487 static int
2488 mdb_txn_renew0(MDB_txn *txn)
2489 {
2490         MDB_env *env = txn->mt_env;
2491         MDB_txninfo *ti = env->me_txns;
2492         MDB_meta *meta;
2493         unsigned int i, nr;
2494         uint16_t x;
2495         int rc, new_notls = 0;
2496
2497         if (txn->mt_flags & MDB_TXN_RDONLY) {
2498                 /* Setup db info */
2499                 txn->mt_numdbs = env->me_numdbs;
2500                 txn->mt_dbxs = env->me_dbxs;    /* mostly static anyway */
2501                 if (!ti) {
2502                         meta = env->me_metas[ mdb_env_pick_meta(env) ];
2503                         txn->mt_txnid = meta->mm_txnid;
2504                         txn->mt_u.reader = NULL;
2505                 } else {
2506                         MDB_reader *r = (env->me_flags & MDB_NOTLS) ? txn->mt_u.reader :
2507                                 pthread_getspecific(env->me_txkey);
2508                         if (r) {
2509                                 if (r->mr_pid != env->me_pid || r->mr_txnid != (txnid_t)-1)
2510                                         return MDB_BAD_RSLOT;
2511                         } else {
2512                                 MDB_PID_T pid = env->me_pid;
2513                                 MDB_THR_T tid = pthread_self();
2514
2515                                 if (!env->me_live_reader) {
2516                                         rc = mdb_reader_pid(env, Pidset, pid);
2517                                         if (rc)
2518                                                 return rc;
2519                                         env->me_live_reader = 1;
2520                                 }
2521
2522                                 LOCK_MUTEX_R(env);
2523                                 nr = ti->mti_numreaders;
2524                                 for (i=0; i<nr; i++)
2525                                         if (ti->mti_readers[i].mr_pid == 0)
2526                                                 break;
2527                                 if (i == env->me_maxreaders) {
2528                                         UNLOCK_MUTEX_R(env);
2529                                         return MDB_READERS_FULL;
2530                                 }
2531                                 ti->mti_readers[i].mr_pid = pid;
2532                                 ti->mti_readers[i].mr_tid = tid;
2533                                 if (i == nr)
2534                                         ti->mti_numreaders = ++nr;
2535                                 /* Save numreaders for un-mutexed mdb_env_close() */
2536                                 env->me_numreaders = nr;
2537                                 UNLOCK_MUTEX_R(env);
2538
2539                                 r = &ti->mti_readers[i];
2540                                 new_notls = (env->me_flags & MDB_NOTLS);
2541                                 if (!new_notls && (rc=pthread_setspecific(env->me_txkey, r))) {
2542                                         r->mr_pid = 0;
2543                                         return rc;
2544                                 }
2545                         }
2546                         txn->mt_txnid = r->mr_txnid = ti->mti_txnid;
2547                         txn->mt_u.reader = r;
2548                         meta = env->me_metas[txn->mt_txnid & 1];
2549                 }
2550         } else {
2551                 if (ti) {
2552                         LOCK_MUTEX_W(env);
2553
2554                         txn->mt_txnid = ti->mti_txnid;
2555                         meta = env->me_metas[txn->mt_txnid & 1];
2556                 } else {
2557                         meta = env->me_metas[ mdb_env_pick_meta(env) ];
2558                         txn->mt_txnid = meta->mm_txnid;
2559                 }
2560                 /* Setup db info */
2561                 txn->mt_numdbs = env->me_numdbs;
2562                 txn->mt_txnid++;
2563 #if MDB_DEBUG
2564                 if (txn->mt_txnid == mdb_debug_start)
2565                         mdb_debug = 1;
2566 #endif
2567                 txn->mt_flags = 0;
2568                 txn->mt_child = NULL;
2569                 txn->mt_loose_pgs = NULL;
2570                 txn->mt_loose_count = 0;
2571                 txn->mt_dirty_room = MDB_IDL_UM_MAX;
2572                 txn->mt_u.dirty_list = env->me_dirty_list;
2573                 txn->mt_u.dirty_list[0].mid = 0;
2574                 txn->mt_free_pgs = env->me_free_pgs;
2575                 txn->mt_free_pgs[0] = 0;
2576                 txn->mt_spill_pgs = NULL;
2577                 env->me_txn = txn;
2578                 memcpy(txn->mt_dbiseqs, env->me_dbiseqs, env->me_maxdbs * sizeof(unsigned int));
2579         }
2580
2581         /* Copy the DB info and flags */
2582         memcpy(txn->mt_dbs, meta->mm_dbs, 2 * sizeof(MDB_db));
2583
2584         /* Moved to here to avoid a data race in read TXNs */
2585         txn->mt_next_pgno = meta->mm_last_pg+1;
2586
2587         for (i=2; i<txn->mt_numdbs; i++) {
2588                 x = env->me_dbflags[i];
2589                 txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS;
2590                 txn->mt_dbflags[i] = (x & MDB_VALID) ? DB_VALID|DB_STALE : 0;
2591         }
2592         txn->mt_dbflags[0] = txn->mt_dbflags[1] = DB_VALID;
2593
2594         if (env->me_maxpg < txn->mt_next_pgno) {
2595                 mdb_txn_reset0(txn, "renew0-mapfail");
2596                 if (new_notls) {
2597                         txn->mt_u.reader->mr_pid = 0;
2598                         txn->mt_u.reader = NULL;
2599                 }
2600                 return MDB_MAP_RESIZED;
2601         }
2602
2603         return MDB_SUCCESS;
2604 }
2605
2606 int
2607 mdb_txn_renew(MDB_txn *txn)
2608 {
2609         int rc;
2610
2611         if (!txn || txn->mt_dbxs)       /* A reset txn has mt_dbxs==NULL */
2612                 return EINVAL;
2613
2614         if (txn->mt_env->me_flags & MDB_FATAL_ERROR) {
2615                 DPUTS("environment had fatal error, must shutdown!");
2616                 return MDB_PANIC;
2617         }
2618
2619         rc = mdb_txn_renew0(txn);
2620         if (rc == MDB_SUCCESS) {
2621                 DPRINTF(("renew txn %"Z"u%c %p on mdbenv %p, root page %"Z"u",
2622                         txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
2623                         (void *)txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root));
2624         }
2625         return rc;
2626 }
2627
2628 int
2629 mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
2630 {
2631         MDB_txn *txn;
2632         MDB_ntxn *ntxn;
2633         int rc, size, tsize = sizeof(MDB_txn);
2634
2635         if (env->me_flags & MDB_FATAL_ERROR) {
2636                 DPUTS("environment had fatal error, must shutdown!");
2637                 return MDB_PANIC;
2638         }
2639         if ((env->me_flags & MDB_RDONLY) && !(flags & MDB_RDONLY))
2640                 return EACCES;
2641         if (parent) {
2642                 /* Nested transactions: Max 1 child, write txns only, no writemap */
2643                 if (parent->mt_child ||
2644                         (flags & MDB_RDONLY) ||
2645                         (parent->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR)) ||
2646                         (env->me_flags & MDB_WRITEMAP))
2647                 {
2648                         return (parent->mt_flags & MDB_TXN_RDONLY) ? EINVAL : MDB_BAD_TXN;
2649                 }
2650                 tsize = sizeof(MDB_ntxn);
2651         }
2652         size = tsize;
2653         if (!(flags & MDB_RDONLY)) {
2654                 if (!parent) {
2655                         txn = env->me_txn0;     /* just reuse preallocated write txn */
2656                         goto ok;
2657                 }
2658                 /* child txns use own copy of cursors */
2659                 size += env->me_maxdbs * sizeof(MDB_cursor *);
2660         }
2661         size += env->me_maxdbs * (sizeof(MDB_db)+1);
2662
2663         if ((txn = calloc(1, size)) == NULL) {
2664                 DPRINTF(("calloc: %s", strerror(errno)));
2665                 return ENOMEM;
2666         }
2667         txn->mt_dbs = (MDB_db *) ((char *)txn + tsize);
2668         if (flags & MDB_RDONLY) {
2669                 txn->mt_flags |= MDB_TXN_RDONLY;
2670                 txn->mt_dbflags = (unsigned char *)(txn->mt_dbs + env->me_maxdbs);
2671                 txn->mt_dbiseqs = env->me_dbiseqs;
2672         } else {
2673                 txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
2674                 if (parent) {
2675                         txn->mt_dbiseqs = parent->mt_dbiseqs;
2676                         txn->mt_dbflags = (unsigned char *)(txn->mt_cursors + env->me_maxdbs);
2677                 } else {
2678                         txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
2679                         txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
2680                 }
2681         }
2682         txn->mt_env = env;
2683
2684 ok:
2685         if (parent) {
2686                 unsigned int i;
2687                 txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE);
2688                 if (!txn->mt_u.dirty_list ||
2689                         !(txn->mt_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)))
2690                 {
2691                         free(txn->mt_u.dirty_list);
2692                         free(txn);
2693                         return ENOMEM;
2694                 }
2695                 txn->mt_txnid = parent->mt_txnid;
2696                 txn->mt_dirty_room = parent->mt_dirty_room;
2697                 txn->mt_u.dirty_list[0].mid = 0;
2698                 txn->mt_spill_pgs = NULL;
2699                 txn->mt_next_pgno = parent->mt_next_pgno;
2700                 parent->mt_child = txn;
2701                 txn->mt_parent = parent;
2702                 txn->mt_numdbs = parent->mt_numdbs;
2703                 txn->mt_flags = parent->mt_flags;
2704                 txn->mt_dbxs = parent->mt_dbxs;
2705                 memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDB_db));
2706                 /* Copy parent's mt_dbflags, but clear DB_NEW */
2707                 for (i=0; i<txn->mt_numdbs; i++)
2708                         txn->mt_dbflags[i] = parent->mt_dbflags[i] & ~DB_NEW;
2709                 rc = 0;
2710                 ntxn = (MDB_ntxn *)txn;
2711                 ntxn->mnt_pgstate = env->me_pgstate; /* save parent me_pghead & co */
2712                 if (env->me_pghead) {
2713                         size = MDB_IDL_SIZEOF(env->me_pghead);
2714                         env->me_pghead = mdb_midl_alloc(env->me_pghead[0]);
2715                         if (env->me_pghead)
2716                                 memcpy(env->me_pghead, ntxn->mnt_pgstate.mf_pghead, size);
2717                         else
2718                                 rc = ENOMEM;
2719                 }
2720                 if (!rc)
2721                         rc = mdb_cursor_shadow(parent, txn);
2722                 if (rc)
2723                         mdb_txn_reset0(txn, "beginchild-fail");
2724         } else {
2725                 rc = mdb_txn_renew0(txn);
2726         }
2727         if (rc) {
2728                 if (txn != env->me_txn0)
2729                         free(txn);
2730         } else {
2731                 *ret = txn;
2732                 DPRINTF(("begin txn %"Z"u%c %p on mdbenv %p, root page %"Z"u",
2733                         txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
2734                         (void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root));
2735         }
2736
2737         return rc;
2738 }
2739
2740 MDB_env *
2741 mdb_txn_env(MDB_txn *txn)
2742 {
2743         if(!txn) return NULL;
2744         return txn->mt_env;
2745 }
2746
2747 /** Export or close DBI handles opened in this txn. */
2748 static void
2749 mdb_dbis_update(MDB_txn *txn, int keep)
2750 {
2751         int i;
2752         MDB_dbi n = txn->mt_numdbs;
2753         MDB_env *env = txn->mt_env;
2754         unsigned char *tdbflags = txn->mt_dbflags;
2755
2756         for (i = n; --i >= 2;) {
2757                 if (tdbflags[i] & DB_NEW) {
2758                         if (keep) {
2759                                 env->me_dbflags[i] = txn->mt_dbs[i].md_flags | MDB_VALID;
2760                         } else {
2761                                 char *ptr = env->me_dbxs[i].md_name.mv_data;
2762                                 if (ptr) {
2763                                         env->me_dbxs[i].md_name.mv_data = NULL;
2764                                         env->me_dbxs[i].md_name.mv_size = 0;
2765                                         env->me_dbflags[i] = 0;
2766                                         env->me_dbiseqs[i]++;
2767                                         free(ptr);
2768                                 }
2769                         }
2770                 }
2771         }
2772         if (keep && env->me_numdbs < n)
2773                 env->me_numdbs = n;
2774 }
2775
2776 /** Common code for #mdb_txn_reset() and #mdb_txn_abort().
2777  * May be called twice for readonly txns: First reset it, then abort.
2778  * @param[in] txn the transaction handle to reset
2779  * @param[in] act why the transaction is being reset
2780  */
2781 static void
2782 mdb_txn_reset0(MDB_txn *txn, const char *act)
2783 {
2784         MDB_env *env = txn->mt_env;
2785
2786         /* Close any DBI handles opened in this txn */
2787         mdb_dbis_update(txn, 0);
2788
2789         DPRINTF(("%s txn %"Z"u%c %p on mdbenv %p, root page %"Z"u",
2790                 act, txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
2791                 (void *) txn, (void *)env, txn->mt_dbs[MAIN_DBI].md_root));
2792
2793         if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
2794                 if (txn->mt_u.reader) {
2795                         txn->mt_u.reader->mr_txnid = (txnid_t)-1;
2796                         if (!(env->me_flags & MDB_NOTLS))
2797                                 txn->mt_u.reader = NULL; /* txn does not own reader */
2798                 }
2799                 txn->mt_numdbs = 0;             /* close nothing if called again */
2800                 txn->mt_dbxs = NULL;    /* mark txn as reset */
2801         } else {
2802                 pgno_t *pghead = env->me_pghead;
2803
2804                 mdb_cursors_close(txn, 0);
2805                 if (!(env->me_flags & MDB_WRITEMAP)) {
2806                         mdb_dlist_free(txn);
2807                 }
2808
2809                 if (!txn->mt_parent) {
2810                         if (mdb_midl_shrink(&txn->mt_free_pgs))
2811                                 env->me_free_pgs = txn->mt_free_pgs;
2812                         /* me_pgstate: */
2813                         env->me_pghead = NULL;
2814                         env->me_pglast = 0;
2815
2816                         env->me_txn = NULL;
2817                         /* The writer mutex was locked in mdb_txn_begin. */
2818                         if (env->me_txns)
2819                                 UNLOCK_MUTEX_W(env);
2820                 } else {
2821                         txn->mt_parent->mt_child = NULL;
2822                         env->me_pgstate = ((MDB_ntxn *)txn)->mnt_pgstate;
2823                         mdb_midl_free(txn->mt_free_pgs);
2824                         mdb_midl_free(txn->mt_spill_pgs);
2825                         free(txn->mt_u.dirty_list);
2826                 }
2827
2828                 mdb_midl_free(pghead);
2829         }
2830 }
2831
2832 void
2833 mdb_txn_reset(MDB_txn *txn)
2834 {
2835         if (txn == NULL)
2836                 return;
2837
2838         /* This call is only valid for read-only txns */
2839         if (!(txn->mt_flags & MDB_TXN_RDONLY))
2840                 return;
2841
2842         mdb_txn_reset0(txn, "reset");
2843 }
2844
2845 void
2846 mdb_txn_abort(MDB_txn *txn)
2847 {
2848         if (txn == NULL)
2849                 return;
2850
2851         if (txn->mt_child)
2852                 mdb_txn_abort(txn->mt_child);
2853
2854         mdb_txn_reset0(txn, "abort");
2855         /* Free reader slot tied to this txn (if MDB_NOTLS && writable FS) */
2856         if ((txn->mt_flags & MDB_TXN_RDONLY) && txn->mt_u.reader)
2857                 txn->mt_u.reader->mr_pid = 0;
2858
2859         if (txn != txn->mt_env->me_txn0)
2860                 free(txn);
2861 }
2862
2863 /** Save the freelist as of this transaction to the freeDB.
2864  * This changes the freelist. Keep trying until it stabilizes.
2865  */
2866 static int
2867 mdb_freelist_save(MDB_txn *txn)
2868 {
2869         /* env->me_pghead[] can grow and shrink during this call.
2870          * env->me_pglast and txn->mt_free_pgs[] can only grow.
2871          * Page numbers cannot disappear from txn->mt_free_pgs[].
2872          */
2873         MDB_cursor mc;
2874         MDB_env *env = txn->mt_env;
2875         int rc, maxfree_1pg = env->me_maxfree_1pg, more = 1;
2876         txnid_t pglast = 0, head_id = 0;
2877         pgno_t  freecnt = 0, *free_pgs, *mop;
2878         ssize_t head_room = 0, total_room = 0, mop_len, clean_limit;
2879
2880         mdb_cursor_init(&mc, txn, FREE_DBI, NULL);
2881
2882         if (env->me_pghead) {
2883                 /* Make sure first page of freeDB is touched and on freelist */
2884                 rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST|MDB_PS_MODIFY);
2885                 if (rc && rc != MDB_NOTFOUND)
2886                         return rc;
2887         }
2888
2889         if (!env->me_pghead && txn->mt_loose_pgs) {
2890                 /* Put loose page numbers in mt_free_pgs, since
2891                  * we may be unable to return them to me_pghead.
2892                  */
2893                 MDB_page *mp = txn->mt_loose_pgs;
2894                 if ((rc = mdb_midl_need(&txn->mt_free_pgs, txn->mt_loose_count)) != 0)
2895                         return rc;
2896                 for (; mp; mp = NEXT_LOOSE_PAGE(mp))
2897                         mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
2898                 txn->mt_loose_pgs = NULL;
2899                 txn->mt_loose_count = 0;
2900         }
2901
2902         /* MDB_RESERVE cancels meminit in ovpage malloc (when no WRITEMAP) */
2903         clean_limit = (env->me_flags & (MDB_NOMEMINIT|MDB_WRITEMAP))
2904                 ? SSIZE_MAX : maxfree_1pg;
2905
2906         for (;;) {
2907                 /* Come back here after each Put() in case freelist changed */
2908                 MDB_val key, data;
2909                 pgno_t *pgs;
2910                 ssize_t j;
2911
2912                 /* If using records from freeDB which we have not yet
2913                  * deleted, delete them and any we reserved for me_pghead.
2914                  */
2915                 while (pglast < env->me_pglast) {
2916                         rc = mdb_cursor_first(&mc, &key, NULL);
2917                         if (rc)
2918                                 return rc;
2919                         pglast = head_id = *(txnid_t *)key.mv_data;
2920                         total_room = head_room = 0;
2921                         mdb_tassert(txn, pglast <= env->me_pglast);
2922                         rc = mdb_cursor_del(&mc, 0);
2923                         if (rc)
2924                                 return rc;
2925                 }
2926
2927                 /* Save the IDL of pages freed by this txn, to a single record */
2928                 if (freecnt < txn->mt_free_pgs[0]) {
2929                         if (!freecnt) {
2930                                 /* Make sure last page of freeDB is touched and on freelist */
2931                                 rc = mdb_page_search(&mc, NULL, MDB_PS_LAST|MDB_PS_MODIFY);
2932                                 if (rc && rc != MDB_NOTFOUND)
2933                                         return rc;
2934                         }
2935                         free_pgs = txn->mt_free_pgs;
2936                         /* Write to last page of freeDB */
2937                         key.mv_size = sizeof(txn->mt_txnid);
2938                         key.mv_data = &txn->mt_txnid;
2939                         do {
2940                                 freecnt = free_pgs[0];
2941                                 data.mv_size = MDB_IDL_SIZEOF(free_pgs);
2942                                 rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
2943                                 if (rc)
2944                                         return rc;
2945                                 /* Retry if mt_free_pgs[] grew during the Put() */
2946                                 free_pgs = txn->mt_free_pgs;
2947                         } while (freecnt < free_pgs[0]);
2948                         mdb_midl_sort(free_pgs);
2949                         memcpy(data.mv_data, free_pgs, data.mv_size);
2950 #if (MDB_DEBUG) > 1
2951                         {
2952                                 unsigned int i = free_pgs[0];
2953                                 DPRINTF(("IDL write txn %"Z"u root %"Z"u num %u",
2954                                         txn->mt_txnid, txn->mt_dbs[FREE_DBI].md_root, i));
2955                                 for (; i; i--)
2956                                         DPRINTF(("IDL %"Z"u", free_pgs[i]));
2957                         }
2958 #endif
2959                         continue;
2960                 }
2961
2962                 mop = env->me_pghead;
2963                 mop_len = (mop ? mop[0] : 0) + txn->mt_loose_count;
2964
2965                 /* Reserve records for me_pghead[]. Split it if multi-page,
2966                  * to avoid searching freeDB for a page range. Use keys in
2967                  * range [1,me_pglast]: Smaller than txnid of oldest reader.
2968                  */
2969                 if (total_room >= mop_len) {
2970                         if (total_room == mop_len || --more < 0)
2971                                 break;
2972                 } else if (head_room >= maxfree_1pg && head_id > 1) {
2973                         /* Keep current record (overflow page), add a new one */
2974                         head_id--;
2975                         head_room = 0;
2976                 }
2977                 /* (Re)write {key = head_id, IDL length = head_room} */
2978                 total_room -= head_room;
2979                 head_room = mop_len - total_room;
2980                 if (head_room > maxfree_1pg && head_id > 1) {
2981                         /* Overflow multi-page for part of me_pghead */
2982                         head_room /= head_id; /* amortize page sizes */
2983                         head_room += maxfree_1pg - head_room % (maxfree_1pg + 1);
2984                 } else if (head_room < 0) {
2985                         /* Rare case, not bothering to delete this record */
2986                         head_room = 0;
2987                 }
2988                 key.mv_size = sizeof(head_id);
2989                 key.mv_data = &head_id;
2990                 data.mv_size = (head_room + 1) * sizeof(pgno_t);
2991                 rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
2992                 if (rc)
2993                         return rc;
2994                 /* IDL is initially empty, zero out at least the length */
2995                 pgs = (pgno_t *)data.mv_data;
2996                 j = head_room > clean_limit ? head_room : 0;
2997                 do {
2998                         pgs[j] = 0;
2999                 } while (--j >= 0);
3000                 total_room += head_room;
3001         }
3002
3003         /* Return loose page numbers to me_pghead, though usually none are
3004          * left at this point.  The pages themselves remain in dirty_list.
3005          */
3006         if (txn->mt_loose_pgs) {
3007                 MDB_page *mp = txn->mt_loose_pgs;
3008                 unsigned count = txn->mt_loose_count;
3009                 MDB_IDL loose;
3010                 /* Room for loose pages + temp IDL with same */
3011                 if ((rc = mdb_midl_need(&env->me_pghead, 2*count+1)) != 0)
3012                         return rc;
3013                 mop = env->me_pghead;
3014                 loose = mop + MDB_IDL_ALLOCLEN(mop) - count;
3015                 for (count = 0; mp; mp = NEXT_LOOSE_PAGE(mp))
3016                         loose[ ++count ] = mp->mp_pgno;
3017                 loose[0] = count;
3018                 mdb_midl_sort(loose);
3019                 mdb_midl_xmerge(mop, loose);
3020                 txn->mt_loose_pgs = NULL;
3021                 txn->mt_loose_count = 0;
3022                 mop_len = mop[0];
3023         }
3024
3025         /* Fill in the reserved me_pghead records */
3026         rc = MDB_SUCCESS;
3027         if (mop_len) {
3028                 MDB_val key, data;
3029
3030                 mop += mop_len;
3031                 rc = mdb_cursor_first(&mc, &key, &data);
3032                 for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) {
3033                         txnid_t id = *(txnid_t *)key.mv_data;
3034                         ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1;
3035                         MDB_ID save;
3036
3037                         mdb_tassert(txn, len >= 0 && id <= env->me_pglast);
3038                         key.mv_data = &id;
3039                         if (len > mop_len) {
3040                                 len = mop_len;
3041                                 data.mv_size = (len + 1) * sizeof(MDB_ID);
3042                         }
3043                         data.mv_data = mop -= len;
3044                         save = mop[0];
3045                         mop[0] = len;
3046                         rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT);
3047                         mop[0] = save;
3048                         if (rc || !(mop_len -= len))
3049                                 break;
3050                 }
3051         }
3052         return rc;
3053 }
3054
3055 /** Flush (some) dirty pages to the map, after clearing their dirty flag.
3056  * @param[in] txn the transaction that's being committed
3057  * @param[in] keep number of initial pages in dirty_list to keep dirty.
3058  * @return 0 on success, non-zero on failure.
3059  */
3060 static int
3061 mdb_page_flush(MDB_txn *txn, int keep)
3062 {
3063         MDB_env         *env = txn->mt_env;
3064         MDB_ID2L        dl = txn->mt_u.dirty_list;
3065         unsigned        psize = env->me_psize, j;
3066         int                     i, pagecount = dl[0].mid, rc;
3067         size_t          size = 0, pos = 0;
3068         pgno_t          pgno = 0;
3069         MDB_page        *dp = NULL;
3070 #ifdef _WIN32
3071         OVERLAPPED      ov;
3072 #else
3073         struct iovec iov[MDB_COMMIT_PAGES];
3074         ssize_t         wpos = 0, wsize = 0, wres;
3075         size_t          next_pos = 1; /* impossible pos, so pos != next_pos */
3076         int                     n = 0;
3077 #endif
3078
3079         j = i = keep;
3080
3081         if (env->me_flags & MDB_WRITEMAP) {
3082                 /* Clear dirty flags */
3083                 while (++i <= pagecount) {
3084                         dp = dl[i].mptr;
3085                         /* Don't flush this page yet */
3086                         if (dp->mp_flags & (P_LOOSE|P_KEEP)) {
3087                                 dp->mp_flags &= ~P_KEEP;
3088                                 dl[++j] = dl[i];
3089                                 continue;
3090                         }
3091                         dp->mp_flags &= ~P_DIRTY;
3092                 }
3093                 goto done;
3094         }
3095
3096         /* Write the pages */
3097         for (;;) {
3098                 if (++i <= pagecount) {
3099                         dp = dl[i].mptr;
3100                         /* Don't flush this page yet */
3101                         if (dp->mp_flags & (P_LOOSE|P_KEEP)) {
3102                                 dp->mp_flags &= ~P_KEEP;
3103                                 dl[i].mid = 0;
3104                                 continue;
3105                         }
3106                         pgno = dl[i].mid;
3107                         /* clear dirty flag */
3108                         dp->mp_flags &= ~P_DIRTY;
3109                         pos = pgno * psize;
3110                         size = psize;
3111                         if (IS_OVERFLOW(dp)) size *= dp->mp_pages;
3112                 }
3113 #ifdef _WIN32
3114                 else break;
3115
3116                 /* Windows actually supports scatter/gather I/O, but only on
3117                  * unbuffered file handles. Since we're relying on the OS page
3118                  * cache for all our data, that's self-defeating. So we just
3119                  * write pages one at a time. We use the ov structure to set
3120                  * the write offset, to at least save the overhead of a Seek
3121                  * system call.
3122                  */
3123                 DPRINTF(("committing page %"Z"u", pgno));
3124                 memset(&ov, 0, sizeof(ov));
3125                 ov.Offset = pos & 0xffffffff;
3126                 ov.OffsetHigh = pos >> 16 >> 16;
3127                 if (!WriteFile(env->me_fd, dp, size, NULL, &ov)) {
3128                         rc = ErrCode();
3129                         DPRINTF(("WriteFile: %d", rc));
3130                         return rc;
3131                 }
3132 #else
3133                 /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
3134                 if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
3135                         if (n) {
3136                                 /* Write previous page(s) */
3137 #ifdef MDB_USE_PWRITEV
3138                                 wres = pwritev(env->me_fd, iov, n, wpos);
3139 #else
3140                                 if (n == 1) {
3141                                         wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
3142                                 } else {
3143                                         if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
3144                                                 rc = ErrCode();
3145                                                 DPRINTF(("lseek: %s", strerror(rc)));
3146                                                 return rc;
3147                                         }
3148                                         wres = writev(env->me_fd, iov, n);
3149                                 }
3150 #endif
3151                                 if (wres != wsize) {
3152                                         if (wres < 0) {
3153                                                 rc = ErrCode();
3154                                                 DPRINTF(("Write error: %s", strerror(rc)));
3155                                         } else {
3156                                                 rc = EIO; /* TODO: Use which error code? */
3157                                                 DPUTS("short write, filesystem full?");
3158                                         }
3159                                         return rc;
3160                                 }
3161                                 n = 0;
3162                         }
3163                         if (i > pagecount)
3164                                 break;
3165                         wpos = pos;
3166                         wsize = 0;
3167                 }
3168                 DPRINTF(("committing page %"Z"u", pgno));
3169                 next_pos = pos + size;
3170                 iov[n].iov_len = size;
3171                 iov[n].iov_base = (char *)dp;
3172                 wsize += size;
3173                 n++;
3174 #endif  /* _WIN32 */
3175         }
3176
3177         /* MIPS has cache coherency issues, this is a no-op everywhere else
3178          * Note: for any size >= on-chip cache size, entire on-chip cache is
3179          * flushed.
3180          */
3181         CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE);
3182
3183         for (i = keep; ++i <= pagecount; ) {
3184                 dp = dl[i].mptr;
3185                 /* This is a page we skipped above */
3186                 if (!dl[i].mid) {
3187                         dl[++j] = dl[i];
3188                         dl[j].mid = dp->mp_pgno;
3189                         continue;
3190                 }
3191                 mdb_dpage_free(env, dp);
3192         }
3193
3194 done:
3195         i--;
3196         txn->mt_dirty_room += i - j;
3197         dl[0].mid = j;
3198         return MDB_SUCCESS;
3199 }
3200
3201 int
3202 mdb_txn_commit(MDB_txn *txn)
3203 {
3204         int             rc;
3205         unsigned int i;
3206         MDB_env *env;
3207
3208         if (txn == NULL || txn->mt_env == NULL)
3209                 return EINVAL;
3210
3211         if (txn->mt_child) {
3212                 rc = mdb_txn_commit(txn->mt_child);
3213                 txn->mt_child = NULL;
3214                 if (rc)
3215                         goto fail;
3216         }
3217
3218         env = txn->mt_env;
3219
3220         if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
3221                 mdb_dbis_update(txn, 1);
3222                 txn->mt_numdbs = 2; /* so txn_abort() doesn't close any new handles */
3223                 mdb_txn_abort(txn);
3224                 return MDB_SUCCESS;
3225         }
3226
3227         if (F_ISSET(txn->mt_flags, MDB_TXN_ERROR)) {
3228                 DPUTS("error flag is set, can't commit");
3229                 if (txn->mt_parent)
3230                         txn->mt_parent->mt_flags |= MDB_TXN_ERROR;
3231                 rc = MDB_BAD_TXN;
3232                 goto fail;
3233         }
3234
3235         if (txn->mt_parent) {
3236                 MDB_txn *parent = txn->mt_parent;
3237                 MDB_page **lp;
3238                 MDB_ID2L dst, src;
3239                 MDB_IDL pspill;
3240                 unsigned x, y, len, ps_len;
3241
3242                 /* Append our free list to parent's */
3243                 rc = mdb_midl_append_list(&parent->mt_free_pgs, txn->mt_free_pgs);
3244                 if (rc)
3245                         goto fail;
3246                 mdb_midl_free(txn->mt_free_pgs);
3247                 /* Failures after this must either undo the changes
3248                  * to the parent or set MDB_TXN_ERROR in the parent.
3249                  */
3250
3251                 parent->mt_next_pgno = txn->mt_next_pgno;
3252                 parent->mt_flags = txn->mt_flags;
3253
3254                 /* Merge our cursors into parent's and close them */
3255                 mdb_cursors_close(txn, 1);
3256
3257                 /* Update parent's DB table. */
3258                 memcpy(parent->mt_dbs, txn->mt_dbs, txn->mt_numdbs * sizeof(MDB_db));
3259                 parent->mt_numdbs = txn->mt_numdbs;
3260                 parent->mt_dbflags[0] = txn->mt_dbflags[0];
3261                 parent->mt_dbflags[1] = txn->mt_dbflags[1];
3262                 for (i=2; i<txn->mt_numdbs; i++) {
3263                         /* preserve parent's DB_NEW status */
3264                         x = parent->mt_dbflags[i] & DB_NEW;
3265                         parent->mt_dbflags[i] = txn->mt_dbflags[i] | x;
3266                 }
3267
3268                 dst = parent->mt_u.dirty_list;
3269                 src = txn->mt_u.dirty_list;
3270                 /* Remove anything in our dirty list from parent's spill list */
3271                 if ((pspill = parent->mt_spill_pgs) && (ps_len = pspill[0])) {
3272                         x = y = ps_len;
3273                         pspill[0] = (pgno_t)-1;
3274                         /* Mark our dirty pages as deleted in parent spill list */
3275                         for (i=0, len=src[0].mid; ++i <= len; ) {
3276                                 MDB_ID pn = src[i].mid << 1;
3277                                 while (pn > pspill[x])
3278                                         x--;
3279                                 if (pn == pspill[x]) {
3280                                         pspill[x] = 1;
3281                                         y = --x;
3282                                 }
3283                         }
3284                         /* Squash deleted pagenums if we deleted any */
3285                         for (x=y; ++x <= ps_len; )
3286                                 if (!(pspill[x] & 1))
3287                                         pspill[++y] = pspill[x];
3288                         pspill[0] = y;
3289                 }
3290
3291                 /* Find len = length of merging our dirty list with parent's */
3292                 x = dst[0].mid;
3293                 dst[0].mid = 0;         /* simplify loops */
3294                 if (parent->mt_parent) {
3295                         len = x + src[0].mid;
3296                         y = mdb_mid2l_search(src, dst[x].mid + 1) - 1;
3297                         for (i = x; y && i; y--) {
3298                                 pgno_t yp = src[y].mid;
3299                                 while (yp < dst[i].mid)
3300                                         i--;
3301                                 if (yp == dst[i].mid) {
3302                                         i--;
3303                                         len--;
3304                                 }
3305                         }
3306                 } else { /* Simplify the above for single-ancestor case */
3307                         len = MDB_IDL_UM_MAX - txn->mt_dirty_room;
3308                 }
3309                 /* Merge our dirty list with parent's */
3310                 y = src[0].mid;
3311                 for (i = len; y; dst[i--] = src[y--]) {
3312                         pgno_t yp = src[y].mid;
3313                         while (yp < dst[x].mid)
3314                                 dst[i--] = dst[x--];
3315                         if (yp == dst[x].mid)
3316                                 free(dst[x--].mptr);
3317                 }
3318                 mdb_tassert(txn, i == x);
3319                 dst[0].mid = len;
3320                 free(txn->mt_u.dirty_list);
3321                 parent->mt_dirty_room = txn->mt_dirty_room;
3322                 if (txn->mt_spill_pgs) {
3323                         if (parent->mt_spill_pgs) {
3324                                 /* TODO: Prevent failure here, so parent does not fail */
3325                                 rc = mdb_midl_append_list(&parent->mt_spill_pgs, txn->mt_spill_pgs);
3326                                 if (rc)
3327                                         parent->mt_flags |= MDB_TXN_ERROR;
3328                                 mdb_midl_free(txn->mt_spill_pgs);
3329                                 mdb_midl_sort(parent->mt_spill_pgs);
3330                         } else {
3331                                 parent->mt_spill_pgs = txn->mt_spill_pgs;
3332                         }
3333                 }
3334
3335                 /* Append our loose page list to parent's */
3336                 for (lp = &parent->mt_loose_pgs; *lp; lp = &NEXT_LOOSE_PAGE(lp))
3337                         ;
3338                 *lp = txn->mt_loose_pgs;
3339                 parent->mt_loose_count += txn->mt_loose_count;
3340
3341                 parent->mt_child = NULL;
3342                 mdb_midl_free(((MDB_ntxn *)txn)->mnt_pgstate.mf_pghead);
3343                 free(txn);
3344                 return rc;
3345         }
3346
3347         if (txn != env->me_txn) {
3348                 DPUTS("attempt to commit unknown transaction");
3349                 rc = EINVAL;
3350                 goto fail;
3351         }
3352
3353         mdb_cursors_close(txn, 0);
3354
3355         if (!txn->mt_u.dirty_list[0].mid &&
3356                 !(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS)))
3357                 goto done;
3358
3359         DPRINTF(("committing txn %"Z"u %p on mdbenv %p, root page %"Z"u",
3360             txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root));
3361
3362         /* Update DB root pointers */
3363         if (txn->mt_numdbs > 2) {
3364                 MDB_cursor mc;
3365                 MDB_dbi i;
3366                 MDB_val data;
3367                 data.mv_size = sizeof(MDB_db);
3368
3369                 mdb_cursor_init(&mc, txn, MAIN_DBI, NULL);
3370                 for (i = 2; i < txn->mt_numdbs; i++) {
3371                         if (txn->mt_dbflags[i] & DB_DIRTY) {
3372                                 if (TXN_DBI_CHANGED(txn, i)) {
3373                                         rc = MDB_BAD_DBI;
3374                                         goto fail;
3375                                 }
3376                                 data.mv_data = &txn->mt_dbs[i];
3377                                 rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data, 0);
3378                                 if (rc)
3379                                         goto fail;
3380                         }
3381                 }
3382         }
3383
3384         rc = mdb_freelist_save(txn);
3385         if (rc)
3386                 goto fail;
3387
3388         mdb_midl_free(env->me_pghead);
3389         env->me_pghead = NULL;
3390         if (mdb_midl_shrink(&txn->mt_free_pgs))
3391                 env->me_free_pgs = txn->mt_free_pgs;
3392
3393 #if (MDB_DEBUG) > 2
3394         mdb_audit(txn);
3395 #endif
3396
3397         i = 0;
3398 #ifdef HAVE_FDATASYNC
3399         if (txn->mt_next_pgno * env->me_psize > env->me_size) {
3400                 i |= FGREW;
3401                 env->me_size = txn->mt_next_pgno * env->me_psize;
3402         }
3403 #endif
3404         if ((rc = mdb_page_flush(txn, 0)) ||
3405                 (rc = mdb_env_sync(env, i)) ||
3406                 (rc = mdb_env_write_meta(txn)))
3407                 goto fail;
3408
3409         /* Free P_LOOSE pages left behind in dirty_list */
3410         if (!(env->me_flags & MDB_WRITEMAP))
3411                 mdb_dlist_free(txn);
3412
3413 done:
3414         env->me_pglast = 0;
3415         env->me_txn = NULL;
3416         mdb_dbis_update(txn, 1);
3417
3418         if (env->me_txns)
3419                 UNLOCK_MUTEX_W(env);
3420         if (txn != env->me_txn0)
3421                 free(txn);
3422
3423         return MDB_SUCCESS;
3424
3425 fail:
3426         mdb_txn_abort(txn);
3427         return rc;
3428 }
3429
3430 /** Read the environment parameters of a DB environment before
3431  * mapping it into memory.
3432  * @param[in] env the environment handle
3433  * @param[out] meta address of where to store the meta information
3434  * @return 0 on success, non-zero on failure.
3435  */
3436 static int ESECT
3437 mdb_env_read_header(MDB_env *env, MDB_meta *meta)
3438 {
3439         MDB_metabuf     pbuf;
3440         MDB_page        *p;
3441         MDB_meta        *m;
3442         int                     i, rc, off;
3443         enum { Size = sizeof(pbuf) };
3444
3445         /* We don't know the page size yet, so use a minimum value.
3446          * Read both meta pages so we can use the latest one.
3447          */
3448
3449         for (i=off=0; i<2; i++, off = meta->mm_psize) {
3450 #ifdef _WIN32
3451                 DWORD len;
3452                 OVERLAPPED ov;
3453                 memset(&ov, 0, sizeof(ov));
3454                 ov.Offset = off;
3455                 rc = ReadFile(env->me_fd, &pbuf, Size, &len, &ov) ? (int)len : -1;
3456                 if (rc == -1 && ErrCode() == ERROR_HANDLE_EOF)
3457                         rc = 0;
3458 #else
3459                 rc = pread(env->me_fd, &pbuf, Size, off);
3460 #endif
3461                 if (rc != Size) {
3462                         if (rc == 0 && off == 0)
3463                                 return ENOENT;
3464                         rc = rc < 0 ? (int) ErrCode() : MDB_INVALID;
3465                         DPRINTF(("read: %s", mdb_strerror(rc)));
3466                         return rc;
3467                 }
3468
3469                 p = (MDB_page *)&pbuf;
3470
3471                 if (!F_ISSET(p->mp_flags, P_META)) {
3472                         DPRINTF(("page %"Z"u not a meta page", p->mp_pgno));
3473                         return MDB_INVALID;
3474                 }
3475
3476                 m = METADATA(p);
3477                 if (m->mm_magic != MDB_MAGIC) {
3478                         DPUTS("meta has invalid magic");
3479                         return MDB_INVALID;
3480                 }
3481
3482                 if (m->mm_version != MDB_DATA_VERSION) {
3483                         DPRINTF(("database is version %u, expected version %u",
3484                                 m->mm_version, MDB_DATA_VERSION));
3485                         return MDB_VERSION_MISMATCH;
3486                 }
3487
3488                 if (off == 0 || m->mm_txnid > meta->mm_txnid)
3489                         *meta = *m;
3490         }
3491         return 0;
3492 }
3493
3494 static void ESECT
3495 mdb_env_init_meta0(MDB_env *env, MDB_meta *meta)
3496 {
3497         meta->mm_magic = MDB_MAGIC;
3498         meta->mm_version = MDB_DATA_VERSION;
3499         meta->mm_mapsize = env->me_mapsize;
3500         meta->mm_psize = env->me_psize;
3501         meta->mm_last_pg = 1;
3502         meta->mm_flags = env->me_flags & 0xffff;
3503         meta->mm_flags |= MDB_INTEGERKEY;
3504         meta->mm_dbs[0].md_root = P_INVALID;
3505         meta->mm_dbs[1].md_root = P_INVALID;
3506 }
3507
3508 /** Write the environment parameters of a freshly created DB environment.
3509  * @param[in] env the environment handle
3510  * @param[out] meta address of where to store the meta information
3511  * @return 0 on success, non-zero on failure.
3512  */
3513 static int ESECT
3514 mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
3515 {
3516         MDB_page *p, *q;
3517         int rc;
3518         unsigned int     psize;
3519 #ifdef _WIN32
3520         DWORD len;
3521         OVERLAPPED ov;
3522         memset(&ov, 0, sizeof(ov));
3523 #define DO_PWRITE(rc, fd, ptr, size, len, pos)  do { \
3524         ov.Offset = pos;        \
3525         rc = WriteFile(fd, ptr, size, &len, &ov);       } while(0)
3526 #else
3527         int len;
3528 #define DO_PWRITE(rc, fd, ptr, size, len, pos)  do { \
3529         len = pwrite(fd, ptr, size, pos);       \
3530         rc = (len >= 0); } while(0)
3531 #endif
3532
3533         DPUTS("writing new meta page");
3534
3535         psize = env->me_psize;
3536
3537         mdb_env_init_meta0(env, meta);
3538
3539         p = calloc(2, psize);
3540         p->mp_pgno = 0;
3541         p->mp_flags = P_META;
3542         *(MDB_meta *)METADATA(p) = *meta;
3543
3544         q = (MDB_page *)((char *)p + psize);
3545         q->mp_pgno = 1;
3546         q->mp_flags = P_META;
3547         *(MDB_meta *)METADATA(q) = *meta;
3548
3549         DO_PWRITE(rc, env->me_fd, p, psize * 2, len, 0);
3550         if (!rc)
3551                 rc = ErrCode();
3552         else if ((unsigned) len == psize * 2)
3553                 rc = MDB_SUCCESS;
3554         else
3555                 rc = ENOSPC;
3556         free(p);
3557         return rc;
3558 }
3559
3560 /** Update the environment info to commit a transaction.
3561  * @param[in] txn the transaction that's being committed
3562  * @return 0 on success, non-zero on failure.
3563  */
3564 static int
3565 mdb_env_write_meta(MDB_txn *txn)
3566 {
3567         MDB_env *env;
3568         MDB_meta        meta, metab, *mp;
3569         size_t mapsize;
3570         off_t off;
3571         int rc, len, toggle;
3572         char *ptr;
3573         HANDLE mfd;
3574 #ifdef _WIN32
3575         OVERLAPPED ov;
3576 #else
3577         int r2;
3578 #endif
3579
3580         toggle = txn->mt_txnid & 1;
3581         DPRINTF(("writing meta page %d for root page %"Z"u",
3582                 toggle, txn->mt_dbs[MAIN_DBI].md_root));
3583
3584         env = txn->mt_env;
3585         mp = env->me_metas[toggle];
3586         mapsize = env->me_metas[toggle ^ 1]->mm_mapsize;
3587         /* Persist any increases of mapsize config */
3588         if (mapsize < env->me_mapsize)
3589                 mapsize = env->me_mapsize;
3590
3591         if (env->me_flags & MDB_WRITEMAP) {
3592                 mp->mm_mapsize = mapsize;
3593                 mp->mm_dbs[0] = txn->mt_dbs[0];
3594                 mp->mm_dbs[1] = txn->mt_dbs[1];
3595                 mp->mm_last_pg = txn->mt_next_pgno - 1;
3596                 mp->mm_txnid = txn->mt_txnid;
3597                 if (!(env->me_flags & (MDB_NOMETASYNC|MDB_NOSYNC))) {
3598                         unsigned meta_size = env->me_psize;
3599                         rc = (env->me_flags & MDB_MAPASYNC) ? MS_ASYNC : MS_SYNC;
3600                         ptr = env->me_map;
3601                         if (toggle) {
3602 #ifndef _WIN32  /* POSIX msync() requires ptr = start of OS page */
3603                                 if (meta_size < env->me_os_psize)
3604                                         meta_size += meta_size;
3605                                 else
3606 #endif
3607                                         ptr += meta_size;
3608                         }
3609                         if (MDB_MSYNC(ptr, meta_size, rc)) {
3610                                 rc = ErrCode();
3611                                 goto fail;
3612                         }
3613                 }
3614                 goto done;
3615         }
3616         metab.mm_txnid = env->me_metas[toggle]->mm_txnid;
3617         metab.mm_last_pg = env->me_metas[toggle]->mm_last_pg;
3618
3619         meta.mm_mapsize = mapsize;
3620         meta.mm_dbs[0] = txn->mt_dbs[0];
3621         meta.mm_dbs[1] = txn->mt_dbs[1];
3622         meta.mm_last_pg = txn->mt_next_pgno - 1;
3623         meta.mm_txnid = txn->mt_txnid;
3624
3625         off = offsetof(MDB_meta, mm_mapsize);
3626         ptr = (char *)&meta + off;
3627         len = sizeof(MDB_meta) - off;
3628         if (toggle)
3629                 off += env->me_psize;
3630         off += PAGEHDRSZ;
3631
3632         /* Write to the SYNC fd */
3633         mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
3634                 env->me_fd : env->me_mfd;
3635 #ifdef _WIN32
3636         {
3637                 memset(&ov, 0, sizeof(ov));
3638                 ov.Offset = off;
3639                 if (!WriteFile(mfd, ptr, len, (DWORD *)&rc, &ov))
3640                         rc = -1;
3641         }
3642 #else
3643         rc = pwrite(mfd, ptr, len, off);
3644 #endif
3645         if (rc != len) {
3646                 rc = rc < 0 ? ErrCode() : EIO;
3647                 DPUTS("write failed, disk error?");
3648                 /* On a failure, the pagecache still contains the new data.
3649                  * Write some old data back, to prevent it from being used.
3650                  * Use the non-SYNC fd; we know it will fail anyway.
3651                  */
3652                 meta.mm_last_pg = metab.mm_last_pg;
3653                 meta.mm_txnid = metab.mm_txnid;
3654 #ifdef _WIN32
3655                 memset(&ov, 0, sizeof(ov));
3656                 ov.Offset = off;
3657                 WriteFile(env->me_fd, ptr, len, NULL, &ov);
3658 #else
3659                 r2 = pwrite(env->me_fd, ptr, len, off);
3660                 (void)r2;       /* Silence warnings. We don't care about pwrite's return value */
3661 #endif
3662 fail:
3663                 env->me_flags |= MDB_FATAL_ERROR;
3664                 return rc;
3665         }
3666         /* MIPS has cache coherency issues, this is a no-op everywhere else */
3667         CACHEFLUSH(env->me_map + off, len, DCACHE);
3668 done:
3669         /* Memory ordering issues are irrelevant; since the entire writer
3670          * is wrapped by wmutex, all of these changes will become visible
3671          * after the wmutex is unlocked. Since the DB is multi-version,
3672          * readers will get consistent data regardless of how fresh or
3673          * how stale their view of these values is.
3674          */
3675         if (env->me_txns)
3676                 env->me_txns->mti_txnid = txn->mt_txnid;
3677
3678         return MDB_SUCCESS;
3679 }
3680
3681 /** Check both meta pages to see which one is newer.
3682  * @param[in] env the environment handle
3683  * @return meta toggle (0 or 1).
3684  */
3685 static int
3686 mdb_env_pick_meta(const MDB_env *env)
3687 {
3688         return (env->me_metas[0]->mm_txnid < env->me_metas[1]->mm_txnid);
3689 }
3690
3691 int ESECT
3692 mdb_env_create(MDB_env **env)
3693 {
3694         MDB_env *e;
3695
3696         e = calloc(1, sizeof(MDB_env));
3697         if (!e)
3698                 return ENOMEM;
3699
3700         e->me_maxreaders = DEFAULT_READERS;
3701         e->me_maxdbs = e->me_numdbs = 2;
3702         e->me_fd = INVALID_HANDLE_VALUE;
3703         e->me_lfd = INVALID_HANDLE_VALUE;
3704         e->me_mfd = INVALID_HANDLE_VALUE;
3705 #ifdef MDB_USE_POSIX_SEM
3706         e->me_rmutex = SEM_FAILED;
3707         e->me_wmutex = SEM_FAILED;
3708 #endif
3709         e->me_pid = getpid();
3710         GET_PAGESIZE(e->me_os_psize);
3711         VGMEMP_CREATE(e,0,0);
3712         *env = e;
3713         return MDB_SUCCESS;
3714 }
3715
3716 static int ESECT
3717 mdb_env_map(MDB_env *env, void *addr)
3718 {
3719         MDB_page *p;
3720         unsigned int flags = env->me_flags;
3721 #ifdef _WIN32
3722         int rc;
3723         HANDLE mh;
3724         LONG sizelo, sizehi;
3725         size_t msize;
3726
3727         if (flags & MDB_RDONLY) {
3728                 /* Don't set explicit map size, use whatever exists */
3729                 msize = 0;
3730                 sizelo = 0;
3731                 sizehi = 0;
3732         } else {
3733                 msize = env->me_mapsize;
3734                 sizelo = msize & 0xffffffff;
3735                 sizehi = msize >> 16 >> 16; /* only needed on Win64 */
3736
3737                 /* Windows won't create mappings for zero length files.
3738                  * and won't map more than the file size.
3739                  * Just set the maxsize right now.
3740                  */
3741                 if (SetFilePointer(env->me_fd, sizelo, &sizehi, 0) != (DWORD)sizelo
3742                         || !SetEndOfFile(env->me_fd)
3743                         || SetFilePointer(env->me_fd, 0, NULL, 0) != 0)
3744                         return ErrCode();
3745         }
3746
3747         mh = CreateFileMapping(env->me_fd, NULL, flags & MDB_WRITEMAP ?
3748                 PAGE_READWRITE : PAGE_READONLY,
3749                 sizehi, sizelo, NULL);
3750         if (!mh)
3751                 return ErrCode();
3752         env->me_map = MapViewOfFileEx(mh, flags & MDB_WRITEMAP ?
3753                 FILE_MAP_WRITE : FILE_MAP_READ,
3754                 0, 0, msize, addr);
3755         rc = env->me_map ? 0 : ErrCode();
3756         CloseHandle(mh);
3757         if (rc)
3758                 return rc;
3759 #else
3760         int prot = PROT_READ;
3761         if (flags & MDB_WRITEMAP) {
3762                 prot |= PROT_WRITE;
3763                 if (ftruncate(env->me_fd, env->me_mapsize) < 0)
3764                         return ErrCode();
3765         }
3766         env->me_map = mmap(addr, env->me_mapsize, prot, MAP_SHARED,
3767                 env->me_fd, 0);
3768         if (env->me_map == MAP_FAILED) {
3769                 env->me_map = NULL;
3770                 return ErrCode();
3771         }
3772
3773         if (flags & MDB_NORDAHEAD) {
3774                 /* Turn off readahead. It's harmful when the DB is larger than RAM. */
3775 #ifdef MADV_RANDOM
3776                 madvise(env->me_map, env->me_mapsize, MADV_RANDOM);
3777 #else
3778 #ifdef POSIX_MADV_RANDOM
3779                 posix_madvise(env->me_map, env->me_mapsize, POSIX_MADV_RANDOM);
3780 #endif /* POSIX_MADV_RANDOM */
3781 #endif /* MADV_RANDOM */
3782         }
3783 #endif /* _WIN32 */
3784
3785         /* Can happen because the address argument to mmap() is just a
3786          * hint.  mmap() can pick another, e.g. if the range is in use.
3787          * The MAP_FIXED flag would prevent that, but then mmap could
3788          * instead unmap existing pages to make room for the new map.
3789          */
3790         if (addr && env->me_map != addr)
3791                 return EBUSY;   /* TODO: Make a new MDB_* error code? */
3792
3793         p = (MDB_page *)env->me_map;
3794         env->me_metas[0] = METADATA(p);
3795         env->me_metas[1] = (MDB_meta *)((char *)env->me_metas[0] + env->me_psize);
3796
3797         return MDB_SUCCESS;
3798 }
3799
3800 int ESECT
3801 mdb_env_set_mapsize(MDB_env *env, size_t size)
3802 {
3803         /* If env is already open, caller is responsible for making
3804          * sure there are no active txns.
3805          */
3806         if (env->me_map) {
3807                 int rc;
3808                 void *old;
3809                 if (env->me_txn)
3810                         return EINVAL;
3811                 if (!size)
3812                         size = env->me_metas[mdb_env_pick_meta(env)]->mm_mapsize;
3813                 else if (size < env->me_mapsize) {
3814                         /* If the configured size is smaller, make sure it's
3815                          * still big enough. Silently round up to minimum if not.
3816                          */
3817                         size_t minsize = (env->me_metas[mdb_env_pick_meta(env)]->mm_last_pg + 1) * env->me_psize;
3818                         if (size < minsize)
3819                                 size = minsize;
3820                 }
3821                 munmap(env->me_map, env->me_mapsize);
3822                 env->me_mapsize = size;
3823                 old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL;
3824                 rc = mdb_env_map(env, old);
3825                 if (rc)
3826                         return rc;
3827         }
3828         env->me_mapsize = size;
3829         if (env->me_psize)
3830                 env->me_maxpg = env->me_mapsize / env->me_psize;
3831         return MDB_SUCCESS;
3832 }
3833
3834 int ESECT
3835 mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
3836 {
3837         if (env->me_map)
3838                 return EINVAL;
3839         env->me_maxdbs = dbs + 2; /* Named databases + main and free DB */
3840         return MDB_SUCCESS;
3841 }
3842
3843 int ESECT
3844 mdb_env_set_maxreaders(MDB_env *env, unsigned int readers)
3845 {
3846         if (env->me_map || readers < 1)
3847                 return EINVAL;
3848         env->me_maxreaders = readers;
3849         return MDB_SUCCESS;
3850 }
3851
3852 int ESECT
3853 mdb_env_get_maxreaders(MDB_env *env, unsigned int *readers)
3854 {
3855         if (!env || !readers)
3856                 return EINVAL;
3857         *readers = env->me_maxreaders;
3858         return MDB_SUCCESS;
3859 }
3860
3861 static int ESECT
3862 mdb_fsize(HANDLE fd, size_t *size)
3863 {
3864 #ifdef _WIN32
3865         LARGE_INTEGER fsize;
3866
3867         if (!GetFileSizeEx(fd, &fsize))
3868                 return ErrCode();
3869
3870         *size = fsize.QuadPart;
3871 #else
3872         struct stat st;
3873
3874         if (fstat(fd, &st))
3875                 return ErrCode();
3876
3877         *size = st.st_size;
3878 #endif
3879         return MDB_SUCCESS;
3880 }
3881
3882 /** Further setup required for opening an LMDB environment
3883  */
3884 static int ESECT
3885 mdb_env_open2(MDB_env *env)
3886 {
3887         unsigned int flags = env->me_flags;
3888         int i, newenv = 0, rc;
3889         MDB_meta meta;
3890
3891 #ifdef _WIN32
3892         /* See if we should use QueryLimited */
3893         rc = GetVersion();
3894         if ((rc & 0xff) > 5)
3895                 env->me_pidquery = MDB_PROCESS_QUERY_LIMITED_INFORMATION;
3896         else
3897                 env->me_pidquery = PROCESS_QUERY_INFORMATION;
3898 #endif /* _WIN32 */
3899
3900         memset(&meta, 0, sizeof(meta));
3901
3902         if ((i = mdb_env_read_header(env, &meta)) != 0) {
3903                 if (i != ENOENT)
3904                         return i;
3905                 DPUTS("new mdbenv");
3906                 newenv = 1;
3907                 env->me_psize = env->me_os_psize;
3908                 if (env->me_psize > MAX_PAGESIZE)
3909                         env->me_psize = MAX_PAGESIZE;
3910         } else {
3911                 env->me_psize = meta.mm_psize;
3912         }
3913
3914         /* Was a mapsize configured? */
3915         if (!env->me_mapsize) {
3916                 /* If this is a new environment, take the default,
3917                  * else use the size recorded in the existing env.
3918                  */
3919                 env->me_mapsize = newenv ? DEFAULT_MAPSIZE : meta.mm_mapsize;
3920         } else if (env->me_mapsize < meta.mm_mapsize) {
3921                 /* If the configured size is smaller, make sure it's
3922                  * still big enough. Silently round up to minimum if not.
3923                  */
3924                 size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize;
3925                 if (env->me_mapsize < minsize)
3926                         env->me_mapsize = minsize;
3927         }
3928
3929         rc = mdb_fsize(env->me_fd, &env->me_size);
3930         if (rc)
3931                 return rc;
3932
3933         rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta.mm_address : NULL);
3934         if (rc)
3935                 return rc;
3936
3937         if (newenv) {
3938                 if (flags & MDB_FIXEDMAP)
3939                         meta.mm_address = env->me_map;
3940                 i = mdb_env_init_meta(env, &meta);
3941                 if (i != MDB_SUCCESS) {
3942                         return i;
3943                 }
3944         }
3945
3946         env->me_maxfree_1pg = (env->me_psize - PAGEHDRSZ) / sizeof(pgno_t) - 1;
3947         env->me_nodemax = (((env->me_psize - PAGEHDRSZ) / MDB_MINKEYS) & -2)
3948                 - sizeof(indx_t);
3949 #if !(MDB_MAXKEYSIZE)
3950         env->me_maxkey = env->me_nodemax - (NODESIZE + sizeof(MDB_db));
3951 #endif
3952         env->me_maxpg = env->me_mapsize / env->me_psize;
3953
3954 #if MDB_DEBUG
3955         {
3956                 int toggle = mdb_env_pick_meta(env);
3957                 MDB_db *db = &env->me_metas[toggle]->mm_dbs[MAIN_DBI];
3958
3959                 DPRINTF(("opened database version %u, pagesize %u",
3960                         env->me_metas[0]->mm_version, env->me_psize));
3961                 DPRINTF(("using meta page %d",    toggle));
3962                 DPRINTF(("depth: %u",             db->md_depth));
3963                 DPRINTF(("entries: %"Z"u",        db->md_entries));
3964                 DPRINTF(("branch pages: %"Z"u",   db->md_branch_pages));
3965                 DPRINTF(("leaf pages: %"Z"u",     db->md_leaf_pages));
3966                 DPRINTF(("overflow pages: %"Z"u", db->md_overflow_pages));
3967                 DPRINTF(("root: %"Z"u",           db->md_root));
3968         }
3969 #endif
3970
3971         return MDB_SUCCESS;
3972 }
3973
3974
3975 /** Release a reader thread's slot in the reader lock table.
3976  *      This function is called automatically when a thread exits.
3977  * @param[in] ptr This points to the slot in the reader lock table.
3978  */
3979 static void
3980 mdb_env_reader_dest(void *ptr)
3981 {
3982         MDB_reader *reader = ptr;
3983
3984         reader->mr_pid = 0;
3985 }
3986
3987 #ifdef _WIN32
3988 /** Junk for arranging thread-specific callbacks on Windows. This is
3989  *      necessarily platform and compiler-specific. Windows supports up
3990  *      to 1088 keys. Let's assume nobody opens more than 64 environments
3991  *      in a single process, for now. They can override this if needed.
3992  */
3993 #ifndef MAX_TLS_KEYS
3994 #define MAX_TLS_KEYS    64
3995 #endif
3996 static pthread_key_t mdb_tls_keys[MAX_TLS_KEYS];
3997 static int mdb_tls_nkeys;
3998
3999 static void NTAPI mdb_tls_callback(PVOID module, DWORD reason, PVOID ptr)
4000 {
4001         int i;
4002         switch(reason) {
4003         case DLL_PROCESS_ATTACH: break;
4004         case DLL_THREAD_ATTACH: break;
4005         case DLL_THREAD_DETACH:
4006                 for (i=0; i<mdb_tls_nkeys; i++) {
4007                         MDB_reader *r = pthread_getspecific(mdb_tls_keys[i]);
4008                         if (r) {
4009                                 mdb_env_reader_dest(r);
4010                         }
4011                 }
4012                 break;
4013         case DLL_PROCESS_DETACH: break;
4014         }
4015 }
4016 #ifdef __GNUC__
4017 #ifdef _WIN64
4018 const PIMAGE_TLS_CALLBACK mdb_tls_cbp __attribute__((section (".CRT$XLB"))) = mdb_tls_callback;
4019 #else
4020 PIMAGE_TLS_CALLBACK mdb_tls_cbp __attribute__((section (".CRT$XLB"))) = mdb_tls_callback;
4021 #endif
4022 #else
4023 #ifdef _WIN64
4024 /* Force some symbol references.
4025  *      _tls_used forces the linker to create the TLS directory if not already done
4026  *      mdb_tls_cbp prevents whole-program-optimizer from dropping the symbol.
4027  */
4028 #pragma comment(linker, "/INCLUDE:_tls_used")
4029 #pragma comment(linker, "/INCLUDE:mdb_tls_cbp")
4030 #pragma const_seg(".CRT$XLB")
4031 extern const PIMAGE_TLS_CALLBACK mdb_tls_cbp;
4032 const PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
4033 #pragma const_seg()
4034 #else   /* _WIN32 */
4035 #pragma comment(linker, "/INCLUDE:__tls_used")
4036 #pragma comment(linker, "/INCLUDE:_mdb_tls_cbp")
4037 #pragma data_seg(".CRT$XLB")
4038 PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
4039 #pragma data_seg()
4040 #endif  /* WIN 32/64 */
4041 #endif  /* !__GNUC__ */
4042 #endif
4043
4044 /** Downgrade the exclusive lock on the region back to shared */
4045 static int ESECT
4046 mdb_env_share_locks(MDB_env *env, int *excl)
4047 {
4048         int rc = 0, toggle = mdb_env_pick_meta(env);
4049
4050         env->me_txns->mti_txnid = env->me_metas[toggle]->mm_txnid;
4051
4052 #ifdef _WIN32
4053         {
4054                 OVERLAPPED ov;
4055                 /* First acquire a shared lock. The Unlock will
4056                  * then release the existing exclusive lock.
4057                  */
4058                 memset(&ov, 0, sizeof(ov));
4059                 if (!LockFileEx(env->me_lfd, 0, 0, 1, 0, &ov)) {
4060                         rc = ErrCode();
4061                 } else {
4062                         UnlockFile(env->me_lfd, 0, 0, 1, 0);
4063                         *excl = 0;
4064                 }
4065         }
4066 #else
4067         {
4068                 struct flock lock_info;
4069                 /* The shared lock replaces the existing lock */
4070                 memset((void *)&lock_info, 0, sizeof(lock_info));
4071                 lock_info.l_type = F_RDLCK;
4072                 lock_info.l_whence = SEEK_SET;
4073                 lock_info.l_start = 0;
4074                 lock_info.l_len = 1;
4075                 while ((rc = fcntl(env->me_lfd, F_SETLK, &lock_info)) &&
4076                                 (rc = ErrCode()) == EINTR) ;
4077                 *excl = rc ? -1 : 0;    /* error may mean we lost the lock */
4078         }
4079 #endif
4080
4081         return rc;
4082 }
4083
4084 /** Try to get exclusive lock, otherwise shared.
4085  *      Maintain *excl = -1: no/unknown lock, 0: shared, 1: exclusive.
4086  */
4087 static int ESECT
4088 mdb_env_excl_lock(MDB_env *env, int *excl)
4089 {
4090         int rc = 0;
4091 #ifdef _WIN32
4092         if (LockFile(env->me_lfd, 0, 0, 1, 0)) {
4093                 *excl = 1;
4094         } else {
4095                 OVERLAPPED ov;
4096                 memset(&ov, 0, sizeof(ov));
4097                 if (LockFileEx(env->me_lfd, 0, 0, 1, 0, &ov)) {
4098                         *excl = 0;
4099                 } else {
4100                         rc = ErrCode();
4101                 }
4102         }
4103 #else
4104         struct flock lock_info;
4105         memset((void *)&lock_info, 0, sizeof(lock_info));
4106         lock_info.l_type = F_WRLCK;
4107         lock_info.l_whence = SEEK_SET;
4108         lock_info.l_start = 0;
4109         lock_info.l_len = 1;
4110         while ((rc = fcntl(env->me_lfd, F_SETLK, &lock_info)) &&
4111                         (rc = ErrCode()) == EINTR) ;
4112         if (!rc) {
4113                 *excl = 1;
4114         } else
4115 # ifdef MDB_USE_POSIX_SEM
4116         if (*excl < 0) /* always true when !MDB_USE_POSIX_SEM */
4117 # endif
4118         {
4119                 lock_info.l_type = F_RDLCK;
4120                 while ((rc = fcntl(env->me_lfd, F_SETLKW, &lock_info)) &&
4121                                 (rc = ErrCode()) == EINTR) ;
4122                 if (rc == 0)
4123                         *excl = 0;
4124         }
4125 #endif
4126         return rc;
4127 }
4128
4129 #ifdef MDB_USE_HASH
4130 /*
4131  * hash_64 - 64 bit Fowler/Noll/Vo-0 FNV-1a hash code
4132  *
4133  * @(#) $Revision: 5.1 $
4134  * @(#) $Id: hash_64a.c,v 5.1 2009/06/30 09:01:38 chongo Exp $
4135  * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64a.c,v $
4136  *
4137  *        http://www.isthe.com/chongo/tech/comp/fnv/index.html
4138  *
4139  ***
4140  *
4141  * Please do not copyright this code.  This code is in the public domain.
4142  *
4143  * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
4144  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
4145  * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
4146  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
4147  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
4148  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4149  * PERFORMANCE OF THIS SOFTWARE.
4150  *
4151  * By:
4152  *      chongo <Landon Curt Noll> /\oo/\
4153  *        http://www.isthe.com/chongo/
4154  *
4155  * Share and Enjoy!     :-)
4156  */
4157
4158 typedef unsigned long long      mdb_hash_t;
4159 #define MDB_HASH_INIT ((mdb_hash_t)0xcbf29ce484222325ULL)
4160
4161 /** perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer
4162  * @param[in] val       value to hash
4163  * @param[in] hval      initial value for hash
4164  * @return 64 bit hash
4165  *
4166  * NOTE: To use the recommended 64 bit FNV-1a hash, use MDB_HASH_INIT as the
4167  *       hval arg on the first call.
4168  */
4169 static mdb_hash_t
4170 mdb_hash_val(MDB_val *val, mdb_hash_t hval)
4171 {
4172         unsigned char *s = (unsigned char *)val->mv_data;       /* unsigned string */
4173         unsigned char *end = s + val->mv_size;
4174         /*
4175          * FNV-1a hash each octet of the string
4176          */
4177         while (s < end) {
4178                 /* xor the bottom with the current octet */
4179                 hval ^= (mdb_hash_t)*s++;
4180
4181                 /* multiply by the 64 bit FNV magic prime mod 2^64 */
4182                 hval += (hval << 1) + (hval << 4) + (hval << 5) +
4183                         (hval << 7) + (hval << 8) + (hval << 40);
4184         }
4185         /* return our new hash value */
4186         return hval;
4187 }
4188
4189 /** Hash the string and output the encoded hash.
4190  * This uses modified RFC1924 Ascii85 encoding to accommodate systems with
4191  * very short name limits. We don't care about the encoding being reversible,
4192  * we just want to preserve as many bits of the input as possible in a
4193  * small printable string.
4194  * @param[in] str string to hash
4195  * @param[out] encbuf an array of 11 chars to hold the hash
4196  */
4197 static const char mdb_a85[]= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
4198
4199 static void
4200 mdb_pack85(unsigned long l, char *out)
4201 {
4202         int i;
4203
4204         for (i=0; i<5; i++) {
4205                 *out++ = mdb_a85[l % 85];
4206                 l /= 85;
4207         }
4208 }
4209
4210 static void
4211 mdb_hash_enc(MDB_val *val, char *encbuf)
4212 {
4213         mdb_hash_t h = mdb_hash_val(val, MDB_HASH_INIT);
4214
4215         mdb_pack85(h, encbuf);
4216         mdb_pack85(h>>32, encbuf+5);
4217         encbuf[10] = '\0';
4218 }
4219 #endif
4220
4221 /** Open and/or initialize the lock region for the environment.
4222  * @param[in] env The LMDB environment.
4223  * @param[in] lpath The pathname of the file used for the lock region.
4224  * @param[in] mode The Unix permissions for the file, if we create it.
4225  * @param[in,out] excl In -1, out lock type: -1 none, 0 shared, 1 exclusive
4226  * @return 0 on success, non-zero on failure.
4227  */
4228 static int ESECT
4229 mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
4230 {
4231 #ifdef _WIN32
4232 #       define MDB_ERRCODE_ROFS ERROR_WRITE_PROTECT
4233 #else
4234 #       define MDB_ERRCODE_ROFS EROFS
4235 #ifdef O_CLOEXEC        /* Linux: Open file and set FD_CLOEXEC atomically */
4236 #       define MDB_CLOEXEC              O_CLOEXEC
4237 #else
4238         int fdflags;
4239 #       define MDB_CLOEXEC              0
4240 #endif
4241 #endif
4242         int rc;
4243         off_t size, rsize;
4244
4245 #ifdef _WIN32
4246         env->me_lfd = CreateFile(lpath, GENERIC_READ|GENERIC_WRITE,
4247                 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
4248                 FILE_ATTRIBUTE_NORMAL, NULL);
4249 #else
4250         env->me_lfd = open(lpath, O_RDWR|O_CREAT|MDB_CLOEXEC, mode);
4251 #endif
4252         if (env->me_lfd == INVALID_HANDLE_VALUE) {
4253                 rc = ErrCode();
4254                 if (rc == MDB_ERRCODE_ROFS && (env->me_flags & MDB_RDONLY)) {
4255                         return MDB_SUCCESS;
4256                 }
4257                 goto fail_errno;
4258         }
4259 #if ! ((MDB_CLOEXEC) || defined(_WIN32))
4260         /* Lose record locks when exec*() */
4261         if ((fdflags = fcntl(env->me_lfd, F_GETFD) | FD_CLOEXEC) >= 0)
4262                         fcntl(env->me_lfd, F_SETFD, fdflags);
4263 #endif
4264
4265         if (!(env->me_flags & MDB_NOTLS)) {
4266                 rc = pthread_key_create(&env->me_txkey, mdb_env_reader_dest);
4267                 if (rc)
4268                         goto fail;
4269                 env->me_flags |= MDB_ENV_TXKEY;
4270 #ifdef _WIN32
4271                 /* Windows TLS callbacks need help finding their TLS info. */
4272                 if (mdb_tls_nkeys >= MAX_TLS_KEYS) {
4273                         rc = MDB_TLS_FULL;
4274                         goto fail;
4275                 }
4276                 mdb_tls_keys[mdb_tls_nkeys++] = env->me_txkey;
4277 #endif
4278         }
4279
4280         /* Try to get exclusive lock. If we succeed, then
4281          * nobody is using the lock region and we should initialize it.
4282          */
4283         if ((rc = mdb_env_excl_lock(env, excl))) goto fail;
4284
4285 #ifdef _WIN32
4286         size = GetFileSize(env->me_lfd, NULL);
4287 #else
4288         size = lseek(env->me_lfd, 0, SEEK_END);
4289         if (size == -1) goto fail_errno;
4290 #endif
4291         rsize = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo);
4292         if (size < rsize && *excl > 0) {
4293 #ifdef _WIN32
4294                 if (SetFilePointer(env->me_lfd, rsize, NULL, FILE_BEGIN) != (DWORD)rsize
4295                         || !SetEndOfFile(env->me_lfd))
4296                         goto fail_errno;
4297 #else
4298                 if (ftruncate(env->me_lfd, rsize) != 0) goto fail_errno;
4299 #endif
4300         } else {
4301                 rsize = size;
4302                 size = rsize - sizeof(MDB_txninfo);
4303                 env->me_maxreaders = size/sizeof(MDB_reader) + 1;
4304         }
4305         {
4306 #ifdef _WIN32
4307                 HANDLE mh;
4308                 mh = CreateFileMapping(env->me_lfd, NULL, PAGE_READWRITE,
4309                         0, 0, NULL);
4310                 if (!mh) goto fail_errno;
4311                 env->me_txns = MapViewOfFileEx(mh, FILE_MAP_WRITE, 0, 0, rsize, NULL);
4312                 CloseHandle(mh);
4313                 if (!env->me_txns) goto fail_errno;
4314 #else
4315                 void *m = mmap(NULL, rsize, PROT_READ|PROT_WRITE, MAP_SHARED,
4316                         env->me_lfd, 0);
4317                 if (m == MAP_FAILED) goto fail_errno;
4318                 env->me_txns = m;
4319 #endif
4320         }
4321         if (*excl > 0) {
4322 #ifdef _WIN32
4323                 BY_HANDLE_FILE_INFORMATION stbuf;
4324                 struct {
4325                         DWORD volume;
4326                         DWORD nhigh;
4327                         DWORD nlow;
4328                 } idbuf;
4329                 MDB_val val;
4330                 char encbuf[11];
4331
4332                 if (!mdb_sec_inited) {
4333                         InitializeSecurityDescriptor(&mdb_null_sd,
4334                                 SECURITY_DESCRIPTOR_REVISION);
4335                         SetSecurityDescriptorDacl(&mdb_null_sd, TRUE, 0, FALSE);
4336                         mdb_all_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
4337                         mdb_all_sa.bInheritHandle = FALSE;
4338                         mdb_all_sa.lpSecurityDescriptor = &mdb_null_sd;
4339                         mdb_sec_inited = 1;
4340                 }
4341                 if (!GetFileInformationByHandle(env->me_lfd, &stbuf)) goto fail_errno;
4342                 idbuf.volume = stbuf.dwVolumeSerialNumber;
4343                 idbuf.nhigh  = stbuf.nFileIndexHigh;
4344                 idbuf.nlow   = stbuf.nFileIndexLow;
4345                 val.mv_data = &idbuf;
4346                 val.mv_size = sizeof(idbuf);
4347                 mdb_hash_enc(&val, encbuf);
4348                 sprintf(env->me_txns->mti_rmname, "Global\\MDBr%s", encbuf);
4349                 sprintf(env->me_txns->mti_wmname, "Global\\MDBw%s", encbuf);
4350                 env->me_rmutex = CreateMutex(&mdb_all_sa, FALSE, env->me_txns->mti_rmname);
4351                 if (!env->me_rmutex) goto fail_errno;
4352                 env->me_wmutex = CreateMutex(&mdb_all_sa, FALSE, env->me_txns->mti_wmname);
4353                 if (!env->me_wmutex) goto fail_errno;
4354 #elif defined(MDB_USE_POSIX_SEM)
4355                 struct stat stbuf;
4356                 struct {
4357                         dev_t dev;
4358                         ino_t ino;
4359                 } idbuf;
4360                 MDB_val val;
4361                 char encbuf[11];
4362
4363 #if defined(__NetBSD__)
4364 #define MDB_SHORT_SEMNAMES      1       /* limited to 14 chars */
4365 #endif
4366                 if (fstat(env->me_lfd, &stbuf)) goto fail_errno;
4367                 idbuf.dev = stbuf.st_dev;
4368                 idbuf.ino = stbuf.st_ino;
4369                 val.mv_data = &idbuf;
4370                 val.mv_size = sizeof(idbuf);
4371                 mdb_hash_enc(&val, encbuf);
4372 #ifdef MDB_SHORT_SEMNAMES
4373                 encbuf[9] = '\0';       /* drop name from 15 chars to 14 chars */
4374 #endif
4375                 sprintf(env->me_txns->mti_rmname, "/MDBr%s", encbuf);
4376                 sprintf(env->me_txns->mti_wmname, "/MDBw%s", encbuf);
4377                 /* Clean up after a previous run, if needed:  Try to
4378                  * remove both semaphores before doing anything else.
4379                  */
4380                 sem_unlink(env->me_txns->mti_rmname);
4381                 sem_unlink(env->me_txns->mti_wmname);
4382                 env->me_rmutex = sem_open(env->me_txns->mti_rmname,
4383                         O_CREAT|O_EXCL, mode, 1);
4384                 if (env->me_rmutex == SEM_FAILED) goto fail_errno;
4385                 env->me_wmutex = sem_open(env->me_txns->mti_wmname,
4386                         O_CREAT|O_EXCL, mode, 1);
4387                 if (env->me_wmutex == SEM_FAILED) goto fail_errno;
4388 #else   /* MDB_USE_POSIX_SEM */
4389                 pthread_mutexattr_t mattr;
4390
4391                 if ((rc = pthread_mutexattr_init(&mattr))
4392                         || (rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED))
4393                         || (rc = pthread_mutex_init(&env->me_txns->mti_mutex, &mattr))
4394                         || (rc = pthread_mutex_init(&env->me_txns->mti_wmutex, &mattr)))
4395                         goto fail;
4396                 pthread_mutexattr_destroy(&mattr);
4397 #endif  /* _WIN32 || MDB_USE_POSIX_SEM */
4398
4399                 env->me_txns->mti_magic = MDB_MAGIC;
4400                 env->me_txns->mti_format = MDB_LOCK_FORMAT;
4401                 env->me_txns->mti_txnid = 0;
4402                 env->me_txns->mti_numreaders = 0;
4403
4404         } else {
4405                 if (env->me_txns->mti_magic != MDB_MAGIC) {
4406                         DPUTS("lock region has invalid magic");
4407                         rc = MDB_INVALID;
4408                         goto fail;
4409                 }
4410                 if (env->me_txns->mti_format != MDB_LOCK_FORMAT) {
4411                         DPRINTF(("lock region has format+version 0x%x, expected 0x%x",
4412                                 env->me_txns->mti_format, MDB_LOCK_FORMAT));
4413                         rc = MDB_VERSION_MISMATCH;
4414                         goto fail;
4415                 }
4416                 rc = ErrCode();
4417                 if (rc && rc != EACCES && rc != EAGAIN) {
4418                         goto fail;
4419                 }
4420 #ifdef _WIN32
4421                 env->me_rmutex = OpenMutex(SYNCHRONIZE, FALSE, env->me_txns->mti_rmname);
4422                 if (!env->me_rmutex) goto fail_errno;
4423                 env->me_wmutex = OpenMutex(SYNCHRONIZE, FALSE, env->me_txns->mti_wmname);
4424                 if (!env->me_wmutex) goto fail_errno;
4425 #elif defined(MDB_USE_POSIX_SEM)
4426                 env->me_rmutex = sem_open(env->me_txns->mti_rmname, 0);
4427                 if (env->me_rmutex == SEM_FAILED) goto fail_errno;
4428                 env->me_wmutex = sem_open(env->me_txns->mti_wmname, 0);
4429                 if (env->me_wmutex == SEM_FAILED) goto fail_errno;
4430 #endif
4431         }
4432         return MDB_SUCCESS;
4433
4434 fail_errno:
4435         rc = ErrCode();
4436 fail:
4437         return rc;
4438 }
4439
4440         /** The name of the lock file in the DB environment */
4441 #define LOCKNAME        "/lock.mdb"
4442         /** The name of the data file in the DB environment */
4443 #define DATANAME        "/data.mdb"
4444         /** The suffix of the lock file when no subdir is used */
4445 #define LOCKSUFF        "-lock"
4446         /** Only a subset of the @ref mdb_env flags can be changed
4447          *      at runtime. Changing other flags requires closing the
4448          *      environment and re-opening it with the new flags.
4449          */
4450 #define CHANGEABLE      (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT)
4451 #define CHANGELESS      (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY|MDB_WRITEMAP| \
4452         MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD)
4453
4454 #if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS)
4455 # error "Persistent DB flags & env flags overlap, but both go in mm_flags"
4456 #endif
4457
4458 int ESECT
4459 mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
4460 {
4461         int             oflags, rc, len, excl = -1;
4462         char *lpath, *dpath;
4463
4464         if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS)))
4465                 return EINVAL;
4466
4467         len = strlen(path);
4468         if (flags & MDB_NOSUBDIR) {
4469                 rc = len + sizeof(LOCKSUFF) + len + 1;
4470         } else {
4471                 rc = len + sizeof(LOCKNAME) + len + sizeof(DATANAME);
4472         }
4473         lpath = malloc(rc);
4474         if (!lpath)
4475                 return ENOMEM;
4476         if (flags & MDB_NOSUBDIR) {
4477                 dpath = lpath + len + sizeof(LOCKSUFF);
4478                 sprintf(lpath, "%s" LOCKSUFF, path);
4479                 strcpy(dpath, path);
4480         } else {
4481                 dpath = lpath + len + sizeof(LOCKNAME);
4482                 sprintf(lpath, "%s" LOCKNAME, path);
4483                 sprintf(dpath, "%s" DATANAME, path);
4484         }
4485
4486         rc = MDB_SUCCESS;
4487         flags |= env->me_flags;
4488         if (flags & MDB_RDONLY) {
4489                 /* silently ignore WRITEMAP when we're only getting read access */
4490                 flags &= ~MDB_WRITEMAP;
4491         } else {
4492                 if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) &&
4493                           (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2)))))
4494                         rc = ENOMEM;
4495         }
4496         env->me_flags = flags |= MDB_ENV_ACTIVE;
4497         if (rc)
4498                 goto leave;
4499
4500         env->me_path = strdup(path);
4501         env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx));
4502         env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t));
4503         env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(unsigned int));
4504         if (!(env->me_dbxs && env->me_path && env->me_dbflags && env->me_dbiseqs)) {
4505                 rc = ENOMEM;
4506                 goto leave;
4507         }
4508
4509         /* For RDONLY, get lockfile after we know datafile exists */
4510         if (!(flags & (MDB_RDONLY|MDB_NOLOCK))) {
4511                 rc = mdb_env_setup_locks(env, lpath, mode, &excl);
4512                 if (rc)
4513                         goto leave;
4514         }
4515
4516 #ifdef _WIN32
4517         if (F_ISSET(flags, MDB_RDONLY)) {
4518                 oflags = GENERIC_READ;
4519                 len = OPEN_EXISTING;
4520         } else {
4521                 oflags = GENERIC_READ|GENERIC_WRITE;
4522                 len = OPEN_ALWAYS;
4523         }
4524         mode = FILE_ATTRIBUTE_NORMAL;
4525         env->me_fd = CreateFile(dpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE,
4526                 NULL, len, mode, NULL);
4527 #else
4528         if (F_ISSET(flags, MDB_RDONLY))
4529                 oflags = O_RDONLY;
4530         else
4531                 oflags = O_RDWR | O_CREAT;
4532
4533         env->me_fd = open(dpath, oflags, mode);
4534 #endif
4535         if (env->me_fd == INVALID_HANDLE_VALUE) {
4536                 rc = ErrCode();
4537                 goto leave;
4538         }
4539
4540         if ((flags & (MDB_RDONLY|MDB_NOLOCK)) == MDB_RDONLY) {
4541                 rc = mdb_env_setup_locks(env, lpath, mode, &excl);
4542                 if (rc)
4543                         goto leave;
4544         }
4545
4546         if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) {
4547                 if (flags & (MDB_RDONLY|MDB_WRITEMAP)) {
4548                         env->me_mfd = env->me_fd;
4549                 } else {
4550                         /* Synchronous fd for meta writes. Needed even with
4551                          * MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset.
4552                          */
4553 #ifdef _WIN32
4554                         len = OPEN_EXISTING;
4555                         env->me_mfd = CreateFile(dpath, oflags,
4556                                 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len,
4557                                 mode | FILE_FLAG_WRITE_THROUGH, NULL);
4558 #else
4559                         oflags &= ~O_CREAT;
4560                         env->me_mfd = open(dpath, oflags | MDB_DSYNC, mode);
4561 #endif
4562                         if (env->me_mfd == INVALID_HANDLE_VALUE) {
4563                                 rc = ErrCode();
4564                                 goto leave;
4565                         }
4566                 }
4567                 DPRINTF(("opened dbenv %p", (void *) env));
4568                 if (excl > 0) {
4569                         rc = mdb_env_share_locks(env, &excl);
4570                         if (rc)
4571                                 goto leave;
4572                 }
4573                 if (!((flags & MDB_RDONLY) ||
4574                           (env->me_pbuf = calloc(1, env->me_psize))))
4575                         rc = ENOMEM;
4576                 if (!(flags & MDB_RDONLY)) {
4577                         MDB_txn *txn;
4578                         int tsize = sizeof(MDB_txn), size = tsize + env->me_maxdbs *
4579                                 (sizeof(MDB_db)+sizeof(MDB_cursor *)+sizeof(unsigned int)+1);
4580                         txn = calloc(1, size);
4581                         if (txn) {
4582                                 txn->mt_dbs = (MDB_db *)((char *)txn + tsize);
4583                                 txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
4584                                 txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
4585                                 txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
4586                                 txn->mt_env = env;
4587                                 txn->mt_dbxs = env->me_dbxs;
4588                                 env->me_txn0 = txn;
4589                         } else {
4590                                 rc = ENOMEM;
4591                         }
4592                 }
4593         }
4594
4595 leave:
4596         if (rc) {
4597                 mdb_env_close0(env, excl);
4598         }
4599         free(lpath);
4600         return rc;
4601 }
4602
4603 /** Destroy resources from mdb_env_open(), clear our readers & DBIs */
4604 static void ESECT
4605 mdb_env_close0(MDB_env *env, int excl)
4606 {
4607         int i;
4608
4609         if (!(env->me_flags & MDB_ENV_ACTIVE))
4610                 return;
4611
4612         /* Doing this here since me_dbxs may not exist during mdb_env_close */
4613         for (i = env->me_maxdbs; --i > MAIN_DBI; )
4614                 free(env->me_dbxs[i].md_name.mv_data);
4615
4616         free(env->me_pbuf);
4617         free(env->me_dbiseqs);
4618         free(env->me_dbflags);
4619         free(env->me_dbxs);
4620         free(env->me_path);
4621         free(env->me_dirty_list);
4622         free(env->me_txn0);
4623         mdb_midl_free(env->me_free_pgs);
4624
4625         if (env->me_flags & MDB_ENV_TXKEY) {
4626                 pthread_key_delete(env->me_txkey);
4627 #ifdef _WIN32
4628                 /* Delete our key from the global list */
4629                 for (i=0; i<mdb_tls_nkeys; i++)
4630                         if (mdb_tls_keys[i] == env->me_txkey) {
4631                                 mdb_tls_keys[i] = mdb_tls_keys[mdb_tls_nkeys-1];
4632                                 mdb_tls_nkeys--;
4633                                 break;
4634                         }
4635 #endif
4636         }
4637
4638         if (env->me_map) {
4639                 munmap(env->me_map, env->me_mapsize);
4640         }
4641         if (env->me_mfd != env->me_fd && env->me_mfd != INVALID_HANDLE_VALUE)
4642                 (void) close(env->me_mfd);
4643         if (env->me_fd != INVALID_HANDLE_VALUE)
4644                 (void) close(env->me_fd);
4645         if (env->me_txns) {
4646                 MDB_PID_T pid = env->me_pid;
4647                 /* Clearing readers is done in this function because
4648                  * me_txkey with its destructor must be disabled first.
4649                  */
4650                 for (i = env->me_numreaders; --i >= 0; )
4651                         if (env->me_txns->mti_readers[i].mr_pid == pid)
4652                                 env->me_txns->mti_readers[i].mr_pid = 0;
4653 #ifdef _WIN32
4654                 if (env->me_rmutex) {
4655                         CloseHandle(env->me_rmutex);
4656                         if (env->me_wmutex) CloseHandle(env->me_wmutex);
4657                 }
4658                 /* Windows automatically destroys the mutexes when
4659                  * the last handle closes.
4660                  */
4661 #elif defined(MDB_USE_POSIX_SEM)
4662                 if (env->me_rmutex != SEM_FAILED) {
4663                         sem_close(env->me_rmutex);
4664                         if (env->me_wmutex != SEM_FAILED)
4665                                 sem_close(env->me_wmutex);
4666                         /* If we have the filelock:  If we are the
4667                          * only remaining user, clean up semaphores.
4668                          */
4669                         if (excl == 0)
4670                                 mdb_env_excl_lock(env, &excl);
4671                         if (excl > 0) {
4672                                 sem_unlink(env->me_txns->mti_rmname);
4673                                 sem_unlink(env->me_txns->mti_wmname);
4674                         }
4675                 }
4676 #endif
4677                 munmap((void *)env->me_txns, (env->me_maxreaders-1)*sizeof(MDB_reader)+sizeof(MDB_txninfo));
4678         }
4679         if (env->me_lfd != INVALID_HANDLE_VALUE) {
4680 #ifdef _WIN32
4681                 if (excl >= 0) {
4682                         /* Unlock the lockfile.  Windows would have unlocked it
4683                          * after closing anyway, but not necessarily at once.
4684                          */
4685                         UnlockFile(env->me_lfd, 0, 0, 1, 0);
4686                 }
4687 #endif
4688                 (void) close(env->me_lfd);
4689         }
4690
4691         env->me_flags &= ~(MDB_ENV_ACTIVE|MDB_ENV_TXKEY);
4692 }
4693
4694
4695 void ESECT
4696 mdb_env_close(MDB_env *env)
4697 {
4698         MDB_page *dp;
4699
4700         if (env == NULL)
4701                 return;
4702
4703         VGMEMP_DESTROY(env);
4704         while ((dp = env->me_dpages) != NULL) {
4705                 VGMEMP_DEFINED(&dp->mp_next, sizeof(dp->mp_next));
4706                 env->me_dpages = dp->mp_next;
4707                 free(dp);
4708         }
4709
4710         mdb_env_close0(env, 0);
4711         free(env);
4712 }
4713
4714 /** Compare two items pointing at aligned size_t's */
4715 static int
4716 mdb_cmp_long(const MDB_val *a, const MDB_val *b)
4717 {
4718         return (*(size_t *)a->mv_data < *(size_t *)b->mv_data) ? -1 :
4719                 *(size_t *)a->mv_data > *(size_t *)b->mv_data;
4720 }
4721
4722 /** Compare two items pointing at aligned unsigned int's */
4723 static int
4724 mdb_cmp_int(const MDB_val *a, const MDB_val *b)
4725 {
4726         return (*(unsigned int *)a->mv_data < *(unsigned int *)b->mv_data) ? -1 :
4727                 *(unsigned int *)a->mv_data > *(unsigned int *)b->mv_data;
4728 }
4729
4730 /** Compare two items pointing at unsigned ints of unknown alignment.
4731  *      Nodes and keys are guaranteed to be 2-byte aligned.
4732  */
4733 static int
4734 mdb_cmp_cint(const MDB_val *a, const MDB_val *b)
4735 {
4736 #if BYTE_ORDER == LITTLE_ENDIAN
4737         unsigned short *u, *c;
4738         int x;
4739
4740         u = (unsigned short *) ((char *) a->mv_data + a->mv_size);
4741         c = (unsigned short *) ((char *) b->mv_data + a->mv_size);
4742         do {
4743                 x = *--u - *--c;
4744         } while(!x && u > (unsigned short *)a->mv_data);
4745         return x;
4746 #else
4747         unsigned short *u, *c, *end;
4748         int x;
4749
4750         end = (unsigned short *) ((char *) a->mv_data + a->mv_size);
4751         u = (unsigned short *)a->mv_data;
4752         c = (unsigned short *)b->mv_data;
4753         do {
4754                 x = *u++ - *c++;
4755         } while(!x && u < end);
4756         return x;
4757 #endif
4758 }
4759
4760 /** Compare two items pointing at size_t's of unknown alignment. */
4761 #ifdef MISALIGNED_OK
4762 # define mdb_cmp_clong mdb_cmp_long
4763 #else
4764 # define mdb_cmp_clong mdb_cmp_cint
4765 #endif
4766
4767 /** Compare two items lexically */
4768 static int
4769 mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
4770 {
4771         int diff;
4772         ssize_t len_diff;
4773         unsigned int len;
4774
4775         len = a->mv_size;
4776         len_diff = (ssize_t) a->mv_size - (ssize_t) b->mv_size;
4777         if (len_diff > 0) {
4778                 len = b->mv_size;
4779                 len_diff = 1;
4780         }
4781
4782         diff = memcmp(a->mv_data, b->mv_data, len);
4783         return diff ? diff : len_diff<0 ? -1 : len_diff;
4784 }
4785
4786 /** Compare two items in reverse byte order */
4787 static int
4788 mdb_cmp_memnr(const MDB_val *a, const MDB_val *b)
4789 {
4790         const unsigned char     *p1, *p2, *p1_lim;
4791         ssize_t len_diff;
4792         int diff;
4793
4794         p1_lim = (const unsigned char *)a->mv_data;
4795         p1 = (const unsigned char *)a->mv_data + a->mv_size;
4796         p2 = (const unsigned char *)b->mv_data + b->mv_size;
4797
4798         len_diff = (ssize_t) a->mv_size - (ssize_t) b->mv_size;
4799         if (len_diff > 0) {
4800                 p1_lim += len_diff;
4801                 len_diff = 1;
4802         }
4803
4804         while (p1 > p1_lim) {
4805                 diff = *--p1 - *--p2;
4806                 if (diff)
4807                         return diff;
4808         }
4809         return len_diff<0 ? -1 : len_diff;
4810 }
4811
4812 /** Search for key within a page, using binary search.
4813  * Returns the smallest entry larger or equal to the key.
4814  * If exactp is non-null, stores whether the found entry was an exact match
4815  * in *exactp (1 or 0).
4816  * Updates the cursor index with the index of the found entry.
4817  * If no entry larger or equal to the key is found, returns NULL.
4818  */
4819 static MDB_node *
4820 mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp)
4821 {
4822         unsigned int     i = 0, nkeys;
4823         int              low, high;
4824         int              rc = 0;
4825         MDB_page *mp = mc->mc_pg[mc->mc_top];
4826         MDB_node        *node = NULL;
4827         MDB_val  nodekey;
4828         MDB_cmp_func *cmp;
4829         DKBUF;
4830
4831         nkeys = NUMKEYS(mp);
4832
4833         DPRINTF(("searching %u keys in %s %spage %"Z"u",
4834             nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
4835             mdb_dbg_pgno(mp)));
4836
4837         low = IS_LEAF(mp) ? 0 : 1;
4838         high = nkeys - 1;
4839         cmp = mc->mc_dbx->md_cmp;
4840
4841         /* Branch pages have no data, so if using integer keys,
4842          * alignment is guaranteed. Use faster mdb_cmp_int.
4843          */
4844         if (cmp == mdb_cmp_cint && IS_BRANCH(mp)) {
4845                 if (NODEPTR(mp, 1)->mn_ksize == sizeof(size_t))
4846                         cmp = mdb_cmp_long;
4847                 else
4848                         cmp = mdb_cmp_int;
4849         }
4850
4851         if (IS_LEAF2(mp)) {
4852                 nodekey.mv_size = mc->mc_db->md_pad;
4853                 node = NODEPTR(mp, 0);  /* fake */
4854                 while (low <= high) {
4855                         i = (low + high) >> 1;
4856                         nodekey.mv_data = LEAF2KEY(mp, i, nodekey.mv_size);
4857                         rc = cmp(key, &nodekey);
4858                         DPRINTF(("found leaf index %u [%s], rc = %i",
4859                             i, DKEY(&nodekey), rc));
4860                         if (rc == 0)
4861                                 break;
4862                         if (rc > 0)
4863                                 low = i + 1;
4864                         else
4865                                 high = i - 1;
4866                 }
4867         } else {
4868                 while (low <= high) {
4869                         i = (low + high) >> 1;
4870
4871                         node = NODEPTR(mp, i);
4872                         nodekey.mv_size = NODEKSZ(node);
4873                         nodekey.mv_data = NODEKEY(node);
4874
4875                         rc = cmp(key, &nodekey);
4876 #if MDB_DEBUG
4877                         if (IS_LEAF(mp))
4878                                 DPRINTF(("found leaf index %u [%s], rc = %i",
4879                                     i, DKEY(&nodekey), rc));
4880                         else
4881                                 DPRINTF(("found branch index %u [%s -> %"Z"u], rc = %i",
4882                                     i, DKEY(&nodekey), NODEPGNO(node), rc));
4883 #endif
4884                         if (rc == 0)
4885                                 break;
4886                         if (rc > 0)
4887                                 low = i + 1;
4888                         else
4889                                 high = i - 1;
4890                 }
4891         }
4892
4893         if (rc > 0) {   /* Found entry is less than the key. */
4894                 i++;    /* Skip to get the smallest entry larger than key. */
4895                 if (!IS_LEAF2(mp))
4896                         node = NODEPTR(mp, i);
4897         }
4898         if (exactp)
4899                 *exactp = (rc == 0 && nkeys > 0);
4900         /* store the key index */
4901         mc->mc_ki[mc->mc_top] = i;
4902         if (i >= nkeys)
4903                 /* There is no entry larger or equal to the key. */
4904                 return NULL;
4905
4906         /* nodeptr is fake for LEAF2 */
4907         return node;
4908 }
4909
4910 #if 0
4911 static void
4912 mdb_cursor_adjust(MDB_cursor *mc, func)
4913 {
4914         MDB_cursor *m2;
4915
4916         for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) {
4917                 if (m2->mc_pg[m2->mc_top] == mc->mc_pg[mc->mc_top]) {
4918                         func(mc, m2);
4919                 }
4920         }
4921 }
4922 #endif
4923
4924 /** Pop a page off the top of the cursor's stack. */
4925 static void
4926 mdb_cursor_pop(MDB_cursor *mc)
4927 {
4928         if (mc->mc_snum) {
4929 #if MDB_DEBUG
4930                 MDB_page        *top = mc->mc_pg[mc->mc_top];
4931 #endif
4932                 mc->mc_snum--;
4933                 if (mc->mc_snum)
4934                         mc->mc_top--;
4935
4936                 DPRINTF(("popped page %"Z"u off db %d cursor %p", top->mp_pgno,
4937                         DDBI(mc), (void *) mc));
4938         }
4939 }
4940
4941 /** Push a page onto the top of the cursor's stack. */
4942 static int
4943 mdb_cursor_push(MDB_cursor *mc, MDB_page *mp)
4944 {
4945         DPRINTF(("pushing page %"Z"u on db %d cursor %p", mp->mp_pgno,
4946                 DDBI(mc), (void *) mc));
4947
4948         if (mc->mc_snum >= CURSOR_STACK) {
4949                 mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
4950                 return MDB_CURSOR_FULL;
4951         }
4952
4953         mc->mc_top = mc->mc_snum++;
4954         mc->mc_pg[mc->mc_top] = mp;
4955         mc->mc_ki[mc->mc_top] = 0;
4956
4957         return MDB_SUCCESS;
4958 }
4959
4960 /** Find the address of the page corresponding to a given page number.
4961  * @param[in] txn the transaction for this access.
4962  * @param[in] pgno the page number for the page to retrieve.
4963  * @param[out] ret address of a pointer where the page's address will be stored.
4964  * @param[out] lvl dirty_list inheritance level of found page. 1=current txn, 0=mapped page.
4965  * @return 0 on success, non-zero on failure.
4966  */
4967 static int
4968 mdb_page_get(MDB_txn *txn, pgno_t pgno, MDB_page **ret, int *lvl)
4969 {
4970         MDB_env *env = txn->mt_env;
4971         MDB_page *p = NULL;
4972         int level;
4973
4974         if (!((txn->mt_flags & MDB_TXN_RDONLY) | (env->me_flags & MDB_WRITEMAP))) {
4975                 MDB_txn *tx2 = txn;
4976                 level = 1;
4977                 do {
4978                         MDB_ID2L dl = tx2->mt_u.dirty_list;
4979                         unsigned x;
4980                         /* Spilled pages were dirtied in this txn and flushed
4981                          * because the dirty list got full. Bring this page
4982                          * back in from the map (but don't unspill it here,
4983                          * leave that unless page_touch happens again).
4984                          */
4985                         if (tx2->mt_spill_pgs) {
4986                                 MDB_ID pn = pgno << 1;
4987                                 x = mdb_midl_search(tx2->mt_spill_pgs, pn);
4988                                 if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) {
4989                                         p = (MDB_page *)(env->me_map + env->me_psize * pgno);
4990                                         goto done;
4991                                 }
4992                         }
4993                         if (dl[0].mid) {
4994                                 unsigned x = mdb_mid2l_search(dl, pgno);
4995                                 if (x <= dl[0].mid && dl[x].mid == pgno) {
4996                                         p = dl[x].mptr;
4997                                         goto done;
4998                                 }
4999                         }
5000                         level++;
5001                 } while ((tx2 = tx2->mt_parent) != NULL);
5002         }
5003
5004         if (pgno < txn->mt_next_pgno) {
5005                 level = 0;
5006                 p = (MDB_page *)(env->me_map + env->me_psize * pgno);
5007         } else {
5008                 DPRINTF(("page %"Z"u not found", pgno));
5009                 txn->mt_flags |= MDB_TXN_ERROR;
5010                 return MDB_PAGE_NOTFOUND;
5011         }
5012
5013 done:
5014         *ret = p;
5015         if (lvl)
5016                 *lvl = level;
5017         return MDB_SUCCESS;
5018 }
5019
5020 /** Finish #mdb_page_search() / #mdb_page_search_lowest().
5021  *      The cursor is at the root page, set up the rest of it.
5022  */
5023 static int
5024 mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags)
5025 {
5026         MDB_page        *mp = mc->mc_pg[mc->mc_top];
5027         int rc;
5028         DKBUF;
5029
5030         while (IS_BRANCH(mp)) {
5031                 MDB_node        *node;
5032                 indx_t          i;
5033
5034                 DPRINTF(("branch page %"Z"u has %u keys", mp->mp_pgno, NUMKEYS(mp)));
5035                 mdb_cassert(mc, NUMKEYS(mp) > 1);
5036                 DPRINTF(("found index 0 to page %"Z"u", NODEPGNO(NODEPTR(mp, 0))));
5037
5038                 if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) {
5039                         i = 0;
5040                         if (flags & MDB_PS_LAST)
5041                                 i = NUMKEYS(mp) - 1;
5042                 } else {
5043                         int      exact;
5044                         node = mdb_node_search(mc, key, &exact);
5045                         if (node == NULL)
5046                                 i = NUMKEYS(mp) - 1;
5047                         else {
5048                                 i = mc->mc_ki[mc->mc_top];
5049                                 if (!exact) {
5050                                         mdb_cassert(mc, i > 0);
5051                                         i--;
5052                                 }
5053                         }
5054                         DPRINTF(("following index %u for key [%s]", i, DKEY(key)));
5055                 }
5056
5057                 mdb_cassert(mc, i < NUMKEYS(mp));
5058                 node = NODEPTR(mp, i);
5059
5060                 if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(node), &mp, NULL)) != 0)
5061                         return rc;
5062
5063                 mc->mc_ki[mc->mc_top] = i;
5064                 if ((rc = mdb_cursor_push(mc, mp)))
5065                         return rc;
5066
5067                 if (flags & MDB_PS_MODIFY) {
5068                         if ((rc = mdb_page_touch(mc)) != 0)
5069                                 return rc;
5070                         mp = mc->mc_pg[mc->mc_top];
5071                 }
5072         }
5073
5074         if (!IS_LEAF(mp)) {
5075                 DPRINTF(("internal error, index points to a %02X page!?",
5076                     mp->mp_flags));
5077                 mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
5078                 return MDB_CORRUPTED;
5079         }
5080
5081         DPRINTF(("found leaf page %"Z"u for key [%s]", mp->mp_pgno,
5082             key ? DKEY(key) : "null"));
5083         mc->mc_flags |= C_INITIALIZED;
5084         mc->mc_flags &= ~C_EOF;
5085
5086         return MDB_SUCCESS;
5087 }
5088
5089 /** Search for the lowest key under the current branch page.
5090  * This just bypasses a NUMKEYS check in the current page
5091  * before calling mdb_page_search_root(), because the callers
5092  * are all in situations where the current page is known to
5093  * be underfilled.
5094  */
5095 static int
5096 mdb_page_search_lowest(MDB_cursor *mc)
5097 {
5098         MDB_page        *mp = mc->mc_pg[mc->mc_top];
5099         MDB_node        *node = NODEPTR(mp, 0);
5100         int rc;
5101
5102         if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(node), &mp, NULL)) != 0)
5103                 return rc;
5104
5105         mc->mc_ki[mc->mc_top] = 0;
5106         if ((rc = mdb_cursor_push(mc, mp)))
5107                 return rc;
5108         return mdb_page_search_root(mc, NULL, MDB_PS_FIRST);
5109 }
5110
5111 /** Search for the page a given key should be in.
5112  * Push it and its parent pages on the cursor stack.
5113  * @param[in,out] mc the cursor for this operation.
5114  * @param[in] key the key to search for, or NULL for first/last page.
5115  * @param[in] flags If MDB_PS_MODIFY is set, visited pages in the DB
5116  *   are touched (updated with new page numbers).
5117  *   If MDB_PS_FIRST or MDB_PS_LAST is set, find first or last leaf.
5118  *   This is used by #mdb_cursor_first() and #mdb_cursor_last().
5119  *   If MDB_PS_ROOTONLY set, just fetch root node, no further lookups.
5120  * @return 0 on success, non-zero on failure.
5121  */
5122 static int
5123 mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags)
5124 {
5125         int              rc;
5126         pgno_t           root;
5127
5128         /* Make sure the txn is still viable, then find the root from
5129          * the txn's db table and set it as the root of the cursor's stack.
5130          */
5131         if (F_ISSET(mc->mc_txn->mt_flags, MDB_TXN_ERROR)) {
5132                 DPUTS("transaction has failed, must abort");
5133                 return MDB_BAD_TXN;
5134         } else {
5135                 /* Make sure we're using an up-to-date root */
5136                 if (*mc->mc_dbflag & DB_STALE) {
5137                                 MDB_cursor mc2;
5138                                 if (TXN_DBI_CHANGED(mc->mc_txn, mc->mc_dbi))
5139                                         return MDB_BAD_DBI;
5140                                 mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, NULL);
5141                                 rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, 0);
5142                                 if (rc)
5143                                         return rc;
5144                                 {
5145                                         MDB_val data;
5146                                         int exact = 0;
5147                                         uint16_t flags;
5148                                         MDB_node *leaf = mdb_node_search(&mc2,
5149                                                 &mc->mc_dbx->md_name, &exact);
5150                                         if (!exact)
5151                                                 return MDB_NOTFOUND;
5152                                         rc = mdb_node_read(mc->mc_txn, leaf, &data);
5153                                         if (rc)
5154                                                 return rc;
5155                                         memcpy(&flags, ((char *) data.mv_data + offsetof(MDB_db, md_flags)),
5156                                                 sizeof(uint16_t));
5157                                         /* The txn may not know this DBI, or another process may
5158                                          * have dropped and recreated the DB with other flags.
5159                                          */
5160                                         if ((mc->mc_db->md_flags & PERSISTENT_FLAGS) != flags)
5161                                                 return MDB_INCOMPATIBLE;
5162                                         memcpy(mc->mc_db, data.mv_data, sizeof(MDB_db));
5163                                 }
5164                                 *mc->mc_dbflag &= ~DB_STALE;
5165                 }
5166                 root = mc->mc_db->md_root;
5167
5168                 if (root == P_INVALID) {                /* Tree is empty. */
5169                         DPUTS("tree is empty");
5170                         return MDB_NOTFOUND;
5171                 }
5172         }
5173
5174         mdb_cassert(mc, root > 1);
5175         if (!mc->mc_pg[0] || mc->mc_pg[0]->mp_pgno != root)
5176                 if ((rc = mdb_page_get(mc->mc_txn, root, &mc->mc_pg[0], NULL)) != 0)
5177                         return rc;
5178
5179         mc->mc_snum = 1;
5180         mc->mc_top = 0;
5181
5182         DPRINTF(("db %d root page %"Z"u has flags 0x%X",
5183                 DDBI(mc), root, mc->mc_pg[0]->mp_flags));
5184
5185         if (flags & MDB_PS_MODIFY) {
5186                 if ((rc = mdb_page_touch(mc)))
5187                         return rc;
5188         }
5189
5190         if (flags & MDB_PS_ROOTONLY)
5191                 return MDB_SUCCESS;
5192
5193         return mdb_page_search_root(mc, key, flags);
5194 }
5195
5196 static int
5197 mdb_ovpage_free(MDB_cursor *mc, MDB_page *mp)
5198 {
5199         MDB_txn *txn = mc->mc_txn;
5200         pgno_t pg = mp->mp_pgno;
5201         unsigned x = 0, ovpages = mp->mp_pages;
5202         MDB_env *env = txn->mt_env;
5203         MDB_IDL sl = txn->mt_spill_pgs;
5204         MDB_ID pn = pg << 1;
5205         int rc;
5206
5207         DPRINTF(("free ov page %"Z"u (%d)", pg, ovpages));
5208         /* If the page is dirty or on the spill list we just acquired it,
5209          * so we should give it back to our current free list, if any.
5210          * Otherwise put it onto the list of pages we freed in this txn.
5211          *
5212          * Won't create me_pghead: me_pglast must be inited along with it.
5213          * Unsupported in nested txns: They would need to hide the page
5214          * range in ancestor txns' dirty and spilled lists.
5215          */
5216         if (env->me_pghead &&
5217                 !txn->mt_parent &&
5218                 ((mp->mp_flags & P_DIRTY) ||
5219                  (sl && (x = mdb_midl_search(sl, pn)) <= sl[0] && sl[x] == pn)))
5220         {
5221                 unsigned i, j;
5222                 pgno_t *mop;
5223                 MDB_ID2 *dl, ix, iy;
5224                 rc = mdb_midl_need(&env->me_pghead, ovpages);
5225                 if (rc)
5226                         return rc;
5227                 if (!(mp->mp_flags & P_DIRTY)) {
5228                         /* This page is no longer spilled */
5229                         if (x == sl[0])
5230                                 sl[0]--;
5231                         else
5232                                 sl[x] |= 1;
5233                         goto release;
5234                 }
5235                 /* Remove from dirty list */
5236                 dl = txn->mt_u.dirty_list;
5237                 x = dl[0].mid--;
5238                 for (ix = dl[x]; ix.mptr != mp; ix = iy) {
5239                         if (x > 1) {
5240                                 x--;
5241                                 iy = dl[x];
5242                                 dl[x] = ix;
5243                         } else {
5244                                 mdb_cassert(mc, x > 1);
5245                                 j = ++(dl[0].mid);
5246                                 dl[j] = ix;             /* Unsorted. OK when MDB_TXN_ERROR. */
5247                                 txn->mt_flags |= MDB_TXN_ERROR;
5248                                 return MDB_CORRUPTED;
5249                         }
5250                 }
5251                 if (!(env->me_flags & MDB_WRITEMAP))
5252                         mdb_dpage_free(env, mp);
5253 release:
5254                 /* Insert in me_pghead */
5255                 mop = env->me_pghead;
5256                 j = mop[0] + ovpages;
5257                 for (i = mop[0]; i && mop[i] < pg; i--)
5258                         mop[j--] = mop[i];
5259                 while (j>i)
5260                         mop[j--] = pg++;
5261                 mop[0] += ovpages;
5262         } else {
5263                 rc = mdb_midl_append_range(&txn->mt_free_pgs, pg, ovpages);
5264                 if (rc)
5265                         return rc;
5266         }
5267         mc->mc_db->md_overflow_pages -= ovpages;
5268         return 0;
5269 }
5270
5271 /** Return the data associated with a given node.
5272  * @param[in] txn The transaction for this operation.
5273  * @param[in] leaf The node being read.
5274  * @param[out] data Updated to point to the node's data.
5275  * @return 0 on success, non-zero on failure.
5276  */
5277 static int
5278 mdb_node_read(MDB_txn *txn, MDB_node *leaf, MDB_val *data)
5279 {
5280         MDB_page        *omp;           /* overflow page */
5281         pgno_t           pgno;
5282         int rc;
5283
5284         if (!F_ISSET(leaf->mn_flags, F_BIGDATA)) {
5285                 data->mv_size = NODEDSZ(leaf);
5286                 data->mv_data = NODEDATA(leaf);
5287                 return MDB_SUCCESS;
5288         }
5289
5290         /* Read overflow data.
5291          */
5292         data->mv_size = NODEDSZ(leaf);
5293         memcpy(&pgno, NODEDATA(leaf), sizeof(pgno));
5294         if ((rc = mdb_page_get(txn, pgno, &omp, NULL)) != 0) {
5295                 DPRINTF(("read overflow page %"Z"u failed", pgno));
5296                 return rc;
5297         }
5298         data->mv_data = METADATA(omp);
5299
5300         return MDB_SUCCESS;
5301 }
5302
5303 int
5304 mdb_get(MDB_txn *txn, MDB_dbi dbi,
5305     MDB_val *key, MDB_val *data)
5306 {
5307         MDB_cursor      mc;
5308         MDB_xcursor     mx;
5309         int exact = 0;
5310         DKBUF;
5311
5312         DPRINTF(("===> get db %u key [%s]", dbi, DKEY(key)));
5313
5314         if (!key || !data || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
5315                 return EINVAL;
5316
5317         if (txn->mt_flags & MDB_TXN_ERROR)
5318                 return MDB_BAD_TXN;
5319
5320         mdb_cursor_init(&mc, txn, dbi, &mx);
5321         return mdb_cursor_set(&mc, key, data, MDB_SET, &exact);
5322 }
5323
5324 /** Find a sibling for a page.
5325  * Replaces the page at the top of the cursor's stack with the
5326  * specified sibling, if one exists.
5327  * @param[in] mc The cursor for this operation.
5328  * @param[in] move_right Non-zero if the right sibling is requested,
5329  * otherwise the left sibling.
5330  * @return 0 on success, non-zero on failure.
5331  */
5332 static int
5333 mdb_cursor_sibling(MDB_cursor *mc, int move_right)
5334 {
5335         int              rc;
5336         MDB_node        *indx;
5337         MDB_page        *mp;
5338
5339         if (mc->mc_snum < 2) {
5340                 return MDB_NOTFOUND;            /* root has no siblings */
5341         }
5342
5343         mdb_cursor_pop(mc);
5344         DPRINTF(("parent page is page %"Z"u, index %u",
5345                 mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top]));
5346
5347         if (move_right ? (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mc->mc_pg[mc->mc_top]))
5348                        : (mc->mc_ki[mc->mc_top] == 0)) {
5349                 DPRINTF(("no more keys left, moving to %s sibling",
5350                     move_right ? "right" : "left"));
5351                 if ((rc = mdb_cursor_sibling(mc, move_right)) != MDB_SUCCESS) {
5352                         /* undo cursor_pop before returning */
5353                         mc->mc_top++;
5354                         mc->mc_snum++;
5355                         return rc;
5356                 }
5357         } else {
5358                 if (move_right)
5359                         mc->mc_ki[mc->mc_top]++;
5360                 else
5361                         mc->mc_ki[mc->mc_top]--;
5362                 DPRINTF(("just moving to %s index key %u",
5363                     move_right ? "right" : "left", mc->mc_ki[mc->mc_top]));
5364         }
5365         mdb_cassert(mc, IS_BRANCH(mc->mc_pg[mc->mc_top]));
5366
5367         indx = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
5368         if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(indx), &mp, NULL)) != 0) {
5369                 /* mc will be inconsistent if caller does mc_snum++ as above */
5370                 mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
5371                 return rc;
5372         }
5373
5374         mdb_cursor_push(mc, mp);
5375         if (!move_right)
5376                 mc->mc_ki[mc->mc_top] = NUMKEYS(mp)-1;
5377
5378         return MDB_SUCCESS;
5379 }
5380
5381 /** Move the cursor to the next data item. */
5382 static int
5383 mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
5384 {
5385         MDB_page        *mp;
5386         MDB_node        *leaf;
5387         int rc;
5388
5389         if (mc->mc_flags & C_EOF) {
5390                 return MDB_NOTFOUND;
5391         }
5392
5393         mdb_cassert(mc, mc->mc_flags & C_INITIALIZED);
5394
5395         mp = mc->mc_pg[mc->mc_top];
5396
5397         if (mc->mc_db->md_flags & MDB_DUPSORT) {
5398                 leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5399                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5400                         if (op == MDB_NEXT || op == MDB_NEXT_DUP) {
5401                                 rc = mdb_cursor_next(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_NEXT);
5402                                 if (op != MDB_NEXT || rc != MDB_NOTFOUND) {
5403                                         if (rc == MDB_SUCCESS)
5404                                                 MDB_GET_KEY(leaf, key);
5405                                         return rc;
5406                                 }
5407                         }
5408                 } else {
5409                         mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5410                         if (op == MDB_NEXT_DUP)
5411                                 return MDB_NOTFOUND;
5412                 }
5413         }
5414
5415         DPRINTF(("cursor_next: top page is %"Z"u in cursor %p",
5416                 mdb_dbg_pgno(mp), (void *) mc));
5417         if (mc->mc_flags & C_DEL)
5418                 goto skip;
5419
5420         if (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mp)) {
5421                 DPUTS("=====> move to next sibling page");
5422                 if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) {
5423                         mc->mc_flags |= C_EOF;
5424                         return rc;
5425                 }
5426                 mp = mc->mc_pg[mc->mc_top];
5427                 DPRINTF(("next page is %"Z"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top]));
5428         } else
5429                 mc->mc_ki[mc->mc_top]++;
5430
5431 skip:
5432         DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u",
5433             mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
5434
5435         if (IS_LEAF2(mp)) {
5436                 key->mv_size = mc->mc_db->md_pad;
5437                 key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
5438                 return MDB_SUCCESS;
5439         }
5440
5441         mdb_cassert(mc, IS_LEAF(mp));
5442         leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5443
5444         if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5445                 mdb_xcursor_init1(mc, leaf);
5446         }
5447         if (data) {
5448                 if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
5449                         return rc;
5450
5451                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5452                         rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
5453                         if (rc != MDB_SUCCESS)
5454                                 return rc;
5455                 }
5456         }
5457
5458         MDB_GET_KEY(leaf, key);
5459         return MDB_SUCCESS;
5460 }
5461
5462 /** Move the cursor to the previous data item. */
5463 static int
5464 mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
5465 {
5466         MDB_page        *mp;
5467         MDB_node        *leaf;
5468         int rc;
5469
5470         mdb_cassert(mc, mc->mc_flags & C_INITIALIZED);
5471
5472         mp = mc->mc_pg[mc->mc_top];
5473
5474         if (mc->mc_db->md_flags & MDB_DUPSORT) {
5475                 leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5476                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5477                         if (op == MDB_PREV || op == MDB_PREV_DUP) {
5478                                 rc = mdb_cursor_prev(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_PREV);
5479                                 if (op != MDB_PREV || rc != MDB_NOTFOUND) {
5480                                         if (rc == MDB_SUCCESS) {
5481                                                 MDB_GET_KEY(leaf, key);
5482                                                 mc->mc_flags &= ~C_EOF;
5483                                         }
5484                                         return rc;
5485                                 }
5486                         }
5487                 } else {
5488                         mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5489                         if (op == MDB_PREV_DUP)
5490                                 return MDB_NOTFOUND;
5491                 }
5492         }
5493
5494         DPRINTF(("cursor_prev: top page is %"Z"u in cursor %p",
5495                 mdb_dbg_pgno(mp), (void *) mc));
5496
5497         if (mc->mc_ki[mc->mc_top] == 0)  {
5498                 DPUTS("=====> move to prev sibling page");
5499                 if ((rc = mdb_cursor_sibling(mc, 0)) != MDB_SUCCESS) {
5500                         return rc;
5501                 }
5502                 mp = mc->mc_pg[mc->mc_top];
5503                 mc->mc_ki[mc->mc_top] = NUMKEYS(mp) - 1;
5504                 DPRINTF(("prev page is %"Z"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top]));
5505         } else
5506                 mc->mc_ki[mc->mc_top]--;
5507
5508         mc->mc_flags &= ~C_EOF;
5509
5510         DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u",
5511             mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
5512
5513         if (IS_LEAF2(mp)) {
5514                 key->mv_size = mc->mc_db->md_pad;
5515                 key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
5516                 return MDB_SUCCESS;
5517         }
5518
5519         mdb_cassert(mc, IS_LEAF(mp));
5520         leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5521
5522         if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5523                 mdb_xcursor_init1(mc, leaf);
5524         }
5525         if (data) {
5526                 if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
5527                         return rc;
5528
5529                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5530                         rc = mdb_cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL);
5531                         if (rc != MDB_SUCCESS)
5532                                 return rc;
5533                 }
5534         }
5535
5536         MDB_GET_KEY(leaf, key);
5537         return MDB_SUCCESS;
5538 }
5539
5540 /** Set the cursor on a specific data item. */
5541 static int
5542 mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data,
5543     MDB_cursor_op op, int *exactp)
5544 {
5545         int              rc;
5546         MDB_page        *mp;
5547         MDB_node        *leaf = NULL;
5548         DKBUF;
5549
5550         if (key->mv_size == 0)
5551                 return MDB_BAD_VALSIZE;
5552
5553         if (mc->mc_xcursor)
5554                 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5555
5556         /* See if we're already on the right page */
5557         if (mc->mc_flags & C_INITIALIZED) {
5558                 MDB_val nodekey;
5559
5560                 mp = mc->mc_pg[mc->mc_top];
5561                 if (!NUMKEYS(mp)) {
5562                         mc->mc_ki[mc->mc_top] = 0;
5563                         return MDB_NOTFOUND;
5564                 }
5565                 if (mp->mp_flags & P_LEAF2) {
5566                         nodekey.mv_size = mc->mc_db->md_pad;
5567                         nodekey.mv_data = LEAF2KEY(mp, 0, nodekey.mv_size);
5568                 } else {
5569                         leaf = NODEPTR(mp, 0);
5570                         MDB_GET_KEY2(leaf, nodekey);
5571                 }
5572                 rc = mc->mc_dbx->md_cmp(key, &nodekey);
5573                 if (rc == 0) {
5574                         /* Probably happens rarely, but first node on the page
5575                          * was the one we wanted.
5576                          */
5577                         mc->mc_ki[mc->mc_top] = 0;
5578                         if (exactp)
5579                                 *exactp = 1;
5580                         goto set1;
5581                 }
5582                 if (rc > 0) {
5583                         unsigned int i;
5584                         unsigned int nkeys = NUMKEYS(mp);
5585                         if (nkeys > 1) {
5586                                 if (mp->mp_flags & P_LEAF2) {
5587                                         nodekey.mv_data = LEAF2KEY(mp,
5588                                                  nkeys-1, nodekey.mv_size);
5589                                 } else {
5590                                         leaf = NODEPTR(mp, nkeys-1);
5591                                         MDB_GET_KEY2(leaf, nodekey);
5592                                 }
5593                                 rc = mc->mc_dbx->md_cmp(key, &nodekey);
5594                                 if (rc == 0) {
5595                                         /* last node was the one we wanted */
5596                                         mc->mc_ki[mc->mc_top] = nkeys-1;
5597                                         if (exactp)
5598                                                 *exactp = 1;
5599                                         goto set1;
5600                                 }
5601                                 if (rc < 0) {
5602                                         if (mc->mc_ki[mc->mc_top] < NUMKEYS(mp)) {
5603                                                 /* This is definitely the right page, skip search_page */
5604                                                 if (mp->mp_flags & P_LEAF2) {
5605                                                         nodekey.mv_data = LEAF2KEY(mp,
5606                                                                  mc->mc_ki[mc->mc_top], nodekey.mv_size);
5607                                                 } else {
5608                                                         leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5609                                                         MDB_GET_KEY2(leaf, nodekey);
5610                                                 }
5611                                                 rc = mc->mc_dbx->md_cmp(key, &nodekey);
5612                                                 if (rc == 0) {
5613                                                         /* current node was the one we wanted */
5614                                                         if (exactp)
5615                                                                 *exactp = 1;
5616                                                         goto set1;
5617                                                 }
5618                                         }
5619                                         rc = 0;
5620                                         goto set2;
5621                                 }
5622                         }
5623                         /* If any parents have right-sibs, search.
5624                          * Otherwise, there's nothing further.
5625                          */
5626                         for (i=0; i<mc->mc_top; i++)
5627                                 if (mc->mc_ki[i] <
5628                                         NUMKEYS(mc->mc_pg[i])-1)
5629                                         break;
5630                         if (i == mc->mc_top) {
5631                                 /* There are no other pages */
5632                                 mc->mc_ki[mc->mc_top] = nkeys;
5633                                 return MDB_NOTFOUND;
5634                         }
5635                 }
5636                 if (!mc->mc_top) {
5637                         /* There are no other pages */
5638                         mc->mc_ki[mc->mc_top] = 0;
5639                         if (op == MDB_SET_RANGE && !exactp) {
5640                                 rc = 0;
5641                                 goto set1;
5642                         } else
5643                                 return MDB_NOTFOUND;
5644                 }
5645         }
5646
5647         rc = mdb_page_search(mc, key, 0);
5648         if (rc != MDB_SUCCESS)
5649                 return rc;
5650
5651         mp = mc->mc_pg[mc->mc_top];
5652         mdb_cassert(mc, IS_LEAF(mp));
5653
5654 set2:
5655         leaf = mdb_node_search(mc, key, exactp);
5656         if (exactp != NULL && !*exactp) {
5657                 /* MDB_SET specified and not an exact match. */
5658                 return MDB_NOTFOUND;
5659         }
5660
5661         if (leaf == NULL) {
5662                 DPUTS("===> inexact leaf not found, goto sibling");
5663                 if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS)
5664                         return rc;              /* no entries matched */
5665                 mp = mc->mc_pg[mc->mc_top];
5666                 mdb_cassert(mc, IS_LEAF(mp));
5667                 leaf = NODEPTR(mp, 0);
5668         }
5669
5670 set1:
5671         mc->mc_flags |= C_INITIALIZED;
5672         mc->mc_flags &= ~C_EOF;
5673
5674         if (IS_LEAF2(mp)) {
5675                 if (op == MDB_SET_RANGE || op == MDB_SET_KEY) {
5676                         key->mv_size = mc->mc_db->md_pad;
5677                         key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
5678                 }
5679                 return MDB_SUCCESS;
5680         }
5681
5682         if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5683                 mdb_xcursor_init1(mc, leaf);
5684         }
5685         if (data) {
5686                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5687                         if (op == MDB_SET || op == MDB_SET_KEY || op == MDB_SET_RANGE) {
5688                                 rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
5689                         } else {
5690                                 int ex2, *ex2p;
5691                                 if (op == MDB_GET_BOTH) {
5692                                         ex2p = &ex2;
5693                                         ex2 = 0;
5694                                 } else {
5695                                         ex2p = NULL;
5696                                 }
5697                                 rc = mdb_cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_SET_RANGE, ex2p);
5698                                 if (rc != MDB_SUCCESS)
5699                                         return rc;
5700                         }
5701                 } else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) {
5702                         MDB_val d2;
5703                         if ((rc = mdb_node_read(mc->mc_txn, leaf, &d2)) != MDB_SUCCESS)
5704                                 return rc;
5705                         rc = mc->mc_dbx->md_dcmp(data, &d2);
5706                         if (rc) {
5707                                 if (op == MDB_GET_BOTH || rc > 0)
5708                                         return MDB_NOTFOUND;
5709                                 rc = 0;
5710                                 *data = d2;
5711                         }
5712
5713                 } else {
5714                         if (mc->mc_xcursor)
5715                                 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5716                         if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
5717                                 return rc;
5718                 }
5719         }
5720
5721         /* The key already matches in all other cases */
5722         if (op == MDB_SET_RANGE || op == MDB_SET_KEY)
5723                 MDB_GET_KEY(leaf, key);
5724         DPRINTF(("==> cursor placed on key [%s]", DKEY(key)));
5725
5726         return rc;
5727 }
5728
5729 /** Move the cursor to the first item in the database. */
5730 static int
5731 mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data)
5732 {
5733         int              rc;
5734         MDB_node        *leaf;
5735
5736         if (mc->mc_xcursor)
5737                 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5738
5739         if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) {
5740                 rc = mdb_page_search(mc, NULL, MDB_PS_FIRST);
5741                 if (rc != MDB_SUCCESS)
5742                         return rc;
5743         }
5744         mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
5745
5746         leaf = NODEPTR(mc->mc_pg[mc->mc_top], 0);
5747         mc->mc_flags |= C_INITIALIZED;
5748         mc->mc_flags &= ~C_EOF;
5749
5750         mc->mc_ki[mc->mc_top] = 0;
5751
5752         if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
5753                 key->mv_size = mc->mc_db->md_pad;
5754                 key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], 0, key->mv_size);
5755                 return MDB_SUCCESS;
5756         }
5757
5758         if (data) {
5759                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5760                         mdb_xcursor_init1(mc, leaf);
5761                         rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
5762                         if (rc)
5763                                 return rc;
5764                 } else {
5765                         if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
5766                                 return rc;
5767                 }
5768         }
5769         MDB_GET_KEY(leaf, key);
5770         return MDB_SUCCESS;
5771 }
5772
5773 /** Move the cursor to the last item in the database. */
5774 static int
5775 mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data)
5776 {
5777         int              rc;
5778         MDB_node        *leaf;
5779
5780         if (mc->mc_xcursor)
5781                 mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
5782
5783         if (!(mc->mc_flags & C_EOF)) {
5784
5785                 if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) {
5786                         rc = mdb_page_search(mc, NULL, MDB_PS_LAST);
5787                         if (rc != MDB_SUCCESS)
5788                                 return rc;
5789                 }
5790                 mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
5791
5792         }
5793         mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]) - 1;
5794         mc->mc_flags |= C_INITIALIZED|C_EOF;
5795         leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
5796
5797         if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
5798                 key->mv_size = mc->mc_db->md_pad;
5799                 key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], key->mv_size);
5800                 return MDB_SUCCESS;
5801         }
5802
5803         if (data) {
5804                 if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5805                         mdb_xcursor_init1(mc, leaf);
5806                         rc = mdb_cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL);
5807                         if (rc)
5808                                 return rc;
5809                 } else {
5810                         if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
5811                                 return rc;
5812                 }
5813         }
5814
5815         MDB_GET_KEY(leaf, key);
5816         return MDB_SUCCESS;
5817 }
5818
5819 int
5820 mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
5821     MDB_cursor_op op)
5822 {
5823         int              rc;
5824         int              exact = 0;
5825         int              (*mfunc)(MDB_cursor *mc, MDB_val *key, MDB_val *data);
5826
5827         if (mc == NULL)
5828                 return EINVAL;
5829
5830         if (mc->mc_txn->mt_flags & MDB_TXN_ERROR)
5831                 return MDB_BAD_TXN;
5832
5833         switch (op) {
5834         case MDB_GET_CURRENT:
5835                 if (!(mc->mc_flags & C_INITIALIZED)) {
5836                         rc = EINVAL;
5837                 } else {
5838                         MDB_page *mp = mc->mc_pg[mc->mc_top];
5839                         int nkeys = NUMKEYS(mp);
5840                         if (!nkeys || mc->mc_ki[mc->mc_top] >= nkeys) {
5841                                 mc->mc_ki[mc->mc_top] = nkeys;
5842                                 rc = MDB_NOTFOUND;
5843                                 break;
5844                         }
5845                         rc = MDB_SUCCESS;
5846                         if (IS_LEAF2(mp)) {
5847                                 key->mv_size = mc->mc_db->md_pad;
5848                                 key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
5849                         } else {
5850                                 MDB_node *leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
5851                                 MDB_GET_KEY(leaf, key);
5852                                 if (data) {
5853                                         if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5854                                                 if (mc->mc_flags & C_DEL)
5855                                                         mdb_xcursor_init1(mc, leaf);
5856                                                 rc = mdb_cursor_get(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_GET_CURRENT);
5857                                         } else {
5858                                                 rc = mdb_node_read(mc->mc_txn, leaf, data);
5859                                         }
5860                                 }
5861                         }
5862                 }
5863                 break;
5864         case MDB_GET_BOTH:
5865         case MDB_GET_BOTH_RANGE:
5866                 if (data == NULL) {
5867                         rc = EINVAL;
5868                         break;
5869                 }
5870                 if (mc->mc_xcursor == NULL) {
5871                         rc = MDB_INCOMPATIBLE;
5872                         break;
5873                 }
5874                 /* FALLTHRU */
5875         case MDB_SET:
5876         case MDB_SET_KEY:
5877         case MDB_SET_RANGE:
5878                 if (key == NULL) {
5879                         rc = EINVAL;
5880                 } else {
5881                         rc = mdb_cursor_set(mc, key, data, op,
5882                                 op == MDB_SET_RANGE ? NULL : &exact);
5883                 }
5884                 break;
5885         case MDB_GET_MULTIPLE:
5886                 if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
5887                         rc = EINVAL;
5888                         break;
5889                 }
5890                 if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
5891                         rc = MDB_INCOMPATIBLE;
5892                         break;
5893                 }
5894                 rc = MDB_SUCCESS;
5895                 if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) ||
5896                         (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF))
5897                         break;
5898                 goto fetchm;
5899         case MDB_NEXT_MULTIPLE:
5900                 if (data == NULL) {
5901                         rc = EINVAL;
5902                         break;
5903                 }
5904                 if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
5905                         rc = MDB_INCOMPATIBLE;
5906                         break;
5907                 }
5908                 if (!(mc->mc_flags & C_INITIALIZED))
5909                         rc = mdb_cursor_first(mc, key, data);
5910                 else
5911                         rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
5912                 if (rc == MDB_SUCCESS) {
5913                         if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
5914                                 MDB_cursor *mx;
5915 fetchm:
5916                                 mx = &mc->mc_xcursor->mx_cursor;
5917                                 data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
5918                                         mx->mc_db->md_pad;
5919                                 data->mv_data = METADATA(mx->mc_pg[mx->mc_top]);
5920                                 mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;
5921                         } else {
5922                                 rc = MDB_NOTFOUND;
5923                         }
5924                 }
5925                 break;
5926         case MDB_NEXT:
5927         case MDB_NEXT_DUP:
5928         case MDB_NEXT_NODUP:
5929                 if (!(mc->mc_flags & C_INITIALIZED))
5930                         rc = mdb_cursor_first(mc, key, data);
5931                 else
5932                         rc = mdb_cursor_next(mc, key, data, op);
5933                 break;
5934         case MDB_PREV:
5935         case MDB_PREV_DUP:
5936         case MDB_PREV_NODUP:
5937                 if (!(mc->mc_flags & C_INITIALIZED)) {
5938                         rc = mdb_cursor_last(mc, key, data);
5939                         if (rc)
5940                                 break;
5941                         mc->mc_flags |= C_INITIALIZED;
5942                         mc->mc_ki[mc->mc_top]++;
5943                 }
5944                 rc = mdb_cursor_prev(mc, key, data, op);
5945                 break;
5946         case MDB_FIRST:
5947                 rc = mdb_cursor_first(mc, key, data);
5948                 break;
5949         case MDB_FIRST_DUP:
5950                 mfunc = mdb_cursor_first;
5951         mmove:
5952                 if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
5953                         rc = EINVAL;
5954                         break;
5955                 }
5956                 if (mc->mc_xcursor == NULL) {
5957                         rc = MDB_INCOMPATIBLE;
5958                         break;
5959                 }
5960                 {
5961                         MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
5962                         if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
5963                                 MDB_GET_KEY(leaf, key);
5964                                 rc = mdb_node_read(mc->mc_txn, leaf, data);
5965                                 break;
5966                         }
5967                 }
5968                 if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
5969                         rc = EINVAL;
5970                         break;
5971                 }
5972                 rc = mfunc(&mc->mc_xcursor->mx_cursor, data, NULL);
5973                 break;
5974         case MDB_LAST:
5975                 rc = mdb_cursor_last(mc, key, data);
5976                 break;
5977         case MDB_LAST_DUP:
5978                 mfunc = mdb_cursor_last;
5979                 goto mmove;
5980         default:
5981                 DPRINTF(("unhandled/unimplemented cursor operation %u", op));
5982                 rc = EINVAL;
5983                 break;
5984         }
5985
5986         if (mc->mc_flags & C_DEL)
5987                 mc->mc_flags ^= C_DEL;
5988
5989         return rc;
5990 }
5991
5992 /** Touch all the pages in the cursor stack. Set mc_top.
5993  *      Makes sure all the pages are writable, before attempting a write operation.
5994  * @param[in] mc The cursor to operate on.
5995  */
5996 static int
5997 mdb_cursor_touch(MDB_cursor *mc)
5998 {
5999         int rc = MDB_SUCCESS;
6000
6001         if (mc->mc_dbi > MAIN_DBI && !(*mc->mc_dbflag & DB_DIRTY)) {
6002                 MDB_cursor mc2;
6003                 MDB_xcursor mcx;
6004                 if (TXN_DBI_CHANGED(mc->mc_txn, mc->mc_dbi))
6005                         return MDB_BAD_DBI;
6006                 mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, &mcx);
6007                 rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, MDB_PS_MODIFY);
6008                 if (rc)
6009                          return rc;
6010                 *mc->mc_dbflag |= DB_DIRTY;
6011         }
6012         mc->mc_top = 0;
6013         if (mc->mc_snum) {
6014                 do {
6015                         rc = mdb_page_touch(mc);
6016                 } while (!rc && ++(mc->mc_top) < mc->mc_snum);
6017                 mc->mc_top = mc->mc_snum-1;
6018         }
6019         return rc;
6020 }
6021
6022 /** Do not spill pages to disk if txn is getting full, may fail instead */
6023 #define MDB_NOSPILL     0x8000
6024
6025 int
6026 mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
6027     unsigned int flags)
6028 {
6029         enum { MDB_NO_ROOT = MDB_LAST_ERRCODE+10 }; /* internal code */
6030         MDB_env         *env;
6031         MDB_node        *leaf = NULL;
6032         MDB_page        *fp, *mp;
6033         uint16_t        fp_flags;
6034         MDB_val         xdata, *rdata, dkey, olddata;
6035         MDB_db dummy;
6036         int do_sub = 0, insert_key, insert_data;
6037         unsigned int mcount = 0, dcount = 0, nospill;
6038         size_t nsize;
6039         int rc, rc2;
6040         unsigned int nflags;
6041         DKBUF;
6042
6043         if (mc == NULL || key == NULL)
6044                 return EINVAL;
6045
6046         env = mc->mc_txn->mt_env;
6047
6048         /* Check this first so counter will always be zero on any
6049          * early failures.
6050          */
6051         if (flags & MDB_MULTIPLE) {
6052                 dcount = data[1].mv_size;
6053                 data[1].mv_size = 0;
6054                 if (!F_ISSET(mc->mc_db->md_flags, MDB_DUPFIXED))
6055                         return MDB_INCOMPATIBLE;
6056         }
6057
6058         nospill = flags & MDB_NOSPILL;
6059         flags &= ~MDB_NOSPILL;
6060
6061         if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
6062                 return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
6063
6064         if (key->mv_size-1 >= ENV_MAXKEY(env))
6065                 return MDB_BAD_VALSIZE;
6066
6067 #if SIZE_MAX > MAXDATASIZE
6068         if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE))
6069                 return MDB_BAD_VALSIZE;
6070 #else
6071         if ((mc->mc_db->md_flags & MDB_DUPSORT) && data->mv_size > ENV_MAXKEY(env))
6072                 return MDB_BAD_VALSIZE;
6073 #endif
6074
6075         DPRINTF(("==> put db %d key [%s], size %"Z"u, data size %"Z"u",
6076                 DDBI(mc), DKEY(key), key ? key->mv_size : 0, data->mv_size));
6077
6078         dkey.mv_size = 0;
6079
6080         if (flags == MDB_CURRENT) {
6081                 if (!(mc->mc_flags & C_INITIALIZED))
6082                         return EINVAL;
6083                 rc = MDB_SUCCESS;
6084         } else if (mc->mc_db->md_root == P_INVALID) {
6085                 /* new database, cursor has nothing to point to */
6086                 mc->mc_snum = 0;
6087                 mc->mc_top = 0;
6088                 mc->mc_flags &= ~C_INITIALIZED;
6089                 rc = MDB_NO_ROOT;
6090         } else {
6091                 int exact = 0;
6092                 MDB_val d2;
6093                 if (flags & MDB_APPEND) {
6094                         MDB_val k2;
6095                         rc = mdb_cursor_last(mc, &k2, &d2);
6096                         if (rc == 0) {
6097                                 rc = mc->mc_dbx->md_cmp(key, &k2);
6098                                 if (rc > 0) {
6099                                         rc = MDB_NOTFOUND;
6100                                         mc->mc_ki[mc->mc_top]++;
6101                                 } else {
6102                                         /* new key is <= last key */
6103                                         rc = MDB_KEYEXIST;
6104                                 }
6105                         }
6106                 } else {
6107                         rc = mdb_cursor_set(mc, key, &d2, MDB_SET, &exact);
6108                 }
6109                 if ((flags & MDB_NOOVERWRITE) && rc == 0) {
6110                         DPRINTF(("duplicate key [%s]", DKEY(key)));
6111                         *data = d2;
6112                         return MDB_KEYEXIST;
6113                 }
6114                 if (rc && rc != MDB_NOTFOUND)
6115                         return rc;
6116         }
6117
6118         if (mc->mc_flags & C_DEL)
6119                 mc->mc_flags ^= C_DEL;
6120
6121         /* Cursor is positioned, check for room in the dirty list */
6122         if (!nospill) {
6123                 if (flags & MDB_MULTIPLE) {
6124                         rdata = &xdata;
6125                         xdata.mv_size = data->mv_size * dcount;
6126                 } else {
6127                         rdata = data;
6128                 }
6129                 if ((rc2 = mdb_page_spill(mc, key, rdata)))
6130                         return rc2;
6131         }
6132
6133         if (rc == MDB_NO_ROOT) {
6134                 MDB_page *np;
6135                 /* new database, write a root leaf page */
6136                 DPUTS("allocating new root leaf page");
6137                 if ((rc2 = mdb_page_new(mc, P_LEAF, 1, &np))) {
6138                         return rc2;
6139                 }
6140                 mdb_cursor_push(mc, np);
6141                 mc->mc_db->md_root = np->mp_pgno;
6142                 mc->mc_db->md_depth++;
6143                 *mc->mc_dbflag |= DB_DIRTY;
6144                 if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED))
6145                         == MDB_DUPFIXED)
6146                         np->mp_flags |= P_LEAF2;
6147                 mc->mc_flags |= C_INITIALIZED;
6148         } else {
6149                 /* make sure all cursor pages are writable */
6150                 rc2 = mdb_cursor_touch(mc);
6151                 if (rc2)
6152                         return rc2;
6153         }
6154
6155         insert_key = insert_data = rc;
6156         if (insert_key) {
6157                 /* The key does not exist */
6158                 DPRINTF(("inserting key at index %i", mc->mc_ki[mc->mc_top]));
6159                 if ((mc->mc_db->md_flags & MDB_DUPSORT) &&
6160                         LEAFSIZE(key, data) > env->me_nodemax)
6161                 {
6162                         /* Too big for a node, insert in sub-DB.  Set up an empty
6163                          * "old sub-page" for prep_subDB to expand to a full page.
6164                          */
6165                         fp_flags = P_LEAF|P_DIRTY;
6166                         fp = env->me_pbuf;
6167                         fp->mp_pad = data->mv_size; /* used if MDB_DUPFIXED */
6168                         fp->mp_lower = fp->mp_upper = (PAGEHDRSZ-PAGEBASE);
6169                         olddata.mv_size = PAGEHDRSZ;
6170                         goto prep_subDB;
6171                 }
6172         } else {
6173                 /* there's only a key anyway, so this is a no-op */
6174                 if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
6175                         char *ptr;
6176                         unsigned int ksize = mc->mc_db->md_pad;
6177                         if (key->mv_size != ksize)
6178                                 return MDB_BAD_VALSIZE;
6179                         ptr = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], ksize);
6180                         memcpy(ptr, key->mv_data, ksize);
6181 fix_parent:
6182                         /* if overwriting slot 0 of leaf, need to
6183                          * update branch key if there is a parent page
6184                          */
6185                         if (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
6186                                 unsigned short top = mc->mc_top;
6187                                 mc->mc_top--;
6188                                 /* slot 0 is always an empty key, find real slot */
6189                                 while (mc->mc_top && !mc->mc_ki[mc->mc_top])
6190                                         mc->mc_top--;
6191                                 if (mc->mc_ki[mc->mc_top])
6192                                         rc2 = mdb_update_key(mc, key);
6193                                 else
6194                                         rc2 = MDB_SUCCESS;
6195                                 mc->mc_top = top;
6196                                 if (rc2)
6197                                         return rc2;
6198                         }
6199                         return MDB_SUCCESS;
6200                 }
6201
6202 more:
6203                 leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
6204                 olddata.mv_size = NODEDSZ(leaf);
6205                 olddata.mv_data = NODEDATA(leaf);
6206
6207                 /* DB has dups? */
6208                 if (F_ISSET(mc->mc_db->md_flags, MDB_DUPSORT)) {
6209                         /* Prepare (sub-)page/sub-DB to accept the new item,
6210                          * if needed.  fp: old sub-page or a header faking
6211                          * it.  mp: new (sub-)page.  offset: growth in page
6212                          * size.  xdata: node data with new page or DB.
6213                          */
6214                         unsigned        i, offset = 0;
6215                         mp = fp = xdata.mv_data = env->me_pbuf;
6216                         mp->mp_pgno = mc->mc_pg[mc->mc_top]->mp_pgno;
6217
6218                         /* Was a single item before, must convert now */
6219                         if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
6220                                 /* Just overwrite the current item */
6221                                 if (flags == MDB_CURRENT)
6222                                         goto current;
6223
6224 #if UINT_MAX < SIZE_MAX
6225                                 if (mc->mc_dbx->md_dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
6226                                         mc->mc_dbx->md_dcmp = mdb_cmp_clong;
6227 #endif
6228                                 /* does data match? */
6229                                 if (!mc->mc_dbx->md_dcmp(data, &olddata)) {
6230                                         if (flags & MDB_NODUPDATA)
6231                                                 return MDB_KEYEXIST;
6232                                         /* overwrite it */
6233                                         goto current;
6234                                 }
6235
6236                                 /* Back up original data item */
6237                                 dkey.mv_size = olddata.mv_size;
6238                                 dkey.mv_data = memcpy(fp+1, olddata.mv_data, olddata.mv_size);
6239
6240                                 /* Make sub-page header for the dup items, with dummy body */
6241                                 fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP;
6242                                 fp->mp_lower = (PAGEHDRSZ-PAGEBASE);
6243                                 xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size;
6244                                 if (mc->mc_db->md_flags & MDB_DUPFIXED) {
6245                                         fp->mp_flags |= P_LEAF2;
6246                                         fp->mp_pad = data->mv_size;
6247                                         xdata.mv_size += 2 * data->mv_size;     /* leave space for 2 more */
6248                                 } else {
6249                                         xdata.mv_size += 2 * (sizeof(indx_t) + NODESIZE) +
6250                                                 (dkey.mv_size & 1) + (data->mv_size & 1);
6251                                 }
6252                                 fp->mp_upper = xdata.mv_size - PAGEBASE;
6253                                 olddata.mv_size = xdata.mv_size; /* pretend olddata is fp */
6254                         } else if (leaf->mn_flags & F_SUBDATA) {
6255                                 /* Data is on sub-DB, just store it */
6256                                 flags |= F_DUPDATA|F_SUBDATA;
6257                                 goto put_sub;
6258                         } else {
6259                                 /* Data is on sub-page */
6260                                 fp = olddata.mv_data;
6261                                 switch (flags) {
6262                                 default:
6263                                         if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
6264                                                 offset = EVEN(NODESIZE + sizeof(indx_t) +
6265                                                         data->mv_size);
6266                                                 break;
6267                                         }
6268                                         offset = fp->mp_pad;
6269                                         if (SIZELEFT(fp) < offset) {
6270                                                 offset *= 4; /* space for 4 more */
6271                                                 break;
6272                                         }
6273                                         /* FALLTHRU: Big enough MDB_DUPFIXED sub-page */
6274                                 case MDB_CURRENT:
6275                                         fp->mp_flags |= P_DIRTY;
6276                                         COPY_PGNO(fp->mp_pgno, mp->mp_pgno);
6277                                         mc->mc_xcursor->mx_cursor.mc_pg[0] = fp;
6278                                         flags |= F_DUPDATA;
6279                                         goto put_sub;
6280                                 }
6281                                 xdata.mv_size = olddata.mv_size + offset;
6282                         }
6283
6284                         fp_flags = fp->mp_flags;
6285                         if (NODESIZE + NODEKSZ(leaf) + xdata.mv_size > env->me_nodemax) {
6286                                         /* Too big for a sub-page, convert to sub-DB */
6287                                         fp_flags &= ~P_SUBP;
6288 prep_subDB:
6289                                         if (mc->mc_db->md_flags & MDB_DUPFIXED) {
6290                                                 fp_flags |= P_LEAF2;
6291                                                 dummy.md_pad = fp->mp_pad;
6292                                                 dummy.md_flags = MDB_DUPFIXED;
6293                                                 if (mc->mc_db->md_flags & MDB_INTEGERDUP)
6294                                                         dummy.md_flags |= MDB_INTEGERKEY;
6295                                         } else {
6296                                                 dummy.md_pad = 0;
6297                                                 dummy.md_flags = 0;
6298                                         }
6299                                         dummy.md_depth = 1;
6300                                         dummy.md_branch_pages = 0;
6301                                         dummy.md_leaf_pages = 1;
6302                                         dummy.md_overflow_pages = 0;
6303                                         dummy.md_entries = NUMKEYS(fp);
6304                                         xdata.mv_size = sizeof(MDB_db);
6305                                         xdata.mv_data = &dummy;
6306                                         if ((rc = mdb_page_alloc(mc, 1, &mp)))
6307                                                 return rc;
6308                                         offset = env->me_psize - olddata.mv_size;
6309                                         flags |= F_DUPDATA|F_SUBDATA;
6310                                         dummy.md_root = mp->mp_pgno;
6311                         }
6312                         if (mp != fp) {
6313                                 mp->mp_flags = fp_flags | P_DIRTY;
6314                                 mp->mp_pad   = fp->mp_pad;
6315                                 mp->mp_lower = fp->mp_lower;
6316                                 mp->mp_upper = fp->mp_upper + offset;
6317                                 if (fp_flags & P_LEAF2) {
6318                                         memcpy(METADATA(mp), METADATA(fp), NUMKEYS(fp) * fp->mp_pad);
6319                                 } else {
6320                                         memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE,
6321                                                 olddata.mv_size - fp->mp_upper - PAGEBASE);
6322                                         for (i=0; i<NUMKEYS(fp); i++)
6323                                                 mp->mp_ptrs[i] = fp->mp_ptrs[i] + offset;
6324                                 }
6325                         }
6326
6327                         rdata = &xdata;
6328                         flags |= F_DUPDATA;
6329                         do_sub = 1;
6330                         if (!insert_key)
6331                                 mdb_node_del(mc, 0);
6332                         goto new_sub;
6333                 }
6334 current:
6335                 /* overflow page overwrites need special handling */
6336                 if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
6337                         MDB_page *omp;
6338                         pgno_t pg;
6339                         int level, ovpages, dpages = OVPAGES(data->mv_size, env->me_psize);
6340
6341                         memcpy(&pg, olddata.mv_data, sizeof(pg));
6342                         if ((rc2 = mdb_page_get(mc->mc_txn, pg, &omp, &level)) != 0)
6343                                 return rc2;
6344                         ovpages = omp->mp_pages;
6345
6346                         /* Is the ov page large enough? */
6347                         if (ovpages >= dpages) {
6348                           if (!(omp->mp_flags & P_DIRTY) &&
6349                                   (level || (env->me_flags & MDB_WRITEMAP)))
6350                           {
6351                                 rc = mdb_page_unspill(mc->mc_txn, omp, &omp);
6352                                 if (rc)
6353                                         return rc;
6354                                 level = 0;              /* dirty in this txn or clean */
6355                           }
6356                           /* Is it dirty? */
6357                           if (omp->mp_flags & P_DIRTY) {
6358                                 /* yes, overwrite it. Note in this case we don't
6359                                  * bother to try shrinking the page if the new data
6360                                  * is smaller than the overflow threshold.
6361                                  */
6362                                 if (level > 1) {
6363                                         /* It is writable only in a parent txn */
6364                                         size_t sz = (size_t) env->me_psize * ovpages, off;
6365                                         MDB_page *np = mdb_page_malloc(mc->mc_txn, ovpages);
6366                                         MDB_ID2 id2;
6367                                         if (!np)
6368                                                 return ENOMEM;
6369                                         id2.mid = pg;
6370                                         id2.mptr = np;
6371                                         rc2 = mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2);
6372                                         mdb_cassert(mc, rc2 == 0);
6373                                         if (!(flags & MDB_RESERVE)) {
6374                                                 /* Copy end of page, adjusting alignment so
6375                                                  * compiler may copy words instead of bytes.
6376                                                  */
6377                                                 off = (PAGEHDRSZ + data->mv_size) & -sizeof(size_t);
6378                                                 memcpy((size_t *)((char *)np + off),
6379                                                         (size_t *)((char *)omp + off), sz - off);
6380                                                 sz = PAGEHDRSZ;
6381                                         }
6382                                         memcpy(np, omp, sz); /* Copy beginning of page */
6383                                         omp = np;
6384                                 }
6385                                 SETDSZ(leaf, data->mv_size);
6386                                 if (F_ISSET(flags, MDB_RESERVE))
6387                                         data->mv_data = METADATA(omp);
6388                                 else
6389                                         memcpy(METADATA(omp), data->mv_data, data->mv_size);
6390                                 return MDB_SUCCESS;
6391                           }
6392                         }
6393                         if ((rc2 = mdb_ovpage_free(mc, omp)) != MDB_SUCCESS)
6394                                 return rc2;
6395                 } else if (data->mv_size == olddata.mv_size) {
6396                         /* same size, just replace it. Note that we could
6397                          * also reuse this node if the new data is smaller,
6398                          * but instead we opt to shrink the node in that case.
6399                          */
6400                         if (F_ISSET(flags, MDB_RESERVE))
6401                                 data->mv_data = olddata.mv_data;
6402                         else if (!(mc->mc_flags & C_SUB))
6403                                 memcpy(olddata.mv_data, data->mv_data, data->mv_size);
6404                         else {
6405                                 memcpy(NODEKEY(leaf), key->mv_data, key->mv_size);
6406                                 goto fix_parent;
6407                         }
6408                         return MDB_SUCCESS;
6409                 }
6410                 mdb_node_del(mc, 0);
6411         }
6412
6413         rdata = data;
6414
6415 new_sub:
6416         nflags = flags & NODE_ADD_FLAGS;
6417         nsize = IS_LEAF2(mc->mc_pg[mc->mc_top]) ? key->mv_size : mdb_leaf_size(env, key, rdata);
6418         if (SIZELEFT(mc->mc_pg[mc->mc_top]) < nsize) {
6419                 if (( flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA )
6420                         nflags &= ~MDB_APPEND; /* sub-page may need room to grow */
6421                 if (!insert_key)
6422                         nflags |= MDB_SPLIT_REPLACE;
6423                 rc = mdb_page_split(mc, key, rdata, P_INVALID, nflags);
6424         } else {
6425                 /* There is room already in this leaf page. */
6426                 rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags);
6427                 if (rc == 0 && insert_key) {
6428                         /* Adjust other cursors pointing to mp */
6429                         MDB_cursor *m2, *m3;
6430                         MDB_dbi dbi = mc->mc_dbi;
6431                         unsigned i = mc->mc_top;
6432                         MDB_page *mp = mc->mc_pg[i];
6433
6434                         for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
6435                                 if (mc->mc_flags & C_SUB)
6436                                         m3 = &m2->mc_xcursor->mx_cursor;
6437                                 else
6438                                         m3 = m2;
6439                                 if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
6440                                 if (m3->mc_pg[i] == mp && m3->mc_ki[i] >= mc->mc_ki[i]) {
6441                                         m3->mc_ki[i]++;
6442                                 }
6443                         }
6444                 }
6445         }
6446
6447         if (rc == MDB_SUCCESS) {
6448                 /* Now store the actual data in the child DB. Note that we're
6449                  * storing the user data in the keys field, so there are strict
6450                  * size limits on dupdata. The actual data fields of the child
6451                  * DB are all zero size.
6452                  */
6453                 if (do_sub) {
6454                         int xflags;
6455                         size_t ecount;
6456 put_sub:
6457                         xdata.mv_size = 0;
6458                         xdata.mv_data = "";
6459                         leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
6460                         if (flags & MDB_CURRENT) {
6461                                 xflags = MDB_CURRENT|MDB_NOSPILL;
6462                         } else {
6463                                 mdb_xcursor_init1(mc, leaf);
6464                                 xflags = (flags & MDB_NODUPDATA) ?
6465                                         MDB_NOOVERWRITE|MDB_NOSPILL : MDB_NOSPILL;
6466                         }
6467                         /* converted, write the original data first */
6468                         if (dkey.mv_size) {
6469                                 rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, &dkey, &xdata, xflags);
6470                                 if (rc)
6471                                         goto bad_sub;
6472                                 {
6473                                         /* Adjust other cursors pointing to mp */
6474                                         MDB_cursor *m2;
6475                                         unsigned i = mc->mc_top;
6476                                         MDB_page *mp = mc->mc_pg[i];
6477
6478                                         for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) {
6479                                                 if (m2 == mc || m2->mc_snum < mc->mc_snum) continue;
6480                                                 if (!(m2->mc_flags & C_INITIALIZED)) continue;
6481                                                 if (m2->mc_pg[i] == mp && m2->mc_ki[i] == mc->mc_ki[i]) {
6482                                                         mdb_xcursor_init1(m2, leaf);
6483                                                 }
6484                                         }
6485                                 }
6486                                 /* we've done our job */
6487                                 dkey.mv_size = 0;
6488                         }
6489                         ecount = mc->mc_xcursor->mx_db.md_entries;
6490                         if (flags & MDB_APPENDDUP)
6491                                 xflags |= MDB_APPEND;
6492                         rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags);
6493                         if (flags & F_SUBDATA) {
6494                                 void *db = NODEDATA(leaf);
6495                                 memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db));
6496                         }
6497                         insert_data = mc->mc_xcursor->mx_db.md_entries - ecount;
6498                 }
6499                 /* Increment count unless we just replaced an existing item. */
6500                 if (insert_data)
6501                         mc->mc_db->md_entries++;
6502                 if (insert_key) {
6503                         /* Invalidate txn if we created an empty sub-DB */
6504                         if (rc)
6505                                 goto bad_sub;
6506                         /* If we succeeded and the key didn't exist before,
6507                          * make sure the cursor is marked valid.
6508                          */
6509                         mc->mc_flags |= C_INITIALIZED;
6510                 }
6511                 if (flags & MDB_MULTIPLE) {
6512                         if (!rc) {
6513                                 mcount++;
6514                                 /* let caller know how many succeeded, if any */
6515                                 data[1].mv_size = mcount;
6516                                 if (mcount < dcount) {
6517                                         data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size;
6518                                         insert_key = insert_data = 0;
6519                                         goto more;
6520                                 }
6521                         }
6522                 }
6523                 return rc;
6524 bad_sub:
6525                 if (rc == MDB_KEYEXIST) /* should not happen, we deleted that item */
6526                         rc = MDB_CORRUPTED;
6527         }
6528         mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
6529         return rc;
6530 }
6531
6532 int
6533 mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
6534 {
6535         MDB_node        *leaf;
6536         MDB_page        *mp;
6537         int rc;
6538
6539         if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
6540                 return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
6541
6542         if (!(mc->mc_flags & C_INITIALIZED))
6543                 return EINVAL;
6544
6545         if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top]))
6546                 return MDB_NOTFOUND;
6547
6548         if (!(flags & MDB_NOSPILL) && (rc = mdb_page_spill(mc, NULL, NULL)))
6549                 return rc;
6550
6551         rc = mdb_cursor_touch(mc);
6552         if (rc)
6553                 return rc;
6554
6555         mp = mc->mc_pg[mc->mc_top];
6556         if (IS_LEAF2(mp))
6557                 goto del_key;
6558         leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
6559
6560         if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
6561                 if (flags & MDB_NODUPDATA) {
6562                         /* mdb_cursor_del0() will subtract the final entry */
6563                         mc->mc_db->md_entries -= mc->mc_xcursor->mx_db.md_entries - 1;
6564                 } else {
6565                         if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) {
6566                                 mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
6567                         }
6568                         rc = mdb_cursor_del(&mc->mc_xcursor->mx_cursor, MDB_NOSPILL);
6569                         if (rc)
6570                                 return rc;
6571                         /* If sub-DB still has entries, we're done */
6572                         if (mc->mc_xcursor->mx_db.md_entries) {
6573                                 if (leaf->mn_flags & F_SUBDATA) {
6574                                         /* update subDB info */
6575                                         void *db = NODEDATA(leaf);
6576                                         memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db));
6577                                 } else {
6578                                         MDB_cursor *m2;
6579                                         /* shrink fake page */
6580                                         mdb_node_shrink(mp, mc->mc_ki[mc->mc_top]);
6581                                         leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
6582                                         mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
6583                                         /* fix other sub-DB cursors pointed at this fake page */
6584                                         for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) {
6585                                                 if (m2 == mc || m2->mc_snum < mc->mc_snum) continue;
6586                                                 if (m2->mc_pg[mc->mc_top] == mp &&
6587                                                         m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top])
6588                                                         m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
6589                                         }
6590                                 }
6591                                 mc->mc_db->md_entries--;
6592                                 mc->mc_flags |= C_DEL;
6593                                 return rc;
6594                         }
6595                         /* otherwise fall thru and delete the sub-DB */
6596                 }
6597
6598                 if (leaf->mn_flags & F_SUBDATA) {
6599                         /* add all the child DB's pages to the free list */
6600                         rc = mdb_drop0(&mc->mc_xcursor->mx_cursor, 0);
6601                         if (rc)
6602                                 goto fail;
6603                 }
6604         }
6605
6606         /* add overflow pages to free list */
6607         if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
6608                 MDB_page *omp;
6609                 pgno_t pg;
6610
6611                 memcpy(&pg, NODEDATA(leaf), sizeof(pg));
6612                 if ((rc = mdb_page_get(mc->mc_txn, pg, &omp, NULL)) ||
6613                         (rc = mdb_ovpage_free(mc, omp)))
6614                         goto fail;
6615         }
6616
6617 del_key:
6618         return mdb_cursor_del0(mc);
6619
6620 fail:
6621         mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
6622         return rc;
6623 }
6624
6625 /** Allocate and initialize new pages for a database.
6626  * @param[in] mc a cursor on the database being added to.
6627  * @param[in] flags flags defining what type of page is being allocated.
6628  * @param[in] num the number of pages to allocate. This is usually 1,
6629  * unless allocating overflow pages for a large record.
6630  * @param[out] mp Address of a page, or NULL on failure.
6631  * @return 0 on success, non-zero on failure.
6632  */
6633 static int
6634 mdb_page_new(MDB_cursor *mc, uint32_t flags, int num, MDB_page **mp)
6635 {
6636         MDB_page        *np;
6637         int rc;
6638
6639         if ((rc = mdb_page_alloc(mc, num, &np)))
6640                 return rc;
6641         DPRINTF(("allocated new mpage %"Z"u, page size %u",
6642             np->mp_pgno, mc->mc_txn->mt_env->me_psize));
6643         np->mp_flags = flags | P_DIRTY;
6644         np->mp_lower = (PAGEHDRSZ-PAGEBASE);
6645         np->mp_upper = mc->mc_txn->mt_env->me_psize - PAGEBASE;
6646
6647         if (IS_BRANCH(np))
6648                 mc->mc_db->md_branch_pages++;
6649         else if (IS_LEAF(np))
6650                 mc->mc_db->md_leaf_pages++;
6651         else if (IS_OVERFLOW(np)) {
6652                 mc->mc_db->md_overflow_pages += num;
6653                 np->mp_pages = num;
6654         }
6655         *mp = np;
6656
6657         return 0;
6658 }
6659
6660 /** Calculate the size of a leaf node.
6661  * The size depends on the environment's page size; if a data item
6662  * is too large it will be put onto an overflow page and the node
6663  * size will only include the key and not the data. Sizes are always
6664  * rounded up to an even number of bytes, to guarantee 2-byte alignment
6665  * of the #MDB_node headers.
6666  * @param[in] env The environment handle.
6667  * @param[in] key The key for the node.
6668  * @param[in] data The data for the node.
6669  * @return The number of bytes needed to store the node.
6670  */
6671 static size_t
6672 mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data)
6673 {
6674         size_t           sz;
6675
6676         sz = LEAFSIZE(key, data);
6677         if (sz > env->me_nodemax) {
6678                 /* put on overflow page */
6679                 sz -= data->mv_size - sizeof(pgno_t);
6680         }
6681
6682         return EVEN(sz + sizeof(indx_t));
6683 }
6684
6685 /** Calculate the size of a branch node.
6686  * The size should depend on the environment's page size but since
6687  * we currently don't support spilling large keys onto overflow
6688  * pages, it's simply the size of the #MDB_node header plus the
6689  * size of the key. Sizes are always rounded up to an even number
6690  * of bytes, to guarantee 2-byte alignment of the #MDB_node headers.
6691  * @param[in] env The environment handle.
6692  * @param[in] key The key for the node.
6693  * @return The number of bytes needed to store the node.
6694  */
6695 static size_t
6696 mdb_branch_size(MDB_env *env, MDB_val *key)
6697 {
6698         size_t           sz;
6699
6700         sz = INDXSIZE(key);
6701         if (sz > env->me_nodemax) {
6702                 /* put on overflow page */
6703                 /* not implemented */
6704                 /* sz -= key->size - sizeof(pgno_t); */
6705         }
6706
6707         return sz + sizeof(indx_t);
6708 }
6709
6710 /** Add a node to the page pointed to by the cursor.
6711  * @param[in] mc The cursor for this operation.
6712  * @param[in] indx The index on the page where the new node should be added.
6713  * @param[in] key The key for the new node.
6714  * @param[in] data The data for the new node, if any.
6715  * @param[in] pgno The page number, if adding a branch node.
6716  * @param[in] flags Flags for the node.
6717  * @return 0 on success, non-zero on failure. Possible errors are:
6718  * <ul>
6719  *      <li>ENOMEM - failed to allocate overflow pages for the node.
6720  *      <li>MDB_PAGE_FULL - there is insufficient room in the page. This error
6721  *      should never happen since all callers already calculate the
6722  *      page's free space before calling this function.
6723  * </ul>
6724  */
6725 static int
6726 mdb_node_add(MDB_cursor *mc, indx_t indx,
6727     MDB_val *key, MDB_val *data, pgno_t pgno, unsigned int flags)
6728 {
6729         unsigned int     i;
6730         size_t           node_size = NODESIZE;
6731         ssize_t          room;
6732         indx_t           ofs;
6733         MDB_node        *node;
6734         MDB_page        *mp = mc->mc_pg[mc->mc_top];
6735         MDB_page        *ofp = NULL;            /* overflow page */
6736         DKBUF;
6737
6738         mdb_cassert(mc, mp->mp_upper >= mp->mp_lower);
6739
6740         DPRINTF(("add to %s %spage %"Z"u index %i, data size %"Z"u key size %"Z"u [%s]",
6741             IS_LEAF(mp) ? "leaf" : "branch",
6742                 IS_SUBP(mp) ? "sub-" : "",
6743                 mdb_dbg_pgno(mp), indx, data ? data->mv_size : 0,
6744                 key ? key->mv_size : 0, key ? DKEY(key) : "null"));
6745
6746         if (IS_LEAF2(mp)) {
6747                 /* Move higher keys up one slot. */
6748                 int ksize = mc->mc_db->md_pad, dif;
6749                 char *ptr = LEAF2KEY(mp, indx, ksize);
6750                 dif = NUMKEYS(mp) - indx;
6751                 if (dif > 0)
6752                         memmove(ptr+ksize, ptr, dif*ksize);
6753                 /* insert new key */
6754                 memcpy(ptr, key->mv_data, ksize);
6755
6756                 /* Just using these for counting */
6757                 mp->mp_lower += sizeof(indx_t);
6758                 mp->mp_upper -= ksize - sizeof(indx_t);
6759                 return MDB_SUCCESS;
6760         }
6761
6762         room = (ssize_t)SIZELEFT(mp) - (ssize_t)sizeof(indx_t);
6763         if (key != NULL)
6764                 node_size += key->mv_size;
6765         if (IS_LEAF(mp)) {
6766                 mdb_cassert(mc, data);
6767                 if (F_ISSET(flags, F_BIGDATA)) {
6768                         /* Data already on overflow page. */
6769                         node_size += sizeof(pgno_t);
6770                 } else if (node_size + data->mv_size > mc->mc_txn->mt_env->me_nodemax) {
6771                         int ovpages = OVPAGES(data->mv_size, mc->mc_txn->mt_env->me_psize);
6772                         int rc;
6773                         /* Put data on overflow page. */
6774                         DPRINTF(("data size is %"Z"u, node would be %"Z"u, put data on overflow page",
6775                             data->mv_size, node_size+data->mv_size));
6776                         node_size = EVEN(node_size + sizeof(pgno_t));
6777                         if ((ssize_t)node_size > room)
6778                                 goto full;
6779                         if ((rc = mdb_page_new(mc, P_OVERFLOW, ovpages, &ofp)))
6780                                 return rc;
6781                         DPRINTF(("allocated overflow page %"Z"u", ofp->mp_pgno));
6782                         flags |= F_BIGDATA;
6783                         goto update;
6784                 } else {
6785                         node_size += data->mv_size;
6786                 }
6787         }
6788         node_size = EVEN(node_size);
6789         if ((ssize_t)node_size > room)
6790                 goto full;
6791
6792 update:
6793         /* Move higher pointers up one slot. */
6794         for (i = NUMKEYS(mp); i > indx; i--)
6795                 mp->mp_ptrs[i] = mp->mp_ptrs[i - 1];
6796
6797         /* Adjust free space offsets. */
6798         ofs = mp->mp_upper - node_size;
6799         mdb_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t));
6800         mp->mp_ptrs[indx] = ofs;
6801         mp->mp_upper = ofs;
6802         mp->mp_lower += sizeof(indx_t);
6803
6804         /* Write the node data. */
6805         node = NODEPTR(mp, indx);
6806         node->mn_ksize = (key == NULL) ? 0 : key->mv_size;
6807         node->mn_flags = flags;
6808         if (IS_LEAF(mp))
6809                 SETDSZ(node,data->mv_size);
6810         else
6811                 SETPGNO(node,pgno);
6812
6813         if (key)
6814                 memcpy(NODEKEY(node), key->mv_data, key->mv_size);
6815
6816         if (IS_LEAF(mp)) {
6817                 mdb_cassert(mc, key);
6818                 if (ofp == NULL) {
6819                         if (F_ISSET(flags, F_BIGDATA))
6820                                 memcpy(node->mn_data + key->mv_size, data->mv_data,
6821                                     sizeof(pgno_t));
6822                         else if (F_ISSET(flags, MDB_RESERVE))
6823                                 data->mv_data = node->mn_data + key->mv_size;
6824                         else
6825                                 memcpy(node->mn_data + key->mv_size, data->mv_data,
6826                                     data->mv_size);
6827                 } else {
6828                         memcpy(node->mn_data + key->mv_size, &ofp->mp_pgno,
6829                             sizeof(pgno_t));
6830                         if (F_ISSET(flags, MDB_RESERVE))
6831                                 data->mv_data = METADATA(ofp);
6832                         else
6833                                 memcpy(METADATA(ofp), data->mv_data, data->mv_size);
6834                 }
6835         }
6836
6837         return MDB_SUCCESS;
6838
6839 full:
6840         DPRINTF(("not enough room in page %"Z"u, got %u ptrs",
6841                 mdb_dbg_pgno(mp), NUMKEYS(mp)));
6842         DPRINTF(("upper-lower = %u - %u = %"Z"d", mp->mp_upper,mp->mp_lower,room));
6843         DPRINTF(("node size = %"Z"u", node_size));
6844         mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
6845         return MDB_PAGE_FULL;
6846 }
6847
6848 /** Delete the specified node from a page.
6849  * @param[in] mc Cursor pointing to the node to delete.
6850  * @param[in] ksize The size of a node. Only used if the page is
6851  * part of a #MDB_DUPFIXED database.
6852  */
6853 static void
6854 mdb_node_del(MDB_cursor *mc, int ksize)
6855 {
6856         MDB_page *mp = mc->mc_pg[mc->mc_top];
6857         indx_t  indx = mc->mc_ki[mc->mc_top];
6858         unsigned int     sz;
6859         indx_t           i, j, numkeys, ptr;
6860         MDB_node        *node;
6861         char            *base;
6862
6863         DPRINTF(("delete node %u on %s page %"Z"u", indx,
6864             IS_LEAF(mp) ? "leaf" : "branch", mdb_dbg_pgno(mp)));
6865         numkeys = NUMKEYS(mp);
6866         mdb_cassert(mc, indx < numkeys);
6867
6868         if (IS_LEAF2(mp)) {
6869                 int x = numkeys - 1 - indx;
6870                 base = LEAF2KEY(mp, indx, ksize);
6871                 if (x)
6872                         memmove(base, base + ksize, x * ksize);
6873                 mp->mp_lower -= sizeof(indx_t);
6874                 mp->mp_upper += ksize - sizeof(indx_t);
6875                 return;
6876         }
6877
6878         node = NODEPTR(mp, indx);
6879         sz = NODESIZE + node->mn_ksize;
6880         if (IS_LEAF(mp)) {
6881                 if (F_ISSET(node->mn_flags, F_BIGDATA))
6882                         sz += sizeof(pgno_t);
6883                 else
6884                         sz += NODEDSZ(node);
6885         }
6886         sz = EVEN(sz);
6887
6888         ptr = mp->mp_ptrs[indx];
6889         for (i = j = 0; i < numkeys; i++) {
6890                 if (i != indx) {
6891                         mp->mp_ptrs[j] = mp->mp_ptrs[i];
6892                         if (mp->mp_ptrs[i] < ptr)
6893                                 mp->mp_ptrs[j] += sz;
6894                         j++;
6895                 }
6896         }
6897
6898         base = (char *)mp + mp->mp_upper + PAGEBASE;
6899         memmove(base + sz, base, ptr - mp->mp_upper);
6900
6901         mp->mp_lower -= sizeof(indx_t);
6902         mp->mp_upper += sz;
6903 }
6904
6905 /** Compact the main page after deleting a node on a subpage.
6906  * @param[in] mp The main page to operate on.
6907  * @param[in] indx The index of the subpage on the main page.
6908  */
6909 static void
6910 mdb_node_shrink(MDB_page *mp, indx_t indx)
6911 {
6912         MDB_node *node;
6913         MDB_page *sp, *xp;
6914         char *base;
6915         int nsize, delta;
6916         indx_t           i, numkeys, ptr;
6917
6918         node = NODEPTR(mp, indx);
6919         sp = (MDB_page *)NODEDATA(node);
6920         delta = SIZELEFT(sp);
6921         xp = (MDB_page *)((char *)sp + delta);
6922
6923         /* shift subpage upward */
6924         if (IS_LEAF2(sp)) {
6925                 nsize = NUMKEYS(sp) * sp->mp_pad;
6926                 if (nsize & 1)
6927                         return;         /* do not make the node uneven-sized */
6928                 memmove(METADATA(xp), METADATA(sp), nsize);
6929         } else {
6930                 int i;
6931                 numkeys = NUMKEYS(sp);
6932                 for (i=numkeys-1; i>=0; i--)
6933                         xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta;
6934         }
6935         xp->mp_upper = sp->mp_lower;
6936         xp->mp_lower = sp->mp_lower;
6937         xp->mp_flags = sp->mp_flags;
6938         xp->mp_pad = sp->mp_pad;
6939         COPY_PGNO(xp->mp_pgno, mp->mp_pgno);
6940
6941         nsize = NODEDSZ(node) - delta;
6942         SETDSZ(node, nsize);
6943
6944         /* shift lower nodes upward */
6945         ptr = mp->mp_ptrs[indx];
6946         numkeys = NUMKEYS(mp);
6947         for (i = 0; i < numkeys; i++) {
6948                 if (mp->mp_ptrs[i] <= ptr)
6949                         mp->mp_ptrs[i] += delta;
6950         }
6951
6952         base = (char *)mp + mp->mp_upper + PAGEBASE;
6953         memmove(base + delta, base, ptr - mp->mp_upper + NODESIZE + NODEKSZ(node));
6954         mp->mp_upper += delta;
6955 }
6956
6957 /** Initial setup of a sorted-dups cursor.
6958  * Sorted duplicates are implemented as a sub-database for the given key.
6959  * The duplicate data items are actually keys of the sub-database.
6960  * Operations on the duplicate data items are performed using a sub-cursor
6961  * initialized when the sub-database is first accessed. This function does
6962  * the preliminary setup of the sub-cursor, filling in the fields that
6963  * depend only on the parent DB.
6964  * @param[in] mc The main cursor whose sorted-dups cursor is to be initialized.
6965  */
6966 static void
6967 mdb_xcursor_init0(MDB_cursor *mc)
6968 {
6969         MDB_xcursor *mx = mc->mc_xcursor;
6970
6971         mx->mx_cursor.mc_xcursor = NULL;
6972         mx->mx_cursor.mc_txn = mc->mc_txn;
6973         mx->mx_cursor.mc_db = &mx->mx_db;
6974         mx->mx_cursor.mc_dbx = &mx->mx_dbx;
6975         mx->mx_cursor.mc_dbi = mc->mc_dbi;
6976         mx->mx_cursor.mc_dbflag = &mx->mx_dbflag;
6977         mx->mx_cursor.mc_snum = 0;
6978         mx->mx_cursor.mc_top = 0;
6979         mx->mx_cursor.mc_flags = C_SUB;
6980         mx->mx_dbx.md_name.mv_size = 0;
6981         mx->mx_dbx.md_name.mv_data = NULL;
6982         mx->mx_dbx.md_cmp = mc->mc_dbx->md_dcmp;
6983         mx->mx_dbx.md_dcmp = NULL;
6984         mx->mx_dbx.md_rel = mc->mc_dbx->md_rel;
6985 }
6986
6987 /** Final setup of a sorted-dups cursor.
6988  *      Sets up the fields that depend on the data from the main cursor.
6989  * @param[in] mc The main cursor whose sorted-dups cursor is to be initialized.
6990  * @param[in] node The data containing the #MDB_db record for the
6991  * sorted-dup database.
6992  */
6993 static void
6994 mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node)
6995 {
6996         MDB_xcursor *mx = mc->mc_xcursor;
6997
6998         if (node->mn_flags & F_SUBDATA) {
6999                 memcpy(&mx->mx_db, NODEDATA(node), sizeof(MDB_db));
7000                 mx->mx_cursor.mc_pg[0] = 0;
7001                 mx->mx_cursor.mc_snum = 0;
7002                 mx->mx_cursor.mc_top = 0;
7003                 mx->mx_cursor.mc_flags = C_SUB;
7004         } else {
7005                 MDB_page *fp = NODEDATA(node);
7006                 mx->mx_db.md_pad = mc->mc_pg[mc->mc_top]->mp_pad;
7007                 mx->mx_db.md_flags = 0;
7008                 mx->mx_db.md_depth = 1;
7009                 mx->mx_db.md_branch_pages = 0;
7010                 mx->mx_db.md_leaf_pages = 1;
7011                 mx->mx_db.md_overflow_pages = 0;
7012                 mx->mx_db.md_entries = NUMKEYS(fp);
7013                 COPY_PGNO(mx->mx_db.md_root, fp->mp_pgno);
7014                 mx->mx_cursor.mc_snum = 1;
7015                 mx->mx_cursor.mc_top = 0;
7016                 mx->mx_cursor.mc_flags = C_INITIALIZED|C_SUB;
7017                 mx->mx_cursor.mc_pg[0] = fp;
7018                 mx->mx_cursor.mc_ki[0] = 0;
7019                 if (mc->mc_db->md_flags & MDB_DUPFIXED) {
7020                         mx->mx_db.md_flags = MDB_DUPFIXED;
7021                         mx->mx_db.md_pad = fp->mp_pad;
7022                         if (mc->mc_db->md_flags & MDB_INTEGERDUP)
7023                                 mx->mx_db.md_flags |= MDB_INTEGERKEY;
7024                 }
7025         }
7026         DPRINTF(("Sub-db -%u root page %"Z"u", mx->mx_cursor.mc_dbi,
7027                 mx->mx_db.md_root));
7028         mx->mx_dbflag = DB_VALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */
7029 #if UINT_MAX < SIZE_MAX
7030         if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(size_t))
7031                 mx->mx_dbx.md_cmp = mdb_cmp_clong;
7032 #endif
7033 }
7034
7035 /** Initialize a cursor for a given transaction and database. */
7036 static void
7037 mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx)
7038 {
7039         mc->mc_next = NULL;
7040         mc->mc_backup = NULL;
7041         mc->mc_dbi = dbi;
7042         mc->mc_txn = txn;
7043         mc->mc_db = &txn->mt_dbs[dbi];
7044         mc->mc_dbx = &txn->mt_dbxs[dbi];
7045         mc->mc_dbflag = &txn->mt_dbflags[dbi];
7046         mc->mc_snum = 0;
7047         mc->mc_top = 0;
7048         mc->mc_pg[0] = 0;
7049         mc->mc_flags = 0;
7050         if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
7051                 mdb_tassert(txn, mx != NULL);
7052                 mc->mc_xcursor = mx;
7053                 mdb_xcursor_init0(mc);
7054         } else {
7055                 mc->mc_xcursor = NULL;
7056         }
7057         if (*mc->mc_dbflag & DB_STALE) {
7058                 mdb_page_search(mc, NULL, MDB_PS_ROOTONLY);
7059         }
7060 }
7061
7062 int
7063 mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
7064 {
7065         MDB_cursor      *mc;
7066         size_t size = sizeof(MDB_cursor);
7067
7068         if (!ret || !TXN_DBI_EXIST(txn, dbi))
7069                 return EINVAL;
7070
7071         if (txn->mt_flags & MDB_TXN_ERROR)
7072                 return MDB_BAD_TXN;
7073
7074         /* Allow read access to the freelist */
7075         if (!dbi && !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
7076                 return EINVAL;
7077
7078         if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT)
7079                 size += sizeof(MDB_xcursor);
7080
7081         if ((mc = malloc(size)) != NULL) {
7082                 mdb_cursor_init(mc, txn, dbi, (MDB_xcursor *)(mc + 1));
7083                 if (txn->mt_cursors) {
7084                         mc->mc_next = txn->mt_cursors[dbi];
7085                         txn->mt_cursors[dbi] = mc;
7086                         mc->mc_flags |= C_UNTRACK;
7087                 }
7088         } else {
7089                 return ENOMEM;
7090         }
7091
7092         *ret = mc;
7093
7094         return MDB_SUCCESS;
7095 }
7096
7097 int
7098 mdb_cursor_renew(MDB_txn *txn, MDB_cursor *mc)
7099 {
7100         if (!mc || !TXN_DBI_EXIST(txn, mc->mc_dbi))
7101                 return EINVAL;
7102
7103         if ((mc->mc_flags & C_UNTRACK) || txn->mt_cursors)
7104                 return EINVAL;
7105
7106         if (txn->mt_flags & MDB_TXN_ERROR)
7107                 return MDB_BAD_TXN;
7108
7109         mdb_cursor_init(mc, txn, mc->mc_dbi, mc->mc_xcursor);
7110         return MDB_SUCCESS;
7111 }
7112
7113 /* Return the count of duplicate data items for the current key */
7114 int
7115 mdb_cursor_count(MDB_cursor *mc, size_t *countp)
7116 {
7117         MDB_node        *leaf;
7118
7119         if (mc == NULL || countp == NULL)
7120                 return EINVAL;
7121
7122         if (mc->mc_xcursor == NULL)
7123                 return MDB_INCOMPATIBLE;
7124
7125         if (mc->mc_txn->mt_flags & MDB_TXN_ERROR)
7126                 return MDB_BAD_TXN;
7127
7128         if (!(mc->mc_flags & C_INITIALIZED))
7129                 return EINVAL;
7130
7131         if (!mc->mc_snum || (mc->mc_flags & C_EOF))
7132                 return MDB_NOTFOUND;
7133
7134         leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
7135         if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
7136                 *countp = 1;
7137         } else {
7138                 if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED))
7139                         return EINVAL;
7140
7141                 *countp = mc->mc_xcursor->mx_db.md_entries;
7142         }
7143         return MDB_SUCCESS;
7144 }
7145
7146 void
7147 mdb_cursor_close(MDB_cursor *mc)
7148 {
7149         if (mc && !mc->mc_backup) {
7150                 /* remove from txn, if tracked */
7151                 if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) {
7152                         MDB_cursor **prev = &mc->mc_txn->mt_cursors[mc->mc_dbi];
7153                         while (*prev && *prev != mc) prev = &(*prev)->mc_next;
7154                         if (*prev == mc)
7155                                 *prev = mc->mc_next;
7156                 }
7157                 free(mc);
7158         }
7159 }
7160
7161 MDB_txn *
7162 mdb_cursor_txn(MDB_cursor *mc)
7163 {
7164         if (!mc) return NULL;
7165         return mc->mc_txn;
7166 }
7167
7168 MDB_dbi
7169 mdb_cursor_dbi(MDB_cursor *mc)
7170 {
7171         return mc->mc_dbi;
7172 }
7173
7174 /** Replace the key for a branch node with a new key.
7175  * @param[in] mc Cursor pointing to the node to operate on.
7176  * @param[in] key The new key to use.
7177  * @return 0 on success, non-zero on failure.
7178  */
7179 static int
7180 mdb_update_key(MDB_cursor *mc, MDB_val *key)
7181 {
7182         MDB_page                *mp;
7183         MDB_node                *node;
7184         char                    *base;
7185         size_t                   len;
7186         int                              delta, ksize, oksize;
7187         indx_t                   ptr, i, numkeys, indx;
7188         DKBUF;
7189
7190         indx = mc->mc_ki[mc->mc_top];
7191         mp = mc->mc_pg[mc->mc_top];
7192         node = NODEPTR(mp, indx);
7193         ptr = mp->mp_ptrs[indx];
7194 #if MDB_DEBUG
7195         {
7196                 MDB_val k2;
7197                 char kbuf2[DKBUF_MAXKEYSIZE*2+1];
7198                 k2.mv_data = NODEKEY(node);
7199                 k2.mv_size = node->mn_ksize;
7200                 DPRINTF(("update key %u (ofs %u) [%s] to [%s] on page %"Z"u",
7201                         indx, ptr,
7202                         mdb_dkey(&k2, kbuf2),
7203                         DKEY(key),
7204                         mp->mp_pgno));
7205         }
7206 #endif
7207
7208         /* Sizes must be 2-byte aligned. */
7209         ksize = EVEN(key->mv_size);
7210         oksize = EVEN(node->mn_ksize);
7211         delta = ksize - oksize;
7212
7213         /* Shift node contents if EVEN(key length) changed. */
7214         if (delta) {
7215                 if (delta > 0 && SIZELEFT(mp) < delta) {
7216                         pgno_t pgno;
7217                         /* not enough space left, do a delete and split */
7218                         DPRINTF(("Not enough room, delta = %d, splitting...", delta));
7219                         pgno = NODEPGNO(node);
7220                         mdb_node_del(mc, 0);
7221                         return mdb_page_split(mc, key, NULL, pgno, MDB_SPLIT_REPLACE);
7222                 }
7223
7224                 numkeys = NUMKEYS(mp);
7225                 for (i = 0; i < numkeys; i++) {
7226                         if (mp->mp_ptrs[i] <= ptr)
7227                                 mp->mp_ptrs[i] -= delta;
7228                 }
7229
7230                 base = (char *)mp + mp->mp_upper + PAGEBASE;
7231                 len = ptr - mp->mp_upper + NODESIZE;
7232                 memmove(base - delta, base, len);
7233                 mp->mp_upper -= delta;
7234
7235                 node = NODEPTR(mp, indx);
7236         }
7237
7238         /* But even if no shift was needed, update ksize */
7239         if (node->mn_ksize != key->mv_size)
7240                 node->mn_ksize = key->mv_size;
7241
7242         if (key->mv_size)
7243                 memcpy(NODEKEY(node), key->mv_data, key->mv_size);
7244
7245         return MDB_SUCCESS;
7246 }
7247
7248 static void
7249 mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst);
7250
7251 /** Move a node from csrc to cdst.
7252  */
7253 static int
7254 mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst)
7255 {
7256         MDB_node                *srcnode;
7257         MDB_val          key, data;
7258         pgno_t  srcpg;
7259         MDB_cursor mn;
7260         int                      rc;
7261         unsigned short flags;
7262
7263         DKBUF;
7264
7265         /* Mark src and dst as dirty. */
7266         if ((rc = mdb_page_touch(csrc)) ||
7267             (rc = mdb_page_touch(cdst)))
7268                 return rc;
7269
7270         if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
7271                 key.mv_size = csrc->mc_db->md_pad;
7272                 key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top], key.mv_size);
7273                 data.mv_size = 0;
7274                 data.mv_data = NULL;
7275                 srcpg = 0;
7276                 flags = 0;
7277         } else {
7278                 srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top]);
7279                 mdb_cassert(csrc, !((size_t)srcnode & 1));
7280                 srcpg = NODEPGNO(srcnode);
7281                 flags = srcnode->mn_flags;
7282                 if (csrc->mc_ki[csrc->mc_top] == 0 && IS_BRANCH(csrc->mc_pg[csrc->mc_top])) {
7283                         unsigned int snum = csrc->mc_snum;
7284                         MDB_node *s2;
7285                         /* must find the lowest key below src */
7286                         rc = mdb_page_search_lowest(csrc);
7287                         if (rc)
7288                                 return rc;
7289                         if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
7290                                 key.mv_size = csrc->mc_db->md_pad;
7291                                 key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size);
7292                         } else {
7293                                 s2 = NODEPTR(csrc->mc_pg[csrc->mc_top], 0);
7294                                 key.mv_size = NODEKSZ(s2);
7295                                 key.mv_data = NODEKEY(s2);
7296                         }
7297                         csrc->mc_snum = snum--;
7298                         csrc->mc_top = snum;
7299                 } else {
7300                         key.mv_size = NODEKSZ(srcnode);
7301                         key.mv_data = NODEKEY(srcnode);
7302                 }
7303                 data.mv_size = NODEDSZ(srcnode);
7304                 data.mv_data = NODEDATA(srcnode);
7305         }
7306         if (IS_BRANCH(cdst->mc_pg[cdst->mc_top]) && cdst->mc_ki[cdst->mc_top] == 0) {
7307                 unsigned int snum = cdst->mc_snum;
7308                 MDB_node *s2;
7309                 MDB_val bkey;
7310                 /* must find the lowest key below dst */
7311                 mdb_cursor_copy(cdst, &mn);
7312                 rc = mdb_page_search_lowest(&mn);
7313                 if (rc)
7314                         return rc;
7315                 if (IS_LEAF2(mn.mc_pg[mn.mc_top])) {
7316                         bkey.mv_size = mn.mc_db->md_pad;
7317                         bkey.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, bkey.mv_size);
7318                 } else {
7319                         s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0);
7320                         bkey.mv_size = NODEKSZ(s2);
7321                         bkey.mv_data = NODEKEY(s2);
7322                 }
7323                 mn.mc_snum = snum--;
7324                 mn.mc_top = snum;
7325                 mn.mc_ki[snum] = 0;
7326                 rc = mdb_update_key(&mn, &bkey);
7327                 if (rc)
7328                         return rc;
7329         }
7330
7331         DPRINTF(("moving %s node %u [%s] on page %"Z"u to node %u on page %"Z"u",
7332             IS_LEAF(csrc->mc_pg[csrc->mc_top]) ? "leaf" : "branch",
7333             csrc->mc_ki[csrc->mc_top],
7334                 DKEY(&key),
7335             csrc->mc_pg[csrc->mc_top]->mp_pgno,
7336             cdst->mc_ki[cdst->mc_top], cdst->mc_pg[cdst->mc_top]->mp_pgno));
7337
7338         /* Add the node to the destination page.
7339          */
7340         rc = mdb_node_add(cdst, cdst->mc_ki[cdst->mc_top], &key, &data, srcpg, flags);
7341         if (rc != MDB_SUCCESS)
7342                 return rc;
7343
7344         /* Delete the node from the source page.
7345          */
7346         mdb_node_del(csrc, key.mv_size);
7347
7348         {
7349                 /* Adjust other cursors pointing to mp */
7350                 MDB_cursor *m2, *m3;
7351                 MDB_dbi dbi = csrc->mc_dbi;
7352                 MDB_page *mp = csrc->mc_pg[csrc->mc_top];
7353
7354                 for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
7355                         if (csrc->mc_flags & C_SUB)
7356                                 m3 = &m2->mc_xcursor->mx_cursor;
7357                         else
7358                                 m3 = m2;
7359                         if (m3 == csrc) continue;
7360                         if (m3->mc_pg[csrc->mc_top] == mp && m3->mc_ki[csrc->mc_top] ==
7361                                 csrc->mc_ki[csrc->mc_top]) {
7362                                 m3->mc_pg[csrc->mc_top] = cdst->mc_pg[cdst->mc_top];
7363                                 m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
7364                         }
7365                 }
7366         }
7367
7368         /* Update the parent separators.
7369          */
7370         if (csrc->mc_ki[csrc->mc_top] == 0) {
7371                 if (csrc->mc_ki[csrc->mc_top-1] != 0) {
7372                         if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
7373                                 key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size);
7374                         } else {
7375                                 srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], 0);
7376                                 key.mv_size = NODEKSZ(srcnode);
7377                                 key.mv_data = NODEKEY(srcnode);
7378                         }
7379                         DPRINTF(("update separator for source page %"Z"u to [%s]",
7380                                 csrc->mc_pg[csrc->mc_top]->mp_pgno, DKEY(&key)));
7381                         mdb_cursor_copy(csrc, &mn);
7382                         mn.mc_snum--;
7383                         mn.mc_top--;
7384                         if ((rc = mdb_update_key(&mn, &key)) != MDB_SUCCESS)
7385                                 return rc;
7386                 }
7387                 if (IS_BRANCH(csrc->mc_pg[csrc->mc_top])) {
7388                         MDB_val  nullkey;
7389                         indx_t  ix = csrc->mc_ki[csrc->mc_top];
7390                         nullkey.mv_size = 0;
7391                         csrc->mc_ki[csrc->mc_top] = 0;
7392                         rc = mdb_update_key(csrc, &nullkey);
7393                         csrc->mc_ki[csrc->mc_top] = ix;
7394                         mdb_cassert(csrc, rc == MDB_SUCCESS);
7395                 }
7396         }
7397
7398         if (cdst->mc_ki[cdst->mc_top] == 0) {
7399                 if (cdst->mc_ki[cdst->mc_top-1] != 0) {
7400                         if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
7401                                 key.mv_data = LEAF2KEY(cdst->mc_pg[cdst->mc_top], 0, key.mv_size);
7402                         } else {
7403                                 srcnode = NODEPTR(cdst->mc_pg[cdst->mc_top], 0);
7404                                 key.mv_size = NODEKSZ(srcnode);
7405                                 key.mv_data = NODEKEY(srcnode);
7406                         }
7407                         DPRINTF(("update separator for destination page %"Z"u to [%s]",
7408                                 cdst->mc_pg[cdst->mc_top]->mp_pgno, DKEY(&key)));
7409                         mdb_cursor_copy(cdst, &mn);
7410                         mn.mc_snum--;
7411                         mn.mc_top--;
7412                         if ((rc = mdb_update_key(&mn, &key)) != MDB_SUCCESS)
7413                                 return rc;
7414                 }
7415                 if (IS_BRANCH(cdst->mc_pg[cdst->mc_top])) {
7416                         MDB_val  nullkey;
7417                         indx_t  ix = cdst->mc_ki[cdst->mc_top];
7418                         nullkey.mv_size = 0;
7419                         cdst->mc_ki[cdst->mc_top] = 0;
7420                         rc = mdb_update_key(cdst, &nullkey);
7421                         cdst->mc_ki[cdst->mc_top] = ix;
7422                         mdb_cassert(csrc, rc == MDB_SUCCESS);
7423                 }
7424         }
7425
7426         return MDB_SUCCESS;
7427 }
7428
7429 /** Merge one page into another.
7430  *  The nodes from the page pointed to by \b csrc will
7431  *      be copied to the page pointed to by \b cdst and then
7432  *      the \b csrc page will be freed.
7433  * @param[in] csrc Cursor pointing to the source page.
7434  * @param[in] cdst Cursor pointing to the destination page.
7435  * @return 0 on success, non-zero on failure.
7436  */
7437 static int
7438 mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
7439 {
7440         MDB_page        *psrc, *pdst;
7441         MDB_node        *srcnode;
7442         MDB_val          key, data;
7443         unsigned         nkeys;
7444         int                      rc;
7445         indx_t           i, j;
7446
7447         psrc = csrc->mc_pg[csrc->mc_top];
7448         pdst = cdst->mc_pg[cdst->mc_top];
7449
7450         DPRINTF(("merging page %"Z"u into %"Z"u", psrc->mp_pgno, pdst->mp_pgno));
7451
7452         mdb_cassert(csrc, csrc->mc_snum > 1);   /* can't merge root page */
7453         mdb_cassert(csrc, cdst->mc_snum > 1);
7454
7455         /* Mark dst as dirty. */
7456         if ((rc = mdb_page_touch(cdst)))
7457                 return rc;
7458
7459         /* Move all nodes from src to dst.
7460          */
7461         j = nkeys = NUMKEYS(pdst);
7462         if (IS_LEAF2(psrc)) {
7463                 key.mv_size = csrc->mc_db->md_pad;
7464                 key.mv_data = METADATA(psrc);
7465                 for (i = 0; i < NUMKEYS(psrc); i++, j++) {
7466                         rc = mdb_node_add(cdst, j, &key, NULL, 0, 0);
7467                         if (rc != MDB_SUCCESS)
7468                                 return rc;
7469                         key.mv_data = (char *)key.mv_data + key.mv_size;
7470                 }
7471         } else {
7472                 for (i = 0; i < NUMKEYS(psrc); i++, j++) {
7473                         srcnode = NODEPTR(psrc, i);
7474                         if (i == 0 && IS_BRANCH(psrc)) {
7475                                 MDB_cursor mn;
7476                                 MDB_node *s2;
7477                                 mdb_cursor_copy(csrc, &mn);
7478                                 /* must find the lowest key below src */
7479                                 rc = mdb_page_search_lowest(&mn);
7480                                 if (rc)
7481                                         return rc;
7482                                 if (IS_LEAF2(mn.mc_pg[mn.mc_top])) {
7483                                         key.mv_size = mn.mc_db->md_pad;
7484                                         key.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, key.mv_size);
7485                                 } else {
7486                                         s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0);
7487                                         key.mv_size = NODEKSZ(s2);
7488                                         key.mv_data = NODEKEY(s2);
7489                                 }
7490                         } else {
7491                                 key.mv_size = srcnode->mn_ksize;
7492                                 key.mv_data = NODEKEY(srcnode);
7493                         }
7494
7495                         data.mv_size = NODEDSZ(srcnode);
7496                         data.mv_data = NODEDATA(srcnode);
7497                         rc = mdb_node_add(cdst, j, &key, &data, NODEPGNO(srcnode), srcnode->mn_flags);
7498                         if (rc != MDB_SUCCESS)
7499                                 return rc;
7500                 }
7501         }
7502
7503         DPRINTF(("dst page %"Z"u now has %u keys (%.1f%% filled)",
7504             pdst->mp_pgno, NUMKEYS(pdst),
7505                 (float)PAGEFILL(cdst->mc_txn->mt_env, pdst) / 10));
7506
7507         /* Unlink the src page from parent and add to free list.
7508          */
7509         csrc->mc_top--;
7510         mdb_node_del(csrc, 0);
7511         if (csrc->mc_ki[csrc->mc_top] == 0) {
7512                 key.mv_size = 0;
7513                 rc = mdb_update_key(csrc, &key);
7514                 if (rc) {
7515                         csrc->mc_top++;
7516                         return rc;
7517                 }
7518         }
7519         csrc->mc_top++;
7520
7521         psrc = csrc->mc_pg[csrc->mc_top];
7522         /* If not operating on FreeDB, allow this page to be reused
7523          * in this txn. Otherwise just add to free list.
7524          */
7525         rc = mdb_page_loose(csrc, psrc);
7526         if (rc)
7527                 return rc;
7528         if (IS_LEAF(psrc))
7529                 csrc->mc_db->md_leaf_pages--;
7530         else
7531                 csrc->mc_db->md_branch_pages--;
7532         {
7533                 /* Adjust other cursors pointing to mp */
7534                 MDB_cursor *m2, *m3;
7535                 MDB_dbi dbi = csrc->mc_dbi;
7536
7537                 for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
7538                         if (csrc->mc_flags & C_SUB)
7539                                 m3 = &m2->mc_xcursor->mx_cursor;
7540                         else
7541                                 m3 = m2;
7542                         if (m3 == csrc) continue;
7543                         if (m3->mc_snum < csrc->mc_snum) continue;
7544                         if (m3->mc_pg[csrc->mc_top] == psrc) {
7545                                 m3->mc_pg[csrc->mc_top] = pdst;
7546                                 m3->mc_ki[csrc->mc_top] += nkeys;
7547                         }
7548                 }
7549         }
7550         {
7551                 unsigned int snum = cdst->mc_snum;
7552                 uint16_t depth = cdst->mc_db->md_depth;
7553                 mdb_cursor_pop(cdst);
7554                 rc = mdb_rebalance(cdst);
7555                 /* Did the tree shrink? */
7556                 if (depth > cdst->mc_db->md_depth)
7557                         snum--;
7558                 cdst->mc_snum = snum;
7559                 cdst->mc_top = snum-1;
7560         }
7561         return rc;
7562 }
7563
7564 /** Copy the contents of a cursor.
7565  * @param[in] csrc The cursor to copy from.
7566  * @param[out] cdst The cursor to copy to.
7567  */
7568 static void
7569 mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst)
7570 {
7571         unsigned int i;
7572
7573         cdst->mc_txn = csrc->mc_txn;
7574         cdst->mc_dbi = csrc->mc_dbi;
7575         cdst->mc_db  = csrc->mc_db;
7576         cdst->mc_dbx = csrc->mc_dbx;
7577         cdst->mc_snum = csrc->mc_snum;
7578         cdst->mc_top = csrc->mc_top;
7579         cdst->mc_flags = csrc->mc_flags;
7580
7581         for (i=0; i<csrc->mc_snum; i++) {
7582                 cdst->mc_pg[i] = csrc->mc_pg[i];
7583                 cdst->mc_ki[i] = csrc->mc_ki[i];
7584         }
7585 }
7586
7587 /** Rebalance the tree after a delete operation.
7588  * @param[in] mc Cursor pointing to the page where rebalancing
7589  * should begin.
7590  * @return 0 on success, non-zero on failure.
7591  */
7592 static int
7593 mdb_rebalance(MDB_cursor *mc)
7594 {
7595         MDB_node        *node;
7596         int rc;
7597         unsigned int ptop, minkeys;
7598         MDB_cursor      mn;
7599         indx_t oldki;
7600
7601         minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top]));
7602         DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)",
7603             IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch",
7604             mdb_dbg_pgno(mc->mc_pg[mc->mc_top]), NUMKEYS(mc->mc_pg[mc->mc_top]),
7605                 (float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10));
7606
7607         if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= FILL_THRESHOLD &&
7608                 NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) {
7609                 DPRINTF(("no need to rebalance page %"Z"u, above fill threshold",
7610                     mdb_dbg_pgno(mc->mc_pg[mc->mc_top])));
7611                 return MDB_SUCCESS;
7612         }
7613
7614         if (mc->mc_snum < 2) {
7615                 MDB_page *mp = mc->mc_pg[0];
7616                 if (IS_SUBP(mp)) {
7617                         DPUTS("Can't rebalance a subpage, ignoring");
7618                         return MDB_SUCCESS;
7619                 }
7620                 if (NUMKEYS(mp) == 0) {
7621                         DPUTS("tree is completely empty");
7622                         mc->mc_db->md_root = P_INVALID;
7623                         mc->mc_db->md_depth = 0;
7624                         mc->mc_db->md_leaf_pages = 0;
7625                         rc = mdb_midl_append(&mc->mc_txn->mt_free_pgs, mp->mp_pgno);
7626                         if (rc)
7627                                 return rc;
7628                         /* Adjust cursors pointing to mp */
7629                         mc->mc_snum = 0;
7630                         mc->mc_top = 0;
7631                         mc->mc_flags &= ~C_INITIALIZED;
7632                         {
7633                                 MDB_cursor *m2, *m3;
7634                                 MDB_dbi dbi = mc->mc_dbi;
7635
7636                                 for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
7637                                         if (mc->mc_flags & C_SUB)
7638                                                 m3 = &m2->mc_xcursor->mx_cursor;
7639                                         else
7640                                                 m3 = m2;
7641                                         if (m3->mc_snum < mc->mc_snum) continue;
7642                                         if (m3->mc_pg[0] == mp) {
7643                                                 m3->mc_snum = 0;
7644                                                 m3->mc_top = 0;
7645                                                 m3->mc_flags &= ~C_INITIALIZED;
7646                                         }
7647                                 }
7648                         }
7649                 } else if (IS_BRANCH(mp) && NUMKEYS(mp) == 1) {
7650                         int i;
7651                         DPUTS("collapsing root page!");
7652                         rc = mdb_midl_append(&mc->mc_txn->mt_free_pgs, mp->mp_pgno);
7653                         if (rc)
7654                                 return rc;
7655                         mc->mc_db->md_root = NODEPGNO(NODEPTR(mp, 0));
7656                         rc = mdb_page_get(mc->mc_txn,mc->mc_db->md_root,&mc->mc_pg[0],NULL);
7657                         if (rc)
7658                                 return rc;
7659                         mc->mc_db->md_depth--;
7660                         mc->mc_db->md_branch_pages--;
7661                         mc->mc_ki[0] = mc->mc_ki[1];
7662                         for (i = 1; i<mc->mc_db->md_depth; i++) {
7663                                 mc->mc_pg[i] = mc->mc_pg[i+1];
7664                                 mc->mc_ki[i] = mc->mc_ki[i+1];
7665                         }
7666                         {
7667                                 /* Adjust other cursors pointing to mp */
7668                                 MDB_cursor *m2, *m3;
7669                                 MDB_dbi dbi = mc->mc_dbi;
7670
7671                                 for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
7672                                         if (mc->mc_flags & C_SUB)
7673                                                 m3 = &m2->mc_xcursor->mx_cursor;
7674                                         else
7675                                                 m3 = m2;
7676                                         if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
7677                                         if (m3->mc_pg[0] == mp) {
7678                                                 m3->mc_snum--;
7679                                                 m3->mc_top--;
7680                                                 for (i=0; i<m3->mc_snum; i++) {
7681                                                         m3->mc_pg[i] = m3->mc_pg[i+1];
7682                                                         m3->mc_ki[i] = m3->mc_ki[i+1];
7683                                                 }
7684                                         }
7685                                 }
7686                         }
7687                 } else
7688                         DPUTS("root page doesn't need rebalancing");
7689                 return MDB_SUCCESS;
7690         }
7691
7692         /* The parent (branch page) must have at least 2 pointers,
7693          * otherwise the tree is invalid.
7694          */
7695         ptop = mc->mc_top-1;
7696         mdb_cassert(mc, NUMKEYS(mc->mc_pg[ptop]) > 1);
7697
7698         /* Leaf page fill factor is below the threshold.
7699          * Try to move keys from left or right neighbor, or
7700          * merge with a neighbor page.
7701          */
7702
7703         /* Find neighbors.
7704          */
7705         mdb_cursor_copy(mc, &mn);
7706         mn.mc_xcursor = NULL;
7707
7708         oldki = mc->mc_ki[mc->mc_top];
7709         if (mc->mc_ki[ptop] == 0) {
7710                 /* We're the leftmost leaf in our parent.
7711                  */
7712                 DPUTS("reading right neighbor");
7713                 mn.mc_ki[ptop]++;
7714                 node = NODEPTR(mc->mc_pg[ptop], mn.mc_ki[ptop]);
7715                 rc = mdb_page_get(mc->mc_txn,NODEPGNO(node),&mn.mc_pg[mn.mc_top],NULL);
7716                 if (rc)
7717                         return rc;
7718                 mn.mc_ki[mn.mc_top] = 0;
7719                 mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]);
7720         } else {
7721                 /* There is at least one neighbor to the left.
7722                  */
7723                 DPUTS("reading left neighbor");
7724                 mn.mc_ki[ptop]--;
7725                 node = NODEPTR(mc->mc_pg[ptop], mn.mc_ki[ptop]);
7726                 rc = mdb_page_get(mc->mc_txn,NODEPGNO(node),&mn.mc_pg[mn.mc_top],NULL);
7727                 if (rc)
7728                         return rc;
7729                 mn.mc_ki[mn.mc_top] = NUMKEYS(mn.mc_pg[mn.mc_top]) - 1;
7730                 mc->mc_ki[mc->mc_top] = 0;
7731         }
7732
7733         DPRINTF(("found neighbor page %"Z"u (%u keys, %.1f%% full)",
7734             mn.mc_pg[mn.mc_top]->mp_pgno, NUMKEYS(mn.mc_pg[mn.mc_top]),
7735                 (float)PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) / 10));
7736
7737         /* If the neighbor page is above threshold and has enough keys,
7738          * move one key from it. Otherwise we should try to merge them.
7739          * (A branch page must never have less than 2 keys.)
7740          */
7741         minkeys = 1 + (IS_BRANCH(mn.mc_pg[mn.mc_top]));
7742         if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
7743                 rc = mdb_node_move(&mn, mc);
7744                 if (mc->mc_ki[ptop]) {
7745                         oldki++;
7746                 }
7747         } else {
7748                 if (mc->mc_ki[ptop] == 0) {
7749                         rc = mdb_page_merge(&mn, mc);
7750                 } else {
7751                         oldki += NUMKEYS(mn.mc_pg[mn.mc_top]);
7752                         mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
7753                         rc = mdb_page_merge(mc, &mn);
7754                         mdb_cursor_copy(&mn, mc);
7755                 }
7756                 mc->mc_flags &= ~C_EOF;
7757         }
7758         mc->mc_ki[mc->mc_top] = oldki;
7759         return rc;
7760 }
7761
7762 /** Complete a delete operation started by #mdb_cursor_del(). */
7763 static int
7764 mdb_cursor_del0(MDB_cursor *mc)
7765 {
7766         int rc;
7767         MDB_page *mp;
7768         indx_t ki;
7769         unsigned int nkeys;
7770
7771         ki = mc->mc_ki[mc->mc_top];
7772         mdb_node_del(mc, mc->mc_db->md_pad);
7773         mc->mc_db->md_entries--;
7774         rc = mdb_rebalance(mc);
7775
7776         if (rc == MDB_SUCCESS) {
7777                 MDB_cursor *m2, *m3;
7778                 MDB_dbi dbi = mc->mc_dbi;
7779
7780                 mp = mc->mc_pg[mc->mc_top];
7781                 nkeys = NUMKEYS(mp);
7782
7783                 /* if mc points past last node in page, find next sibling */
7784                 if (mc->mc_ki[mc->mc_top] >= nkeys) {
7785                         rc = mdb_cursor_sibling(mc, 1);
7786                         if (rc == MDB_NOTFOUND) {
7787                                 mc->mc_flags |= C_EOF;
7788                                 rc = MDB_SUCCESS;
7789                         }
7790                 }
7791
7792                 /* Adjust other cursors pointing to mp */
7793                 for (m2 = mc->mc_txn->mt_cursors[dbi]; !rc && m2; m2=m2->mc_next) {
7794                         m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2;
7795                         if (! (m2->mc_flags & m3->mc_flags & C_INITIALIZED))
7796                                 continue;
7797                         if (m3 == mc || m3->mc_snum < mc->mc_snum)
7798                                 continue;
7799                         if (m3->mc_pg[mc->mc_top] == mp) {
7800                                 if (m3->mc_ki[mc->mc_top] >= ki) {
7801                                         m3->mc_flags |= C_DEL;
7802                                         if (m3->mc_ki[mc->mc_top] > ki)
7803                                                 m3->mc_ki[mc->mc_top]--;
7804                                         else if (mc->mc_db->md_flags & MDB_DUPSORT)
7805                                                 m3->mc_xcursor->mx_cursor.mc_flags |= C_EOF;
7806                                 }
7807                                 if (m3->mc_ki[mc->mc_top] >= nkeys) {
7808                                         rc = mdb_cursor_sibling(m3, 1);
7809                                         if (rc == MDB_NOTFOUND) {
7810                                                 m3->mc_flags |= C_EOF;
7811                                                 rc = MDB_SUCCESS;
7812                                         }
7813                                 }
7814                         }
7815                 }
7816                 mc->mc_flags |= C_DEL;
7817         }
7818
7819         if (rc)
7820                 mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
7821         return rc;
7822 }
7823
7824 int
7825 mdb_del(MDB_txn *txn, MDB_dbi dbi,
7826     MDB_val *key, MDB_val *data)
7827 {
7828         if (!key || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
7829                 return EINVAL;
7830
7831         if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
7832                 return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
7833
7834         if (!F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) {
7835                 /* must ignore any data */
7836                 data = NULL;
7837         }
7838
7839         return mdb_del0(txn, dbi, key, data, 0);
7840 }
7841
7842 static int
7843 mdb_del0(MDB_txn *txn, MDB_dbi dbi,
7844         MDB_val *key, MDB_val *data, unsigned flags)
7845 {
7846         MDB_cursor mc;
7847         MDB_xcursor mx;
7848         MDB_cursor_op op;
7849         MDB_val rdata, *xdata;
7850         int              rc, exact = 0;
7851         DKBUF;
7852
7853         DPRINTF(("====> delete db %u key [%s]", dbi, DKEY(key)));
7854
7855         mdb_cursor_init(&mc, txn, dbi, &mx);
7856
7857         if (data) {
7858                 op = MDB_GET_BOTH;
7859                 rdata = *data;
7860                 xdata = &rdata;
7861         } else {
7862                 op = MDB_SET;
7863                 xdata = NULL;
7864                 flags |= MDB_NODUPDATA;
7865         }
7866         rc = mdb_cursor_set(&mc, key, xdata, op, &exact);
7867         if (rc == 0) {
7868                 /* let mdb_page_split know about this cursor if needed:
7869                  * delete will trigger a rebalance; if it needs to move
7870                  * a node from one page to another, it will have to
7871                  * update the parent's separator key(s). If the new sepkey
7872                  * is larger than the current one, the parent page may
7873                  * run out of space, triggering a split. We need this
7874                  * cursor to be consistent until the end of the rebalance.
7875                  */
7876                 mc.mc_flags |= C_UNTRACK;
7877                 mc.mc_next = txn->mt_cursors[dbi];
7878                 txn->mt_cursors[dbi] = &mc;
7879                 rc = mdb_cursor_del(&mc, flags);
7880                 txn->mt_cursors[dbi] = mc.mc_next;
7881         }
7882         return rc;
7883 }
7884
7885 /** Split a page and insert a new node.
7886  * @param[in,out] mc Cursor pointing to the page and desired insertion index.
7887  * The cursor will be updated to point to the actual page and index where
7888  * the node got inserted after the split.
7889  * @param[in] newkey The key for the newly inserted node.
7890  * @param[in] newdata The data for the newly inserted node.
7891  * @param[in] newpgno The page number, if the new node is a branch node.
7892  * @param[in] nflags The #NODE_ADD_FLAGS for the new node.
7893  * @return 0 on success, non-zero on failure.
7894  */
7895 static int
7896 mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno,
7897         unsigned int nflags)
7898 {
7899         unsigned int flags;
7900         int              rc = MDB_SUCCESS, new_root = 0, did_split = 0;
7901         indx_t           newindx;
7902         pgno_t           pgno = 0;
7903         int      i, j, split_indx, nkeys, pmax;
7904         MDB_env         *env = mc->mc_txn->mt_env;
7905         MDB_node        *node;
7906         MDB_val  sepkey, rkey, xdata, *rdata = &xdata;
7907         MDB_page        *copy = NULL;
7908         MDB_page        *mp, *rp, *pp;
7909         int ptop;
7910         MDB_cursor      mn;
7911         DKBUF;
7912
7913         mp = mc->mc_pg[mc->mc_top];
7914         newindx = mc->mc_ki[mc->mc_top];
7915         nkeys = NUMKEYS(mp);
7916
7917         DPRINTF(("-----> splitting %s page %"Z"u and adding [%s] at index %i/%i",
7918             IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno,
7919             DKEY(newkey), mc->mc_ki[mc->mc_top], nkeys));
7920
7921         /* Create a right sibling. */
7922         if ((rc = mdb_page_new(mc, mp->mp_flags, 1, &rp)))
7923                 return rc;
7924         DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno));
7925
7926         if (mc->mc_snum < 2) {
7927                 if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp)))
7928                         goto done;
7929                 /* shift current top to make room for new parent */
7930                 mc->mc_pg[1] = mc->mc_pg[0];
7931                 mc->mc_ki[1] = mc->mc_ki[0];
7932                 mc->mc_pg[0] = pp;
7933                 mc->mc_ki[0] = 0;
7934                 mc->mc_db->md_root = pp->mp_pgno;
7935                 DPRINTF(("root split! new root = %"Z"u", pp->mp_pgno));
7936                 mc->mc_db->md_depth++;
7937                 new_root = 1;
7938
7939                 /* Add left (implicit) pointer. */
7940                 if ((rc = mdb_node_add(mc, 0, NULL, NULL, mp->mp_pgno, 0)) != MDB_SUCCESS) {
7941                         /* undo the pre-push */
7942                         mc->mc_pg[0] = mc->mc_pg[1];
7943                         mc->mc_ki[0] = mc->mc_ki[1];
7944                         mc->mc_db->md_root = mp->mp_pgno;
7945                         mc->mc_db->md_depth--;
7946                         goto done;
7947                 }
7948                 mc->mc_snum = 2;
7949                 mc->mc_top = 1;
7950                 ptop = 0;
7951         } else {
7952                 ptop = mc->mc_top-1;
7953                 DPRINTF(("parent branch page is %"Z"u", mc->mc_pg[ptop]->mp_pgno));
7954         }
7955
7956         mc->mc_flags |= C_SPLITTING;
7957         mdb_cursor_copy(mc, &mn);
7958         mn.mc_pg[mn.mc_top] = rp;
7959         mn.mc_ki[ptop] = mc->mc_ki[ptop]+1;
7960
7961         if (nflags & MDB_APPEND) {
7962                 mn.mc_ki[mn.mc_top] = 0;
7963                 sepkey = *newkey;
7964                 split_indx = newindx;
7965                 nkeys = 0;
7966         } else {
7967
7968                 split_indx = (nkeys+1) / 2;
7969
7970                 if (IS_LEAF2(rp)) {
7971                         char *split, *ins;
7972                         int x;
7973                         unsigned int lsize, rsize, ksize;
7974                         /* Move half of the keys to the right sibling */
7975                         x = mc->mc_ki[mc->mc_top] - split_indx;
7976                         ksize = mc->mc_db->md_pad;
7977                         split = LEAF2KEY(mp, split_indx, ksize);
7978                         rsize = (nkeys - split_indx) * ksize;
7979                         lsize = (nkeys - split_indx) * sizeof(indx_t);
7980                         mp->mp_lower -= lsize;
7981                         rp->mp_lower += lsize;
7982                         mp->mp_upper += rsize - lsize;
7983                         rp->mp_upper -= rsize - lsize;
7984                         sepkey.mv_size = ksize;
7985                         if (newindx == split_indx) {
7986                                 sepkey.mv_data = newkey->mv_data;
7987                         } else {
7988                                 sepkey.mv_data = split;
7989                         }
7990                         if (x<0) {
7991                                 ins = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], ksize);
7992                                 memcpy(rp->mp_ptrs, split, rsize);
7993                                 sepkey.mv_data = rp->mp_ptrs;
7994                                 memmove(ins+ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize);
7995                                 memcpy(ins, newkey->mv_data, ksize);
7996                                 mp->mp_lower += sizeof(indx_t);
7997                                 mp->mp_upper -= ksize - sizeof(indx_t);
7998                         } else {
7999                                 if (x)
8000                                         memcpy(rp->mp_ptrs, split, x * ksize);
8001                                 ins = LEAF2KEY(rp, x, ksize);
8002                                 memcpy(ins, newkey->mv_data, ksize);
8003                                 memcpy(ins+ksize, split + x * ksize, rsize - x * ksize);
8004                                 rp->mp_lower += sizeof(indx_t);
8005                                 rp->mp_upper -= ksize - sizeof(indx_t);
8006                                 mc->mc_ki[mc->mc_top] = x;
8007                                 mc->mc_pg[mc->mc_top] = rp;
8008                         }
8009                 } else {
8010                         int psize, nsize, k;
8011                         /* Maximum free space in an empty page */
8012                         pmax = env->me_psize - PAGEHDRSZ;
8013                         if (IS_LEAF(mp))
8014                                 nsize = mdb_leaf_size(env, newkey, newdata);
8015                         else
8016                                 nsize = mdb_branch_size(env, newkey);
8017                         nsize = EVEN(nsize);
8018
8019                         /* grab a page to hold a temporary copy */
8020                         copy = mdb_page_malloc(mc->mc_txn, 1);
8021                         if (copy == NULL) {
8022                                 rc = ENOMEM;
8023                                 goto done;
8024                         }
8025                         copy->mp_pgno  = mp->mp_pgno;
8026                         copy->mp_flags = mp->mp_flags;
8027                         copy->mp_lower = (PAGEHDRSZ-PAGEBASE);
8028                         copy->mp_upper = env->me_psize - PAGEBASE;
8029
8030                         /* prepare to insert */
8031                         for (i=0, j=0; i<nkeys; i++) {
8032                                 if (i == newindx) {
8033                                         copy->mp_ptrs[j++] = 0;
8034                                 }
8035                                 copy->mp_ptrs[j++] = mp->mp_ptrs[i];
8036                         }
8037
8038                         /* When items are relatively large the split point needs
8039                          * to be checked, because being off-by-one will make the
8040                          * difference between success or failure in mdb_node_add.
8041                          *
8042                          * It's also relevant if a page happens to be laid out
8043                          * such that one half of its nodes are all "small" and
8044                          * the other half of its nodes are "large." If the new
8045                          * item is also "large" and falls on the half with
8046                          * "large" nodes, it also may not fit.
8047                          *
8048                          * As a final tweak, if the new item goes on the last
8049                          * spot on the page (and thus, onto the new page), bias
8050                          * the split so the new page is emptier than the old page.
8051                          * This yields better packing during sequential inserts.
8052                          */
8053                         if (nkeys < 20 || nsize > pmax/16 || newindx >= nkeys) {
8054                                 /* Find split point */
8055                                 psize = 0;
8056                                 if (newindx <= split_indx || newindx >= nkeys) {
8057                                         i = 0; j = 1;
8058                                         k = newindx >= nkeys ? nkeys : split_indx+2;
8059                                 } else {
8060                                         i = nkeys; j = -1;
8061                                         k = split_indx-1;
8062                                 }
8063                                 for (; i!=k; i+=j) {
8064                                         if (i == newindx) {
8065                                                 psize += nsize;
8066                                                 node = NULL;
8067                                         } else {
8068                                                 node = (MDB_node *)((char *)mp + copy->mp_ptrs[i] + PAGEBASE);
8069                                                 psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t);
8070                                                 if (IS_LEAF(mp)) {
8071                                                         if (F_ISSET(node->mn_flags, F_BIGDATA))
8072                                                                 psize += sizeof(pgno_t);
8073                                                         else
8074                                                                 psize += NODEDSZ(node);
8075                                                 }
8076                                                 psize = EVEN(psize);
8077                                         }
8078                                         if (psize > pmax || i == k-j) {
8079                                                 split_indx = i + (j<0);
8080                                                 break;
8081                                         }
8082                                 }
8083                         }
8084                         if (split_indx == newindx) {
8085                                 sepkey.mv_size = newkey->mv_size;
8086                                 sepkey.mv_data = newkey->mv_data;
8087                         } else {
8088                                 node = (MDB_node *)((char *)mp + copy->mp_ptrs[split_indx] + PAGEBASE);
8089                                 sepkey.mv_size = node->mn_ksize;
8090                                 sepkey.mv_data = NODEKEY(node);
8091                         }
8092                 }
8093         }
8094
8095         DPRINTF(("separator is %d [%s]", split_indx, DKEY(&sepkey)));
8096
8097         /* Copy separator key to the parent.
8098          */
8099         if (SIZELEFT(mn.mc_pg[ptop]) < mdb_branch_size(env, &sepkey)) {
8100                 mn.mc_snum--;
8101                 mn.mc_top--;
8102                 did_split = 1;
8103                 rc = mdb_page_split(&mn, &sepkey, NULL, rp->mp_pgno, 0);
8104                 if (rc)
8105                         goto done;
8106
8107                 /* root split? */
8108                 if (mn.mc_snum == mc->mc_snum) {
8109                         mc->mc_pg[mc->mc_snum] = mc->mc_pg[mc->mc_top];
8110                         mc->mc_ki[mc->mc_snum] = mc->mc_ki[mc->mc_top];
8111                         mc->mc_pg[mc->mc_top] = mc->mc_pg[ptop];
8112                         mc->mc_ki[mc->mc_top] = mc->mc_ki[ptop];
8113                         mc->mc_snum++;
8114                         mc->mc_top++;
8115                         ptop++;
8116                 }
8117                 /* Right page might now have changed parent.
8118                  * Check if left page also changed parent.
8119                  */
8120                 if (mn.mc_pg[ptop] != mc->mc_pg[ptop] &&
8121                     mc->mc_ki[ptop] >= NUMKEYS(mc->mc_pg[ptop])) {
8122                         for (i=0; i<ptop; i++) {
8123                                 mc->mc_pg[i] = mn.mc_pg[i];
8124                                 mc->mc_ki[i] = mn.mc_ki[i];
8125                         }
8126                         mc->mc_pg[ptop] = mn.mc_pg[ptop];
8127                         if (mn.mc_ki[ptop]) {
8128                                 mc->mc_ki[ptop] = mn.mc_ki[ptop] - 1;
8129                         } else {
8130                                 /* find right page's left sibling */
8131                                 mc->mc_ki[ptop] = mn.mc_ki[ptop];
8132                                 mdb_cursor_sibling(mc, 0);
8133                         }
8134                 }
8135         } else {
8136                 mn.mc_top--;
8137                 rc = mdb_node_add(&mn, mn.mc_ki[ptop], &sepkey, NULL, rp->mp_pgno, 0);
8138                 mn.mc_top++;
8139         }
8140         mc->mc_flags ^= C_SPLITTING;
8141         if (rc != MDB_SUCCESS) {
8142                 goto done;
8143         }
8144         if (nflags & MDB_APPEND) {
8145                 mc->mc_pg[mc->mc_top] = rp;
8146                 mc->mc_ki[mc->mc_top] = 0;
8147                 rc = mdb_node_add(mc, 0, newkey, newdata, newpgno, nflags);
8148                 if (rc)
8149                         goto done;
8150                 for (i=0; i<mc->mc_top; i++)
8151                         mc->mc_ki[i] = mn.mc_ki[i];
8152         } else if (!IS_LEAF2(mp)) {
8153                 /* Move nodes */
8154                 mc->mc_pg[mc->mc_top] = rp;
8155                 i = split_indx;
8156                 j = 0;
8157                 do {
8158                         if (i == newindx) {
8159                                 rkey.mv_data = newkey->mv_data;
8160                                 rkey.mv_size = newkey->mv_size;
8161                                 if (IS_LEAF(mp)) {
8162                                         rdata = newdata;
8163                                 } else
8164                                         pgno = newpgno;
8165                                 flags = nflags;
8166                                 /* Update index for the new key. */
8167                                 mc->mc_ki[mc->mc_top] = j;
8168                         } else {
8169                                 node = (MDB_node *)((char *)mp + copy->mp_ptrs[i] + PAGEBASE);
8170                                 rkey.mv_data = NODEKEY(node);
8171                                 rkey.mv_size = node->mn_ksize;
8172                                 if (IS_LEAF(mp)) {
8173                                         xdata.mv_data = NODEDATA(node);
8174                                         xdata.mv_size = NODEDSZ(node);
8175                                         rdata = &xdata;
8176                                 } else
8177                                         pgno = NODEPGNO(node);
8178                                 flags = node->mn_flags;
8179                         }
8180
8181                         if (!IS_LEAF(mp) && j == 0) {
8182                                 /* First branch index doesn't need key data. */
8183                                 rkey.mv_size = 0;
8184                         }
8185
8186                         rc = mdb_node_add(mc, j, &rkey, rdata, pgno, flags);
8187                         if (rc)
8188                                 goto done;
8189                         if (i == nkeys) {
8190                                 i = 0;
8191                                 j = 0;
8192                                 mc->mc_pg[mc->mc_top] = copy;
8193                         } else {
8194                                 i++;
8195                                 j++;
8196                         }
8197                 } while (i != split_indx);
8198
8199                 nkeys = NUMKEYS(copy);
8200                 for (i=0; i<nkeys; i++)
8201                         mp->mp_ptrs[i] = copy->mp_ptrs[i];
8202                 mp->mp_lower = copy->mp_lower;
8203                 mp->mp_upper = copy->mp_upper;
8204                 memcpy(NODEPTR(mp, nkeys-1), NODEPTR(copy, nkeys-1),
8205                         env->me_psize - copy->mp_upper - PAGEBASE);
8206
8207                 /* reset back to original page */
8208                 if (newindx < split_indx) {
8209                         mc->mc_pg[mc->mc_top] = mp;
8210                         if (nflags & MDB_RESERVE) {
8211                                 node = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
8212                                 if (!(node->mn_flags & F_BIGDATA))
8213                                         newdata->mv_data = NODEDATA(node);
8214                         }
8215                 } else {
8216                         mc->mc_pg[mc->mc_top] = rp;
8217                         mc->mc_ki[ptop]++;
8218                         /* Make sure mc_ki is still valid.
8219                          */
8220                         if (mn.mc_pg[ptop] != mc->mc_pg[ptop] &&
8221                                 mc->mc_ki[ptop] >= NUMKEYS(mc->mc_pg[ptop])) {
8222                                 for (i=0; i<=ptop; i++) {
8223                                         mc->mc_pg[i] = mn.mc_pg[i];
8224                                         mc->mc_ki[i] = mn.mc_ki[i];
8225                                 }
8226                         }
8227                 }
8228         }
8229
8230         {
8231                 /* Adjust other cursors pointing to mp */
8232                 MDB_cursor *m2, *m3;
8233                 MDB_dbi dbi = mc->mc_dbi;
8234                 int fixup = NUMKEYS(mp);
8235
8236                 for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
8237                         if (mc->mc_flags & C_SUB)
8238                                 m3 = &m2->mc_xcursor->mx_cursor;
8239                         else
8240                                 m3 = m2;
8241                         if (m3 == mc)
8242                                 continue;
8243                         if (!(m2->mc_flags & m3->mc_flags & C_INITIALIZED))
8244                                 continue;
8245                         if (m3->mc_flags & C_SPLITTING)
8246                                 continue;
8247                         if (new_root) {
8248                                 int k;
8249                                 /* root split */
8250                                 for (k=m3->mc_top; k>=0; k--) {
8251                                         m3->mc_ki[k+1] = m3->mc_ki[k];
8252                                         m3->mc_pg[k+1] = m3->mc_pg[k];
8253                                 }
8254                                 if (m3->mc_ki[0] >= split_indx) {
8255                                         m3->mc_ki[0] = 1;
8256                                 } else {
8257                                         m3->mc_ki[0] = 0;
8258                                 }
8259                                 m3->mc_pg[0] = mc->mc_pg[0];
8260                                 m3->mc_snum++;
8261                                 m3->mc_top++;
8262                         }
8263                         if (m3->mc_top >= mc->mc_top && m3->mc_pg[mc->mc_top] == mp) {
8264                                 if (m3->mc_ki[mc->mc_top] >= newindx && !(nflags & MDB_SPLIT_REPLACE))
8265                                         m3->mc_ki[mc->mc_top]++;
8266                                 if (m3->mc_ki[mc->mc_top] >= fixup) {
8267                                         m3->mc_pg[mc->mc_top] = rp;
8268                                         m3->mc_ki[mc->mc_top] -= fixup;
8269                                         m3->mc_ki[ptop] = mn.mc_ki[ptop];
8270                                 }
8271                         } else if (!did_split && m3->mc_top >= ptop && m3->mc_pg[ptop] == mc->mc_pg[ptop] &&
8272                                 m3->mc_ki[ptop] >= mc->mc_ki[ptop]) {
8273                                 m3->mc_ki[ptop]++;
8274                         }
8275                 }
8276         }
8277         DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp)));
8278
8279 done:
8280         if (copy)                                       /* tmp page */
8281                 mdb_page_free(env, copy);
8282         if (rc)
8283                 mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
8284         return rc;
8285 }
8286
8287 int
8288 mdb_put(MDB_txn *txn, MDB_dbi dbi,
8289     MDB_val *key, MDB_val *data, unsigned int flags)
8290 {
8291         MDB_cursor mc;
8292         MDB_xcursor mx;
8293
8294         if (!key || !data || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
8295                 return EINVAL;
8296
8297         if ((flags & (MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP)) != flags)
8298                 return EINVAL;
8299
8300         mdb_cursor_init(&mc, txn, dbi, &mx);
8301         return mdb_cursor_put(&mc, key, data, flags);
8302 }
8303
8304 #ifndef MDB_WBUF
8305 #define MDB_WBUF        (1024*1024)
8306 #endif
8307
8308         /** State needed for a compacting copy. */
8309 typedef struct mdb_copy {
8310         pthread_mutex_t mc_mutex;
8311         pthread_cond_t mc_cond;
8312         char *mc_wbuf[2];
8313         char *mc_over[2];
8314         MDB_env *mc_env;
8315         MDB_txn *mc_txn;
8316         int mc_wlen[2];
8317         int mc_olen[2];
8318         pgno_t mc_next_pgno;
8319         HANDLE mc_fd;
8320         int mc_status;
8321         volatile int mc_new;
8322         int mc_toggle;
8323
8324 } mdb_copy;
8325
8326         /** Dedicated writer thread for compacting copy. */
8327 static THREAD_RET ESECT
8328 mdb_env_copythr(void *arg)
8329 {
8330         mdb_copy *my = arg;
8331         char *ptr;
8332         int toggle = 0, wsize, rc;
8333 #ifdef _WIN32
8334         DWORD len;
8335 #define DO_WRITE(rc, fd, ptr, w2, len)  rc = WriteFile(fd, ptr, w2, &len, NULL)
8336 #else
8337         int len;
8338 #define DO_WRITE(rc, fd, ptr, w2, len)  len = write(fd, ptr, w2); rc = (len >= 0)
8339 #endif
8340
8341         pthread_mutex_lock(&my->mc_mutex);
8342         my->mc_new = 0;
8343         pthread_cond_signal(&my->mc_cond);
8344         for(;;) {
8345                 while (!my->mc_new)
8346                         pthread_cond_wait(&my->mc_cond, &my->mc_mutex);
8347                 if (my->mc_new < 0) {
8348                         my->mc_new = 0;
8349                         break;
8350                 }
8351                 my->mc_new = 0;
8352                 wsize = my->mc_wlen[toggle];
8353                 ptr = my->mc_wbuf[toggle];
8354 again:
8355                 while (wsize > 0) {
8356                         DO_WRITE(rc, my->mc_fd, ptr, wsize, len);
8357                         if (!rc) {
8358                                 rc = ErrCode();
8359                                 break;
8360                         } else if (len > 0) {
8361                                 rc = MDB_SUCCESS;
8362                                 ptr += len;
8363                                 wsize -= len;
8364                                 continue;
8365                         } else {
8366                                 rc = EIO;
8367                                 break;
8368                         }
8369                 }
8370                 if (rc) {
8371                         my->mc_status = rc;
8372                         break;
8373                 }
8374                 /* If there's an overflow page tail, write it too */
8375                 if (my->mc_olen[toggle]) {
8376                         wsize = my->mc_olen[toggle];
8377                         ptr = my->mc_over[toggle];
8378                         my->mc_olen[toggle] = 0;
8379                         goto again;
8380                 }
8381                 my->mc_wlen[toggle] = 0;
8382                 toggle ^= 1;
8383                 pthread_cond_signal(&my->mc_cond);
8384         }
8385         pthread_cond_signal(&my->mc_cond);
8386         pthread_mutex_unlock(&my->mc_mutex);
8387         return (THREAD_RET)0;
8388 #undef DO_WRITE
8389 }
8390
8391         /** Tell the writer thread there's a buffer ready to write */
8392 static int ESECT
8393 mdb_env_cthr_toggle(mdb_copy *my, int st)
8394 {
8395         int toggle = my->mc_toggle ^ 1;
8396         pthread_mutex_lock(&my->mc_mutex);
8397         if (my->mc_status) {
8398                 pthread_mutex_unlock(&my->mc_mutex);
8399                 return my->mc_status;
8400         }
8401         while (my->mc_new == 1)
8402                 pthread_cond_wait(&my->mc_cond, &my->mc_mutex);
8403         my->mc_new = st;
8404         my->mc_toggle = toggle;
8405         pthread_cond_signal(&my->mc_cond);
8406         pthread_mutex_unlock(&my->mc_mutex);
8407         return 0;
8408 }
8409
8410         /** Depth-first tree traversal for compacting copy. */
8411 static int ESECT
8412 mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags)
8413 {
8414         MDB_cursor mc;
8415         MDB_txn *txn = my->mc_txn;
8416         MDB_node *ni;
8417         MDB_page *mo, *mp, *leaf;
8418         char *buf, *ptr;
8419         int rc, toggle;
8420         unsigned int i;
8421
8422         /* Empty DB, nothing to do */
8423         if (*pg == P_INVALID)
8424                 return MDB_SUCCESS;
8425
8426         mc.mc_snum = 1;
8427         mc.mc_top = 0;
8428         mc.mc_txn = txn;
8429
8430         rc = mdb_page_get(my->mc_txn, *pg, &mc.mc_pg[0], NULL);
8431         if (rc)
8432                 return rc;
8433         rc = mdb_page_search_root(&mc, NULL, MDB_PS_FIRST);
8434         if (rc)
8435                 return rc;
8436
8437         /* Make cursor pages writable */
8438         buf = ptr = malloc(my->mc_env->me_psize * mc.mc_snum);
8439         if (buf == NULL)
8440                 return ENOMEM;
8441
8442         for (i=0; i<mc.mc_top; i++) {
8443                 mdb_page_copy((MDB_page *)ptr, mc.mc_pg[i], my->mc_env->me_psize);
8444                 mc.mc_pg[i] = (MDB_page *)ptr;
8445                 ptr += my->mc_env->me_psize;
8446         }
8447
8448         /* This is writable space for a leaf page. Usually not needed. */
8449         leaf = (MDB_page *)ptr;
8450
8451         toggle = my->mc_toggle;
8452         while (mc.mc_snum > 0) {
8453                 unsigned n;
8454                 mp = mc.mc_pg[mc.mc_top];
8455                 n = NUMKEYS(mp);
8456
8457                 if (IS_LEAF(mp)) {
8458                         if (!IS_LEAF2(mp) && !(flags & F_DUPDATA)) {
8459                                 for (i=0; i<n; i++) {
8460                                         ni = NODEPTR(mp, i);
8461                                         if (ni->mn_flags & F_BIGDATA) {
8462                                                 MDB_page *omp;
8463                                                 pgno_t pg;
8464
8465                                                 /* Need writable leaf */
8466                                                 if (mp != leaf) {
8467                                                         mc.mc_pg[mc.mc_top] = leaf;
8468                                                         mdb_page_copy(leaf, mp, my->mc_env->me_psize);
8469                                                         mp = leaf;
8470                                                         ni = NODEPTR(mp, i);
8471                                                 }
8472
8473                                                 memcpy(&pg, NODEDATA(ni), sizeof(pg));
8474                                                 rc = mdb_page_get(txn, pg, &omp, NULL);
8475                                                 if (rc)
8476                                                         goto done;
8477                                                 if (my->mc_wlen[toggle] >= MDB_WBUF) {
8478                                                         rc = mdb_env_cthr_toggle(my, 1);
8479                                                         if (rc)
8480                                                                 goto done;
8481                                                         toggle = my->mc_toggle;
8482                                                 }
8483                                                 mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
8484                                                 memcpy(mo, omp, my->mc_env->me_psize);
8485                                                 mo->mp_pgno = my->mc_next_pgno;
8486                                                 my->mc_next_pgno += omp->mp_pages;
8487                                                 my->mc_wlen[toggle] += my->mc_env->me_psize;
8488                                                 if (omp->mp_pages > 1) {
8489                                                         my->mc_olen[toggle] = my->mc_env->me_psize * (omp->mp_pages - 1);
8490                                                         my->mc_over[toggle] = (char *)omp + my->mc_env->me_psize;
8491                                                         rc = mdb_env_cthr_toggle(my, 1);
8492                                                         if (rc)
8493                                                                 goto done;
8494                                                         toggle = my->mc_toggle;
8495                                                 }
8496                                                 memcpy(NODEDATA(ni), &mo->mp_pgno, sizeof(pgno_t));
8497                                         } else if (ni->mn_flags & F_SUBDATA) {
8498                                                 MDB_db db;
8499
8500                                                 /* Need writable leaf */
8501                                                 if (mp != leaf) {
8502                                                         mc.mc_pg[mc.mc_top] = leaf;
8503                                                         mdb_page_copy(leaf, mp, my->mc_env->me_psize);
8504                                                         mp = leaf;
8505                                                         ni = NODEPTR(mp, i);
8506                                                 }
8507
8508                                                 memcpy(&db, NODEDATA(ni), sizeof(db));
8509                                                 my->mc_toggle = toggle;
8510                                                 rc = mdb_env_cwalk(my, &db.md_root, ni->mn_flags & F_DUPDATA);
8511                                                 if (rc)
8512                                                         goto done;
8513                                                 toggle = my->mc_toggle;
8514                                                 memcpy(NODEDATA(ni), &db, sizeof(db));
8515                                         }
8516                                 }
8517                         }
8518                 } else {
8519                         mc.mc_ki[mc.mc_top]++;
8520                         if (mc.mc_ki[mc.mc_top] < n) {
8521                                 pgno_t pg;
8522 again:
8523                                 ni = NODEPTR(mp, mc.mc_ki[mc.mc_top]);
8524                                 pg = NODEPGNO(ni);
8525                                 rc = mdb_page_get(txn, pg, &mp, NULL);
8526                                 if (rc)
8527                                         goto done;
8528                                 mc.mc_top++;
8529                                 mc.mc_snum++;
8530                                 mc.mc_ki[mc.mc_top] = 0;
8531                                 if (IS_BRANCH(mp)) {
8532                                         /* Whenever we advance to a sibling branch page,
8533                                          * we must proceed all the way down to its first leaf.
8534                                          */
8535                                         mdb_page_copy(mc.mc_pg[mc.mc_top], mp, my->mc_env->me_psize);
8536                                         goto again;
8537                                 } else
8538                                         mc.mc_pg[mc.mc_top] = mp;
8539                                 continue;
8540                         }
8541                 }
8542                 if (my->mc_wlen[toggle] >= MDB_WBUF) {
8543                         rc = mdb_env_cthr_toggle(my, 1);
8544                         if (rc)
8545                                 goto done;
8546                         toggle = my->mc_toggle;
8547                 }
8548                 mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
8549                 mdb_page_copy(mo, mp, my->mc_env->me_psize);
8550                 mo->mp_pgno = my->mc_next_pgno++;
8551                 my->mc_wlen[toggle] += my->mc_env->me_psize;
8552                 if (mc.mc_top) {
8553                         /* Update parent if there is one */
8554                         ni = NODEPTR(mc.mc_pg[mc.mc_top-1], mc.mc_ki[mc.mc_top-1]);
8555                         SETPGNO(ni, mo->mp_pgno);
8556                         mdb_cursor_pop(&mc);
8557                 } else {
8558                         /* Otherwise we're done */
8559                         *pg = mo->mp_pgno;
8560                         break;
8561                 }
8562         }
8563 done:
8564         free(buf);
8565         return rc;
8566 }
8567
8568         /** Copy environment with compaction. */
8569 static int ESECT
8570 mdb_env_copyfd1(MDB_env *env, HANDLE fd)
8571 {
8572         MDB_meta *mm;
8573         MDB_page *mp;
8574         mdb_copy my;
8575         MDB_txn *txn = NULL;
8576         pthread_t thr;
8577         int rc;
8578
8579 #ifdef _WIN32
8580         my.mc_mutex = CreateMutex(NULL, FALSE, NULL);
8581         my.mc_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
8582         my.mc_wbuf[0] = _aligned_malloc(MDB_WBUF*2, env->me_os_psize);
8583         if (my.mc_wbuf[0] == NULL)
8584                 return errno;
8585 #else
8586         pthread_mutex_init(&my.mc_mutex, NULL);
8587         pthread_cond_init(&my.mc_cond, NULL);
8588 #ifdef HAVE_MEMALIGN
8589         my.mc_wbuf[0] = memalign(env->me_os_psize, MDB_WBUF*2);
8590         if (my.mc_wbuf[0] == NULL)
8591                 return errno;
8592 #else
8593         rc = posix_memalign((void **)&my.mc_wbuf[0], env->me_os_psize, MDB_WBUF*2);
8594         if (rc)
8595                 return rc;
8596 #endif
8597 #endif
8598         memset(my.mc_wbuf[0], 0, MDB_WBUF*2);
8599         my.mc_wbuf[1] = my.mc_wbuf[0] + MDB_WBUF;
8600         my.mc_wlen[0] = 0;
8601         my.mc_wlen[1] = 0;
8602         my.mc_olen[0] = 0;
8603         my.mc_olen[1] = 0;
8604         my.mc_next_pgno = 2;
8605         my.mc_status = 0;
8606         my.mc_new = 1;
8607         my.mc_toggle = 0;
8608         my.mc_env = env;
8609         my.mc_fd = fd;
8610         THREAD_CREATE(thr, mdb_env_copythr, &my);
8611
8612         rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
8613         if (rc)
8614                 return rc;
8615
8616         mp = (MDB_page *)my.mc_wbuf[0];
8617         memset(mp, 0, 2*env->me_psize);
8618         mp->mp_pgno = 0;
8619         mp->mp_flags = P_META;
8620         mm = (MDB_meta *)METADATA(mp);
8621         mdb_env_init_meta0(env, mm);
8622         mm->mm_address = env->me_metas[0]->mm_address;
8623
8624         mp = (MDB_page *)(my.mc_wbuf[0] + env->me_psize);
8625         mp->mp_pgno = 1;
8626         mp->mp_flags = P_META;
8627         *(MDB_meta *)METADATA(mp) = *mm;
8628         mm = (MDB_meta *)METADATA(mp);
8629
8630         /* Count the number of free pages, subtract from lastpg to find
8631          * number of active pages
8632          */
8633         {
8634                 MDB_ID freecount = 0;
8635                 MDB_cursor mc;
8636                 MDB_val key, data;
8637                 mdb_cursor_init(&mc, txn, FREE_DBI, NULL);
8638                 while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0)
8639                         freecount += *(MDB_ID *)data.mv_data;
8640                 freecount += txn->mt_dbs[0].md_branch_pages +
8641                         txn->mt_dbs[0].md_leaf_pages +
8642                         txn->mt_dbs[0].md_overflow_pages;
8643
8644                 /* Set metapage 1 */
8645                 mm->mm_last_pg = txn->mt_next_pgno - freecount - 1;
8646                 mm->mm_dbs[1] = txn->mt_dbs[1];
8647                 if (mm->mm_last_pg > 1) {
8648                         mm->mm_dbs[1].md_root = mm->mm_last_pg;
8649                         mm->mm_txnid = 1;
8650                 } else {
8651                         mm->mm_dbs[1].md_root = P_INVALID;
8652                 }
8653         }
8654         my.mc_wlen[0] = env->me_psize * 2;
8655         my.mc_txn = txn;
8656         pthread_mutex_lock(&my.mc_mutex);
8657         while(my.mc_new)
8658                 pthread_cond_wait(&my.mc_cond, &my.mc_mutex);
8659         pthread_mutex_unlock(&my.mc_mutex);
8660         rc = mdb_env_cwalk(&my, &txn->mt_dbs[1].md_root, 0);
8661         if (rc == MDB_SUCCESS && my.mc_wlen[my.mc_toggle])
8662                 rc = mdb_env_cthr_toggle(&my, 1);
8663         mdb_env_cthr_toggle(&my, -1);
8664         pthread_mutex_lock(&my.mc_mutex);
8665         while(my.mc_new)
8666                 pthread_cond_wait(&my.mc_cond, &my.mc_mutex);
8667         pthread_mutex_unlock(&my.mc_mutex);
8668         THREAD_FINISH(thr);
8669
8670         mdb_txn_abort(txn);
8671 #ifdef _WIN32
8672         CloseHandle(my.mc_cond);
8673         CloseHandle(my.mc_mutex);
8674         _aligned_free(my.mc_wbuf[0]);
8675 #else
8676         pthread_cond_destroy(&my.mc_cond);
8677         pthread_mutex_destroy(&my.mc_mutex);
8678         free(my.mc_wbuf[0]);
8679 #endif
8680         return rc;
8681 }
8682
8683         /** Copy environment as-is. */
8684 static int ESECT
8685 mdb_env_copyfd0(MDB_env *env, HANDLE fd)
8686 {
8687         MDB_txn *txn = NULL;
8688         int rc;
8689         size_t wsize;
8690         char *ptr;
8691 #ifdef _WIN32
8692         DWORD len, w2;
8693 #define DO_WRITE(rc, fd, ptr, w2, len)  rc = WriteFile(fd, ptr, w2, &len, NULL)
8694 #else
8695         ssize_t len;
8696         size_t w2;
8697 #define DO_WRITE(rc, fd, ptr, w2, len)  len = write(fd, ptr, w2); rc = (len >= 0)
8698 #endif
8699
8700         /* Do the lock/unlock of the reader mutex before starting the
8701          * write txn.  Otherwise other read txns could block writers.
8702          */
8703         rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
8704         if (rc)
8705                 return rc;
8706
8707         if (env->me_txns) {
8708                 /* We must start the actual read txn after blocking writers */
8709                 mdb_txn_reset0(txn, "reset-stage1");
8710
8711                 /* Temporarily block writers until we snapshot the meta pages */
8712                 LOCK_MUTEX_W(env);
8713
8714                 rc = mdb_txn_renew0(txn);
8715                 if (rc) {
8716                         UNLOCK_MUTEX_W(env);
8717                         goto leave;
8718                 }
8719         }
8720
8721         wsize = env->me_psize * 2;
8722         ptr = env->me_map;
8723         w2 = wsize;
8724         while (w2 > 0) {
8725                 DO_WRITE(rc, fd, ptr, w2, len);
8726                 if (!rc) {
8727                         rc = ErrCode();
8728                         break;
8729                 } else if (len > 0) {
8730                         rc = MDB_SUCCESS;
8731                         ptr += len;
8732                         w2 -= len;
8733                         continue;
8734                 } else {
8735                         /* Non-blocking or async handles are not supported */
8736                         rc = EIO;
8737                         break;
8738                 }
8739         }
8740         if (env->me_txns)
8741                 UNLOCK_MUTEX_W(env);
8742
8743         if (rc)
8744                 goto leave;
8745
8746         w2 = txn->mt_next_pgno * env->me_psize;
8747         {
8748                 size_t fsize = 0;
8749                 if ((rc = mdb_fsize(env->me_fd, &fsize)))
8750                         goto leave;
8751                 if (w2 > fsize)
8752                         w2 = fsize;
8753         }
8754         wsize = w2 - wsize;
8755         while (wsize > 0) {
8756                 if (wsize > MAX_WRITE)
8757                         w2 = MAX_WRITE;
8758                 else
8759                         w2 = wsize;
8760                 DO_WRITE(rc, fd, ptr, w2, len);
8761                 if (!rc) {
8762                         rc = ErrCode();
8763                         break;
8764                 } else if (len > 0) {
8765                         rc = MDB_SUCCESS;
8766                         ptr += len;
8767                         wsize -= len;
8768                         continue;
8769                 } else {
8770                         rc = EIO;
8771                         break;
8772                 }
8773         }
8774
8775 leave:
8776         mdb_txn_abort(txn);
8777         return rc;
8778 }
8779
8780 int ESECT
8781 mdb_env_copyfd2(MDB_env *env, HANDLE fd, unsigned int flags)
8782 {
8783         if (flags & MDB_CP_COMPACT)
8784                 return mdb_env_copyfd1(env, fd);
8785         else
8786                 return mdb_env_copyfd0(env, fd);
8787 }
8788
8789 int ESECT
8790 mdb_env_copyfd(MDB_env *env, HANDLE fd)
8791 {
8792         return mdb_env_copyfd2(env, fd, 0);
8793 }
8794
8795 int ESECT
8796 mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
8797 {
8798         int rc, len;
8799         char *lpath;
8800         HANDLE newfd = INVALID_HANDLE_VALUE;
8801
8802         if (env->me_flags & MDB_NOSUBDIR) {
8803                 lpath = (char *)path;
8804         } else {
8805                 len = strlen(path);
8806                 len += sizeof(DATANAME);
8807                 lpath = malloc(len);
8808                 if (!lpath)
8809                         return ENOMEM;
8810                 sprintf(lpath, "%s" DATANAME, path);
8811         }
8812
8813         /* The destination path must exist, but the destination file must not.
8814          * We don't want the OS to cache the writes, since the source data is
8815          * already in the OS cache.
8816          */
8817 #ifdef _WIN32
8818         newfd = CreateFile(lpath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
8819                                 FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL);
8820 #else
8821         newfd = open(lpath, O_WRONLY|O_CREAT|O_EXCL, 0666);
8822 #endif
8823         if (newfd == INVALID_HANDLE_VALUE) {
8824                 rc = ErrCode();
8825                 goto leave;
8826         }
8827
8828         if (env->me_psize >= env->me_os_psize) {
8829 #ifdef O_DIRECT
8830         /* Set O_DIRECT if the file system supports it */
8831         if ((rc = fcntl(newfd, F_GETFL)) != -1)
8832                 (void) fcntl(newfd, F_SETFL, rc | O_DIRECT);
8833 #endif
8834 #ifdef F_NOCACHE        /* __APPLE__ */
8835         rc = fcntl(newfd, F_NOCACHE, 1);
8836         if (rc) {
8837                 rc = ErrCode();
8838                 goto leave;
8839         }
8840 #endif
8841         }
8842
8843         rc = mdb_env_copyfd2(env, newfd, flags);
8844
8845 leave:
8846         if (!(env->me_flags & MDB_NOSUBDIR))
8847                 free(lpath);
8848         if (newfd != INVALID_HANDLE_VALUE)
8849                 if (close(newfd) < 0 && rc == MDB_SUCCESS)
8850                         rc = ErrCode();
8851
8852         return rc;
8853 }
8854
8855 int ESECT
8856 mdb_env_copy(MDB_env *env, const char *path)
8857 {
8858         return mdb_env_copy2(env, path, 0);
8859 }
8860
8861 int ESECT
8862 mdb_env_set_flags(MDB_env *env, unsigned int flag, int onoff)
8863 {
8864         if ((flag & CHANGEABLE) != flag)
8865                 return EINVAL;
8866         if (onoff)
8867                 env->me_flags |= flag;
8868         else
8869                 env->me_flags &= ~flag;
8870         return MDB_SUCCESS;
8871 }
8872
8873 int ESECT
8874 mdb_env_get_flags(MDB_env *env, unsigned int *arg)
8875 {
8876         if (!env || !arg)
8877                 return EINVAL;
8878
8879         *arg = env->me_flags;
8880         return MDB_SUCCESS;
8881 }
8882
8883 int ESECT
8884 mdb_env_set_userctx(MDB_env *env, void *ctx)
8885 {
8886         if (!env)
8887                 return EINVAL;
8888         env->me_userctx = ctx;
8889         return MDB_SUCCESS;
8890 }
8891
8892 void * ESECT
8893 mdb_env_get_userctx(MDB_env *env)
8894 {
8895         return env ? env->me_userctx : NULL;
8896 }
8897
8898 int ESECT
8899 mdb_env_set_assert(MDB_env *env, MDB_assert_func *func)
8900 {
8901         if (!env)
8902                 return EINVAL;
8903 #ifndef NDEBUG
8904         env->me_assert_func = func;
8905 #endif
8906         return MDB_SUCCESS;
8907 }
8908
8909 int ESECT
8910 mdb_env_get_path(MDB_env *env, const char **arg)
8911 {
8912         if (!env || !arg)
8913                 return EINVAL;
8914
8915         *arg = env->me_path;
8916         return MDB_SUCCESS;
8917 }
8918
8919 int ESECT
8920 mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *arg)
8921 {
8922         if (!env || !arg)
8923                 return EINVAL;
8924
8925         *arg = env->me_fd;
8926         return MDB_SUCCESS;
8927 }
8928
8929 /** Common code for #mdb_stat() and #mdb_env_stat().
8930  * @param[in] env the environment to operate in.
8931  * @param[in] db the #MDB_db record containing the stats to return.
8932  * @param[out] arg the address of an #MDB_stat structure to receive the stats.
8933  * @return 0, this function always succeeds.
8934  */
8935 static int ESECT
8936 mdb_stat0(MDB_env *env, MDB_db *db, MDB_stat *arg)
8937 {
8938         arg->ms_psize = env->me_psize;
8939         arg->ms_depth = db->md_depth;
8940         arg->ms_branch_pages = db->md_branch_pages;
8941         arg->ms_leaf_pages = db->md_leaf_pages;
8942         arg->ms_overflow_pages = db->md_overflow_pages;
8943         arg->ms_entries = db->md_entries;
8944
8945         return MDB_SUCCESS;
8946 }
8947
8948 int ESECT
8949 mdb_env_stat(MDB_env *env, MDB_stat *arg)
8950 {
8951         int toggle;
8952
8953         if (env == NULL || arg == NULL)
8954                 return EINVAL;
8955
8956         toggle = mdb_env_pick_meta(env);
8957
8958         return mdb_stat0(env, &env->me_metas[toggle]->mm_dbs[MAIN_DBI], arg);
8959 }
8960
8961 int ESECT
8962 mdb_env_info(MDB_env *env, MDB_envinfo *arg)
8963 {
8964         int toggle;
8965
8966         if (env == NULL || arg == NULL)
8967                 return EINVAL;
8968
8969         toggle = mdb_env_pick_meta(env);
8970         arg->me_mapaddr = env->me_metas[toggle]->mm_address;
8971         arg->me_mapsize = env->me_mapsize;
8972         arg->me_maxreaders = env->me_maxreaders;
8973
8974         /* me_numreaders may be zero if this process never used any readers. Use
8975          * the shared numreader count if it exists.
8976          */
8977         arg->me_numreaders = env->me_txns ? env->me_txns->mti_numreaders : env->me_numreaders;
8978
8979         arg->me_last_pgno = env->me_metas[toggle]->mm_last_pg;
8980         arg->me_last_txnid = env->me_metas[toggle]->mm_txnid;
8981         return MDB_SUCCESS;
8982 }
8983
8984 /** Set the default comparison functions for a database.
8985  * Called immediately after a database is opened to set the defaults.
8986  * The user can then override them with #mdb_set_compare() or
8987  * #mdb_set_dupsort().
8988  * @param[in] txn A transaction handle returned by #mdb_txn_begin()
8989  * @param[in] dbi A database handle returned by #mdb_dbi_open()
8990  */
8991 static void
8992 mdb_default_cmp(MDB_txn *txn, MDB_dbi dbi)
8993 {
8994         uint16_t f = txn->mt_dbs[dbi].md_flags;
8995
8996         txn->mt_dbxs[dbi].md_cmp =
8997                 (f & MDB_REVERSEKEY) ? mdb_cmp_memnr :
8998                 (f & MDB_INTEGERKEY) ? mdb_cmp_cint  : mdb_cmp_memn;
8999
9000         txn->mt_dbxs[dbi].md_dcmp =
9001                 !(f & MDB_DUPSORT) ? 0 :
9002                 ((f & MDB_INTEGERDUP)
9003                  ? ((f & MDB_DUPFIXED)   ? mdb_cmp_int   : mdb_cmp_cint)
9004                  : ((f & MDB_REVERSEDUP) ? mdb_cmp_memnr : mdb_cmp_memn));
9005 }
9006
9007 int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
9008 {
9009         MDB_val key, data;
9010         MDB_dbi i;
9011         MDB_cursor mc;
9012         MDB_db dummy;
9013         int rc, dbflag, exact;
9014         unsigned int unused = 0, seq;
9015         size_t len;
9016
9017         if (txn->mt_dbxs[FREE_DBI].md_cmp == NULL) {
9018                 mdb_default_cmp(txn, FREE_DBI);
9019         }
9020
9021         if ((flags & VALID_FLAGS) != flags)
9022                 return EINVAL;
9023         if (txn->mt_flags & MDB_TXN_ERROR)
9024                 return MDB_BAD_TXN;
9025
9026         /* main DB? */
9027         if (!name) {
9028                 *dbi = MAIN_DBI;
9029                 if (flags & PERSISTENT_FLAGS) {
9030                         uint16_t f2 = flags & PERSISTENT_FLAGS;
9031                         /* make sure flag changes get committed */
9032                         if ((txn->mt_dbs[MAIN_DBI].md_flags | f2) != txn->mt_dbs[MAIN_DBI].md_flags) {
9033                                 txn->mt_dbs[MAIN_DBI].md_flags |= f2;
9034                                 txn->mt_flags |= MDB_TXN_DIRTY;
9035                         }
9036                 }
9037                 mdb_default_cmp(txn, MAIN_DBI);
9038                 return MDB_SUCCESS;
9039         }
9040
9041         if (txn->mt_dbxs[MAIN_DBI].md_cmp == NULL) {
9042                 mdb_default_cmp(txn, MAIN_DBI);
9043         }
9044
9045         /* Is the DB already open? */
9046         len = strlen(name);
9047         for (i=2; i<txn->mt_numdbs; i++) {
9048                 if (!txn->mt_dbxs[i].md_name.mv_size) {
9049                         /* Remember this free slot */
9050                         if (!unused) unused = i;
9051                         continue;
9052                 }
9053                 if (len == txn->mt_dbxs[i].md_name.mv_size &&
9054                         !strncmp(name, txn->mt_dbxs[i].md_name.mv_data, len)) {
9055                         *dbi = i;
9056                         return MDB_SUCCESS;
9057                 }
9058         }
9059
9060         /* If no free slot and max hit, fail */
9061         if (!unused && txn->mt_numdbs >= txn->mt_env->me_maxdbs)
9062                 return MDB_DBS_FULL;
9063
9064         /* Cannot mix named databases with some mainDB flags */
9065         if (txn->mt_dbs[MAIN_DBI].md_flags & (MDB_DUPSORT|MDB_INTEGERKEY))
9066                 return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND;
9067
9068         /* Find the DB info */
9069         dbflag = DB_NEW|DB_VALID;
9070         exact = 0;
9071         key.mv_size = len;
9072         key.mv_data = (void *)name;
9073         mdb_cursor_init(&mc, txn, MAIN_DBI, NULL);
9074         rc = mdb_cursor_set(&mc, &key, &data, MDB_SET, &exact);
9075         if (rc == MDB_SUCCESS) {
9076                 /* make sure this is actually a DB */
9077                 MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]);
9078                 if (!(node->mn_flags & F_SUBDATA))
9079                         return MDB_INCOMPATIBLE;
9080         } else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) {
9081                 /* Create if requested */
9082                 data.mv_size = sizeof(MDB_db);
9083                 data.mv_data = &dummy;
9084                 memset(&dummy, 0, sizeof(dummy));
9085                 dummy.md_root = P_INVALID;
9086                 dummy.md_flags = flags & PERSISTENT_FLAGS;
9087                 rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA);
9088                 dbflag |= DB_DIRTY;
9089         }
9090
9091         /* OK, got info, add to table */
9092         if (rc == MDB_SUCCESS) {
9093                 unsigned int slot = unused ? unused : txn->mt_numdbs;
9094                 txn->mt_dbxs[slot].md_name.mv_data = strdup(name);
9095                 txn->mt_dbxs[slot].md_name.mv_size = len;
9096                 txn->mt_dbxs[slot].md_rel = NULL;
9097                 txn->mt_dbflags[slot] = dbflag;
9098                 /* txn-> and env-> are the same in read txns, use
9099                  * tmp variable to avoid undefined assignment
9100                  */
9101                 seq = ++txn->mt_env->me_dbiseqs[slot];
9102                 txn->mt_dbiseqs[slot] = seq;
9103
9104                 memcpy(&txn->mt_dbs[slot], data.mv_data, sizeof(MDB_db));
9105                 *dbi = slot;
9106                 mdb_default_cmp(txn, slot);
9107                 if (!unused) {
9108                         txn->mt_numdbs++;
9109                 }
9110         }
9111
9112         return rc;
9113 }
9114
9115 int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *arg)
9116 {
9117         if (!arg || !TXN_DBI_EXIST(txn, dbi))
9118                 return EINVAL;
9119
9120         if (txn->mt_flags & MDB_TXN_ERROR)
9121                 return MDB_BAD_TXN;
9122
9123         if (txn->mt_dbflags[dbi] & DB_STALE) {
9124                 MDB_cursor mc;
9125                 MDB_xcursor mx;
9126                 /* Stale, must read the DB's root. cursor_init does it for us. */
9127                 mdb_cursor_init(&mc, txn, dbi, &mx);
9128         }
9129         return mdb_stat0(txn->mt_env, &txn->mt_dbs[dbi], arg);
9130 }
9131
9132 void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
9133 {
9134         char *ptr;
9135         if (dbi <= MAIN_DBI || dbi >= env->me_maxdbs)
9136                 return;
9137         ptr = env->me_dbxs[dbi].md_name.mv_data;
9138         /* If there was no name, this was already closed */
9139         if (ptr) {
9140                 env->me_dbxs[dbi].md_name.mv_data = NULL;
9141                 env->me_dbxs[dbi].md_name.mv_size = 0;
9142                 env->me_dbflags[dbi] = 0;
9143                 env->me_dbiseqs[dbi]++;
9144                 free(ptr);
9145         }
9146 }
9147
9148 int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
9149 {
9150         /* We could return the flags for the FREE_DBI too but what's the point? */
9151         if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9152                 return EINVAL;
9153         *flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS;
9154         return MDB_SUCCESS;
9155 }
9156
9157 /** Add all the DB's pages to the free list.
9158  * @param[in] mc Cursor on the DB to free.
9159  * @param[in] subs non-Zero to check for sub-DBs in this DB.
9160  * @return 0 on success, non-zero on failure.
9161  */
9162 static int
9163 mdb_drop0(MDB_cursor *mc, int subs)
9164 {
9165         int rc;
9166
9167         rc = mdb_page_search(mc, NULL, MDB_PS_FIRST);
9168         if (rc == MDB_SUCCESS) {
9169                 MDB_txn *txn = mc->mc_txn;
9170                 MDB_node *ni;
9171                 MDB_cursor mx;
9172                 unsigned int i;
9173
9174                 /* LEAF2 pages have no nodes, cannot have sub-DBs */
9175                 if (IS_LEAF2(mc->mc_pg[mc->mc_top]))
9176                         mdb_cursor_pop(mc);
9177
9178                 mdb_cursor_copy(mc, &mx);
9179                 while (mc->mc_snum > 0) {
9180                         MDB_page *mp = mc->mc_pg[mc->mc_top];
9181                         unsigned n = NUMKEYS(mp);
9182                         if (IS_LEAF(mp)) {
9183                                 for (i=0; i<n; i++) {
9184                                         ni = NODEPTR(mp, i);
9185                                         if (ni->mn_flags & F_BIGDATA) {
9186                                                 MDB_page *omp;
9187                                                 pgno_t pg;
9188                                                 memcpy(&pg, NODEDATA(ni), sizeof(pg));
9189                                                 rc = mdb_page_get(txn, pg, &omp, NULL);
9190                                                 if (rc != 0)
9191                                                         goto done;
9192                                                 mdb_cassert(mc, IS_OVERFLOW(omp));
9193                                                 rc = mdb_midl_append_range(&txn->mt_free_pgs,
9194                                                         pg, omp->mp_pages);
9195                                                 if (rc)
9196                                                         goto done;
9197                                         } else if (subs && (ni->mn_flags & F_SUBDATA)) {
9198                                                 mdb_xcursor_init1(mc, ni);
9199                                                 rc = mdb_drop0(&mc->mc_xcursor->mx_cursor, 0);
9200                                                 if (rc)
9201                                                         goto done;
9202                                         }
9203                                 }
9204                         } else {
9205                                 if ((rc = mdb_midl_need(&txn->mt_free_pgs, n)) != 0)
9206                                         goto done;
9207                                 for (i=0; i<n; i++) {
9208                                         pgno_t pg;
9209                                         ni = NODEPTR(mp, i);
9210                                         pg = NODEPGNO(ni);
9211                                         /* free it */
9212                                         mdb_midl_xappend(txn->mt_free_pgs, pg);
9213                                 }
9214                         }
9215                         if (!mc->mc_top)
9216                                 break;
9217                         mc->mc_ki[mc->mc_top] = i;
9218                         rc = mdb_cursor_sibling(mc, 1);
9219                         if (rc) {
9220                                 if (rc != MDB_NOTFOUND)
9221                                         goto done;
9222                                 /* no more siblings, go back to beginning
9223                                  * of previous level.
9224                                  */
9225                                 mdb_cursor_pop(mc);
9226                                 mc->mc_ki[0] = 0;
9227                                 for (i=1; i<mc->mc_snum; i++) {
9228                                         mc->mc_ki[i] = 0;
9229                                         mc->mc_pg[i] = mx.mc_pg[i];
9230                                 }
9231                         }
9232                 }
9233                 /* free it */
9234                 rc = mdb_midl_append(&txn->mt_free_pgs, mc->mc_db->md_root);
9235 done:
9236                 if (rc)
9237                         txn->mt_flags |= MDB_TXN_ERROR;
9238         } else if (rc == MDB_NOTFOUND) {
9239                 rc = MDB_SUCCESS;
9240         }
9241         return rc;
9242 }
9243
9244 int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
9245 {
9246         MDB_cursor *mc, *m2;
9247         int rc;
9248
9249         if ((unsigned)del > 1 || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9250                 return EINVAL;
9251
9252         if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
9253                 return EACCES;
9254
9255         if (dbi > MAIN_DBI && TXN_DBI_CHANGED(txn, dbi))
9256                 return MDB_BAD_DBI;
9257
9258         rc = mdb_cursor_open(txn, dbi, &mc);
9259         if (rc)
9260                 return rc;
9261
9262         rc = mdb_drop0(mc, mc->mc_db->md_flags & MDB_DUPSORT);
9263         /* Invalidate the dropped DB's cursors */
9264         for (m2 = txn->mt_cursors[dbi]; m2; m2 = m2->mc_next)
9265                 m2->mc_flags &= ~(C_INITIALIZED|C_EOF);
9266         if (rc)
9267                 goto leave;
9268
9269         /* Can't delete the main DB */
9270         if (del && dbi > MAIN_DBI) {
9271                 rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, 0);
9272                 if (!rc) {
9273                         txn->mt_dbflags[dbi] = DB_STALE;
9274                         mdb_dbi_close(txn->mt_env, dbi);
9275                 } else {
9276                         txn->mt_flags |= MDB_TXN_ERROR;
9277                 }
9278         } else {
9279                 /* reset the DB record, mark it dirty */
9280                 txn->mt_dbflags[dbi] |= DB_DIRTY;
9281                 txn->mt_dbs[dbi].md_depth = 0;
9282                 txn->mt_dbs[dbi].md_branch_pages = 0;
9283                 txn->mt_dbs[dbi].md_leaf_pages = 0;
9284                 txn->mt_dbs[dbi].md_overflow_pages = 0;
9285                 txn->mt_dbs[dbi].md_entries = 0;
9286                 txn->mt_dbs[dbi].md_root = P_INVALID;
9287
9288                 txn->mt_flags |= MDB_TXN_DIRTY;
9289         }
9290 leave:
9291         mdb_cursor_close(mc);
9292         return rc;
9293 }
9294
9295 int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
9296 {
9297         if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9298                 return EINVAL;
9299
9300         txn->mt_dbxs[dbi].md_cmp = cmp;
9301         return MDB_SUCCESS;
9302 }
9303
9304 int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
9305 {
9306         if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9307                 return EINVAL;
9308
9309         txn->mt_dbxs[dbi].md_dcmp = cmp;
9310         return MDB_SUCCESS;
9311 }
9312
9313 int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
9314 {
9315         if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9316                 return EINVAL;
9317
9318         txn->mt_dbxs[dbi].md_rel = rel;
9319         return MDB_SUCCESS;
9320 }
9321
9322 int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
9323 {
9324         if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
9325                 return EINVAL;
9326
9327         txn->mt_dbxs[dbi].md_relctx = ctx;
9328         return MDB_SUCCESS;
9329 }
9330
9331 int ESECT
9332 mdb_env_get_maxkeysize(MDB_env *env)
9333 {
9334         return ENV_MAXKEY(env);
9335 }
9336
9337 int ESECT
9338 mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx)
9339 {
9340         unsigned int i, rdrs;
9341         MDB_reader *mr;
9342         char buf[64];
9343         int rc = 0, first = 1;
9344
9345         if (!env || !func)
9346                 return -1;
9347         if (!env->me_txns) {
9348                 return func("(no reader locks)\n", ctx);
9349         }
9350         rdrs = env->me_txns->mti_numreaders;
9351         mr = env->me_txns->mti_readers;
9352         for (i=0; i<rdrs; i++) {
9353                 if (mr[i].mr_pid) {
9354                         txnid_t txnid = mr[i].mr_txnid;
9355                         sprintf(buf, txnid == (txnid_t)-1 ?
9356                                 "%10d %"Z"x -\n" : "%10d %"Z"x %"Z"u\n",
9357                                 (int)mr[i].mr_pid, (size_t)mr[i].mr_tid, txnid);
9358                         if (first) {
9359                                 first = 0;
9360                                 rc = func("    pid     thread     txnid\n", ctx);
9361                                 if (rc < 0)
9362                                         break;
9363                         }
9364                         rc = func(buf, ctx);
9365                         if (rc < 0)
9366                                 break;
9367                 }
9368         }
9369         if (first) {
9370                 rc = func("(no active readers)\n", ctx);
9371         }
9372         return rc;
9373 }
9374
9375 /** Insert pid into list if not already present.
9376  * return -1 if already present.
9377  */
9378 static int ESECT
9379 mdb_pid_insert(MDB_PID_T *ids, MDB_PID_T pid)
9380 {
9381         /* binary search of pid in list */
9382         unsigned base = 0;
9383         unsigned cursor = 1;
9384         int val = 0;
9385         unsigned n = ids[0];
9386
9387         while( 0 < n ) {
9388                 unsigned pivot = n >> 1;
9389                 cursor = base + pivot + 1;
9390                 val = pid - ids[cursor];
9391
9392                 if( val < 0 ) {
9393                         n = pivot;
9394
9395                 } else if ( val > 0 ) {
9396                         base = cursor;
9397                         n -= pivot + 1;
9398
9399                 } else {
9400                         /* found, so it's a duplicate */
9401                         return -1;
9402                 }
9403         }
9404
9405         if( val > 0 ) {
9406                 ++cursor;
9407         }
9408         ids[0]++;
9409         for (n = ids[0]; n > cursor; n--)
9410                 ids[n] = ids[n-1];
9411         ids[n] = pid;
9412         return 0;
9413 }
9414
9415 int ESECT
9416 mdb_reader_check(MDB_env *env, int *dead)
9417 {
9418         unsigned int i, j, rdrs;
9419         MDB_reader *mr;
9420         MDB_PID_T *pids, pid;
9421         int count = 0;
9422
9423         if (!env)
9424                 return EINVAL;
9425         if (dead)
9426                 *dead = 0;
9427         if (!env->me_txns)
9428                 return MDB_SUCCESS;
9429         rdrs = env->me_txns->mti_numreaders;
9430         pids = malloc((rdrs+1) * sizeof(MDB_PID_T));
9431         if (!pids)
9432                 return ENOMEM;
9433         pids[0] = 0;
9434         mr = env->me_txns->mti_readers;
9435         for (i=0; i<rdrs; i++) {
9436                 if (mr[i].mr_pid && mr[i].mr_pid != env->me_pid) {
9437                         pid = mr[i].mr_pid;
9438                         if (mdb_pid_insert(pids, pid) == 0) {
9439                                 if (!mdb_reader_pid(env, Pidcheck, pid)) {
9440                                         LOCK_MUTEX_R(env);
9441                                         /* Recheck, a new process may have reused pid */
9442                                         if (!mdb_reader_pid(env, Pidcheck, pid)) {
9443                                                 for (j=i; j<rdrs; j++)
9444                                                         if (mr[j].mr_pid == pid) {
9445                                                                 DPRINTF(("clear stale reader pid %u txn %"Z"d",
9446                                                                         (unsigned) pid, mr[j].mr_txnid));
9447                                                                 mr[j].mr_pid = 0;
9448                                                                 count++;
9449                                                         }
9450                                         }
9451                                         UNLOCK_MUTEX_R(env);
9452                                 }
9453                         }
9454                 }
9455         }
9456         free(pids);
9457         if (dead)
9458                 *dead = count;
9459         return MDB_SUCCESS;
9460 }
9461 /** @} */