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