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