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