lmdb 0.6 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/lmdb_ext/extconf.rb +7 -3
- data/ext/lmdb_ext/lmdb_ext.c +120 -110
- data/lib/lmdb/version.rb +1 -1
- data/lmdb.gemspec +4 -4
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/.gitignore +8 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/COPYRIGHT +1 -1
- data/vendor/libraries/liblmdb/Doxyfile +1631 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/LICENSE +0 -0
- data/vendor/libraries/liblmdb/Makefile +118 -0
- data/vendor/libraries/liblmdb/intro.doc +192 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/lmdb.h +161 -61
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/mdb.c +3244 -1302
- data/vendor/libraries/liblmdb/mdb_copy.1 +61 -0
- data/vendor/libraries/liblmdb/mdb_copy.c +84 -0
- data/vendor/libraries/liblmdb/mdb_drop.1 +40 -0
- data/vendor/libraries/liblmdb/mdb_drop.c +135 -0
- data/vendor/libraries/liblmdb/mdb_dump.1 +81 -0
- data/vendor/libraries/liblmdb/mdb_dump.c +319 -0
- data/vendor/libraries/liblmdb/mdb_load.1 +84 -0
- data/vendor/libraries/liblmdb/mdb_load.c +492 -0
- data/vendor/libraries/liblmdb/mdb_stat.1 +70 -0
- data/vendor/libraries/liblmdb/mdb_stat.c +264 -0
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/midl.c +66 -5
- data/{ext/lmdb_ext → vendor/libraries}/liblmdb/midl.h +19 -5
- data/vendor/libraries/liblmdb/mtest.c +177 -0
- data/vendor/libraries/liblmdb/mtest2.c +124 -0
- data/vendor/libraries/liblmdb/mtest3.c +133 -0
- data/vendor/libraries/liblmdb/mtest4.c +168 -0
- data/vendor/libraries/liblmdb/mtest5.c +135 -0
- data/vendor/libraries/liblmdb/mtest6.c +141 -0
- data/vendor/libraries/liblmdb/sample-bdb.txt +73 -0
- data/vendor/libraries/liblmdb/sample-mdb.txt +62 -0
- data/vendor/libraries/liblmdb/tooltag +27 -0
- metadata +34 -14
- data/.gitignore +0 -15
- data/.travis.yml +0 -14
- data/ext/lmdb_ext/liblmdb/CHANGES +0 -112
File without changes
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# Makefile for liblmdb (Lightning memory-mapped database library).
|
2
|
+
|
3
|
+
########################################################################
|
4
|
+
# Configuration. The compiler options must enable threaded compilation.
|
5
|
+
#
|
6
|
+
# Preprocessor macros (for CPPFLAGS) of interest...
|
7
|
+
# Note that the defaults should already be correct for most
|
8
|
+
# platforms; you should not need to change any of these.
|
9
|
+
# Read their descriptions in mdb.c if you do:
|
10
|
+
#
|
11
|
+
# - MDB_USE_POSIX_MUTEX, MDB_USE_POSIX_SEM, MDB_USE_SYSV_SEM
|
12
|
+
# - MDB_DSYNC
|
13
|
+
# - MDB_FDATASYNC
|
14
|
+
# - MDB_FDATASYNC_WORKS
|
15
|
+
# - MDB_USE_PWRITEV
|
16
|
+
# - MDB_USE_ROBUST
|
17
|
+
#
|
18
|
+
# There may be other macros in mdb.c of interest. You should
|
19
|
+
# read mdb.c before changing any of them.
|
20
|
+
#
|
21
|
+
CC = gcc
|
22
|
+
AR = ar
|
23
|
+
W = -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized
|
24
|
+
THREADS = -pthread
|
25
|
+
OPT = -O2 -g
|
26
|
+
CFLAGS = $(THREADS) $(OPT) $(W) $(XCFLAGS)
|
27
|
+
LDLIBS =
|
28
|
+
SOLIBS =
|
29
|
+
SOEXT = .so
|
30
|
+
prefix = /usr/local
|
31
|
+
exec_prefix = $(prefix)
|
32
|
+
bindir = $(exec_prefix)/bin
|
33
|
+
libdir = $(exec_prefix)/lib
|
34
|
+
includedir = $(prefix)/include
|
35
|
+
datarootdir = $(prefix)/share
|
36
|
+
mandir = $(datarootdir)/man
|
37
|
+
|
38
|
+
########################################################################
|
39
|
+
|
40
|
+
IHDRS = lmdb.h
|
41
|
+
ILIBS = liblmdb.a liblmdb$(SOEXT)
|
42
|
+
IPROGS = mdb_stat mdb_copy mdb_dump mdb_load mdb_drop
|
43
|
+
IDOCS = mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1 mdb_drop.1
|
44
|
+
PROGS = $(IPROGS) mtest mtest2 mtest3 mtest4 mtest5
|
45
|
+
all: $(ILIBS) $(PROGS)
|
46
|
+
|
47
|
+
install: $(ILIBS) $(IPROGS) $(IHDRS)
|
48
|
+
mkdir -p $(DESTDIR)$(bindir)
|
49
|
+
mkdir -p $(DESTDIR)$(libdir)
|
50
|
+
mkdir -p $(DESTDIR)$(includedir)
|
51
|
+
mkdir -p $(DESTDIR)$(mandir)/man1
|
52
|
+
for f in $(IPROGS); do cp $$f $(DESTDIR)$(bindir); done
|
53
|
+
for f in $(ILIBS); do cp $$f $(DESTDIR)$(libdir); done
|
54
|
+
for f in $(IHDRS); do cp $$f $(DESTDIR)$(includedir); done
|
55
|
+
for f in $(IDOCS); do cp $$f $(DESTDIR)$(mandir)/man1; done
|
56
|
+
|
57
|
+
clean:
|
58
|
+
rm -rf $(PROGS) *.[ao] *.[ls]o *~ testdb
|
59
|
+
|
60
|
+
test: all
|
61
|
+
rm -rf testdb && mkdir testdb
|
62
|
+
./mtest && ./mdb_stat testdb
|
63
|
+
|
64
|
+
liblmdb.a: mdb.o midl.o
|
65
|
+
$(AR) rs $@ mdb.o midl.o
|
66
|
+
|
67
|
+
liblmdb$(SOEXT): mdb.lo midl.lo
|
68
|
+
# $(CC) $(LDFLAGS) -pthread -shared -Wl,-Bsymbolic -o $@ mdb.o midl.o $(SOLIBS)
|
69
|
+
$(CC) $(LDFLAGS) -pthread -shared -o $@ mdb.lo midl.lo $(SOLIBS)
|
70
|
+
|
71
|
+
mdb_stat: mdb_stat.o liblmdb.a
|
72
|
+
mdb_copy: mdb_copy.o liblmdb.a
|
73
|
+
mdb_dump: mdb_dump.o liblmdb.a
|
74
|
+
mdb_load: mdb_load.o liblmdb.a
|
75
|
+
mdb_drop: mdb_drop.o liblmdb.a
|
76
|
+
mtest: mtest.o liblmdb.a
|
77
|
+
mtest2: mtest2.o liblmdb.a
|
78
|
+
mtest3: mtest3.o liblmdb.a
|
79
|
+
mtest4: mtest4.o liblmdb.a
|
80
|
+
mtest5: mtest5.o liblmdb.a
|
81
|
+
mtest6: mtest6.o liblmdb.a
|
82
|
+
|
83
|
+
mdb.o: mdb.c lmdb.h midl.h
|
84
|
+
$(CC) $(CFLAGS) $(CPPFLAGS) -c mdb.c
|
85
|
+
|
86
|
+
midl.o: midl.c midl.h
|
87
|
+
$(CC) $(CFLAGS) $(CPPFLAGS) -c midl.c
|
88
|
+
|
89
|
+
mdb.lo: mdb.c lmdb.h midl.h
|
90
|
+
$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c mdb.c -o $@
|
91
|
+
|
92
|
+
midl.lo: midl.c midl.h
|
93
|
+
$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c midl.c -o $@
|
94
|
+
|
95
|
+
%: %.o
|
96
|
+
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
97
|
+
|
98
|
+
%.o: %.c lmdb.h
|
99
|
+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
100
|
+
|
101
|
+
COV_FLAGS=-fprofile-arcs -ftest-coverage
|
102
|
+
COV_OBJS=xmdb.o xmidl.o
|
103
|
+
|
104
|
+
coverage: xmtest
|
105
|
+
for i in mtest*.c [0-9]*.c; do j=`basename \$$i .c`; $(MAKE) $$j.o; \
|
106
|
+
gcc -o x$$j $$j.o $(COV_OBJS) -pthread $(COV_FLAGS); \
|
107
|
+
rm -rf testdb; mkdir testdb; ./x$$j; done
|
108
|
+
gcov xmdb.c
|
109
|
+
gcov xmidl.c
|
110
|
+
|
111
|
+
xmtest: mtest.o xmdb.o xmidl.o
|
112
|
+
gcc -o xmtest mtest.o xmdb.o xmidl.o -pthread $(COV_FLAGS)
|
113
|
+
|
114
|
+
xmdb.o: mdb.c lmdb.h midl.h
|
115
|
+
$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -O0 $(COV_FLAGS) -c mdb.c -o $@
|
116
|
+
|
117
|
+
xmidl.o: midl.c midl.h
|
118
|
+
$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -O0 $(COV_FLAGS) -c midl.c -o $@
|
@@ -0,0 +1,192 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2015-2021 Howard Chu, Symas Corp.
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted only as authorized by the OpenLDAP
|
7
|
+
* Public License.
|
8
|
+
*
|
9
|
+
* A copy of this license is available in the file LICENSE in the
|
10
|
+
* top-level directory of the distribution or, alternatively, at
|
11
|
+
* <http://www.OpenLDAP.org/license.html>.
|
12
|
+
*/
|
13
|
+
/** @page starting Getting Started
|
14
|
+
|
15
|
+
LMDB is compact, fast, powerful, and robust and implements a simplified
|
16
|
+
variant of the BerkeleyDB (BDB) API. (BDB is also very powerful, and verbosely
|
17
|
+
documented in its own right.) After reading this page, the main
|
18
|
+
\ref mdb documentation should make sense. Thanks to Bert Hubert
|
19
|
+
for creating the
|
20
|
+
<a href="https://github.com/ahupowerdns/ahutils/blob/master/lmdb-semantics.md">
|
21
|
+
initial version</a> of this writeup.
|
22
|
+
|
23
|
+
Everything starts with an environment, created by #mdb_env_create().
|
24
|
+
Once created, this environment must also be opened with #mdb_env_open().
|
25
|
+
|
26
|
+
#mdb_env_open() gets passed a name which is interpreted as a directory
|
27
|
+
path. Note that this directory must exist already, it is not created
|
28
|
+
for you. Within that directory, a lock file and a storage file will be
|
29
|
+
generated. If you don't want to use a directory, you can pass the
|
30
|
+
#MDB_NOSUBDIR option, in which case the path you provided is used
|
31
|
+
directly as the data file, and another file with a "-lock" suffix
|
32
|
+
added will be used for the lock file.
|
33
|
+
|
34
|
+
Once the environment is open, a transaction can be created within it
|
35
|
+
using #mdb_txn_begin(). Transactions may be read-write or read-only,
|
36
|
+
and read-write transactions may be nested. A transaction must only
|
37
|
+
be used by one thread at a time. Transactions are always required,
|
38
|
+
even for read-only access. The transaction provides a consistent
|
39
|
+
view of the data.
|
40
|
+
|
41
|
+
Once a transaction has been created, a database can be opened within it
|
42
|
+
using #mdb_dbi_open(). If only one database will ever be used in the
|
43
|
+
environment, a NULL can be passed as the database name. For named
|
44
|
+
databases, the #MDB_CREATE flag must be used to create the database
|
45
|
+
if it doesn't already exist. Also, #mdb_env_set_maxdbs() must be
|
46
|
+
called after #mdb_env_create() and before #mdb_env_open() to set the
|
47
|
+
maximum number of named databases you want to support.
|
48
|
+
|
49
|
+
Note: a single transaction can open multiple databases. Generally
|
50
|
+
databases should only be opened once, by the first transaction in
|
51
|
+
the process. After the first transaction completes, the database
|
52
|
+
handles can freely be used by all subsequent transactions.
|
53
|
+
|
54
|
+
Within a transaction, #mdb_get() and #mdb_put() can store single
|
55
|
+
key/value pairs if that is all you need to do (but see \ref Cursors
|
56
|
+
below if you want to do more).
|
57
|
+
|
58
|
+
A key/value pair is expressed as two #MDB_val structures. This struct
|
59
|
+
has two fields, \c mv_size and \c mv_data. The data is a \c void pointer to
|
60
|
+
an array of \c mv_size bytes.
|
61
|
+
|
62
|
+
Because LMDB is very efficient (and usually zero-copy), the data returned
|
63
|
+
in an #MDB_val structure may be memory-mapped straight from disk. In
|
64
|
+
other words <b>look but do not touch</b> (or free() for that matter).
|
65
|
+
Once a transaction is closed, the values can no longer be used, so
|
66
|
+
make a copy if you need to keep them after that.
|
67
|
+
|
68
|
+
@section Cursors Cursors
|
69
|
+
|
70
|
+
To do more powerful things, we must use a cursor.
|
71
|
+
|
72
|
+
Within the transaction, a cursor can be created with #mdb_cursor_open().
|
73
|
+
With this cursor we can store/retrieve/delete (multiple) values using
|
74
|
+
#mdb_cursor_get(), #mdb_cursor_put(), and #mdb_cursor_del().
|
75
|
+
|
76
|
+
#mdb_cursor_get() positions itself depending on the cursor operation
|
77
|
+
requested, and for some operations, on the supplied key. For example,
|
78
|
+
to list all key/value pairs in a database, use operation #MDB_FIRST for
|
79
|
+
the first call to #mdb_cursor_get(), and #MDB_NEXT on subsequent calls,
|
80
|
+
until the end is hit.
|
81
|
+
|
82
|
+
To retrieve all keys starting from a specified key value, use #MDB_SET.
|
83
|
+
For more cursor operations, see the \ref mdb docs.
|
84
|
+
|
85
|
+
When using #mdb_cursor_put(), either the function will position the
|
86
|
+
cursor for you based on the \b key, or you can use operation
|
87
|
+
#MDB_CURRENT to use the current position of the cursor. Note that
|
88
|
+
\b key must then match the current position's key.
|
89
|
+
|
90
|
+
@subsection summary Summarizing the Opening
|
91
|
+
|
92
|
+
So we have a cursor in a transaction which opened a database in an
|
93
|
+
environment which is opened from a filesystem after it was
|
94
|
+
separately created.
|
95
|
+
|
96
|
+
Or, we create an environment, open it from a filesystem, create a
|
97
|
+
transaction within it, open a database within that transaction,
|
98
|
+
and create a cursor within all of the above.
|
99
|
+
|
100
|
+
Got it?
|
101
|
+
|
102
|
+
@section thrproc Threads and Processes
|
103
|
+
|
104
|
+
LMDB uses POSIX locks on files, and these locks have issues if one
|
105
|
+
process opens a file multiple times. Because of this, do not
|
106
|
+
#mdb_env_open() a file multiple times from a single process. Instead,
|
107
|
+
share the LMDB environment that has opened the file across all threads.
|
108
|
+
Otherwise, if a single process opens the same environment multiple times,
|
109
|
+
closing it once will remove all the locks held on it, and the other
|
110
|
+
instances will be vulnerable to corruption from other processes.
|
111
|
+
|
112
|
+
Also note that a transaction is tied to one thread by default using
|
113
|
+
Thread Local Storage. If you want to pass read-only transactions across
|
114
|
+
threads, you can use the #MDB_NOTLS option on the environment.
|
115
|
+
|
116
|
+
@section txns Transactions, Rollbacks, etc.
|
117
|
+
|
118
|
+
To actually get anything done, a transaction must be committed using
|
119
|
+
#mdb_txn_commit(). Alternatively, all of a transaction's operations
|
120
|
+
can be discarded using #mdb_txn_abort(). In a read-only transaction,
|
121
|
+
any cursors will \b not automatically be freed. In a read-write
|
122
|
+
transaction, all cursors will be freed and must not be used again.
|
123
|
+
|
124
|
+
For read-only transactions, obviously there is nothing to commit to
|
125
|
+
storage. The transaction still must eventually be aborted to close
|
126
|
+
any database handle(s) opened in it, or committed to keep the
|
127
|
+
database handles around for reuse in new transactions.
|
128
|
+
|
129
|
+
In addition, as long as a transaction is open, a consistent view of
|
130
|
+
the database is kept alive, which requires storage. A read-only
|
131
|
+
transaction that no longer requires this consistent view should
|
132
|
+
be terminated (committed or aborted) when the view is no longer
|
133
|
+
needed (but see below for an optimization).
|
134
|
+
|
135
|
+
There can be multiple simultaneously active read-only transactions
|
136
|
+
but only one that can write. Once a single read-write transaction
|
137
|
+
is opened, all further attempts to begin one will block until the
|
138
|
+
first one is committed or aborted. This has no effect on read-only
|
139
|
+
transactions, however, and they may continue to be opened at any time.
|
140
|
+
|
141
|
+
@section dupkeys Duplicate Keys
|
142
|
+
|
143
|
+
#mdb_get() and #mdb_put() respectively have no and only some support
|
144
|
+
for multiple key/value pairs with identical keys. If there are multiple
|
145
|
+
values for a key, #mdb_get() will only return the first value.
|
146
|
+
|
147
|
+
When multiple values for one key are required, pass the #MDB_DUPSORT
|
148
|
+
flag to #mdb_dbi_open(). In an #MDB_DUPSORT database, by default
|
149
|
+
#mdb_put() will not replace the value for a key if the key existed
|
150
|
+
already. Instead it will add the new value to the key. In addition,
|
151
|
+
#mdb_del() will pay attention to the value field too, allowing for
|
152
|
+
specific values of a key to be deleted.
|
153
|
+
|
154
|
+
Finally, additional cursor operations become available for
|
155
|
+
traversing through and retrieving duplicate values.
|
156
|
+
|
157
|
+
@section optim Some Optimization
|
158
|
+
|
159
|
+
If you frequently begin and abort read-only transactions, as an
|
160
|
+
optimization, it is possible to only reset and renew a transaction.
|
161
|
+
|
162
|
+
#mdb_txn_reset() releases any old copies of data kept around for
|
163
|
+
a read-only transaction. To reuse this reset transaction, call
|
164
|
+
#mdb_txn_renew() on it. Any cursors in this transaction must also
|
165
|
+
be renewed using #mdb_cursor_renew().
|
166
|
+
|
167
|
+
Note that #mdb_txn_reset() is similar to #mdb_txn_abort() and will
|
168
|
+
close any databases you opened within the transaction.
|
169
|
+
|
170
|
+
To permanently free a transaction, reset or not, use #mdb_txn_abort().
|
171
|
+
|
172
|
+
@section cleanup Cleaning Up
|
173
|
+
|
174
|
+
For read-only transactions, any cursors created within it must
|
175
|
+
be closed using #mdb_cursor_close().
|
176
|
+
|
177
|
+
It is very rarely necessary to close a database handle, and in
|
178
|
+
general they should just be left open.
|
179
|
+
|
180
|
+
@section onward The Full API
|
181
|
+
|
182
|
+
The full \ref mdb documentation lists further details, like how to:
|
183
|
+
|
184
|
+
\li size a database (the default limits are intentionally small)
|
185
|
+
\li drop and clean a database
|
186
|
+
\li detect and report errors
|
187
|
+
\li optimize (bulk) loading speed
|
188
|
+
\li (temporarily) reduce robustness to gain even more speed
|
189
|
+
\li gather statistics about the database
|
190
|
+
\li define custom sort orders
|
191
|
+
|
192
|
+
*/
|