Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
HAMANO Tsukasa
OpenLDAP
Commits
70a4f6f2
Commit
70a4f6f2
authored
Sep 05, 2011
by
Howard Chu
Browse files
mdb_cmp refactoring
parent
7bb14a2e
Changes
2
Hide whitespace changes
Inline
Side-by-side
libraries/libmdb/mdb.c
View file @
70a4f6f2
...
...
@@ -529,10 +529,9 @@ static size_t mdb_leaf_size(MDB_env *env, MDB_val *key,
MDB_val
*
data
);
static
size_t
mdb_branch_size
(
MDB_env
*
env
,
MDB_val
*
key
);
static
int
memncmp
(
const
void
*
s1
,
size_t
n1
,
const
void
*
s2
,
size_t
n2
);
static
int
memnrcmp
(
const
void
*
s1
,
size_t
n1
,
const
void
*
s2
,
size_t
n2
);
static
void
mdb_default_cmp
(
MDB_txn
*
txn
,
MDB_dbi
dbi
);
static
MDB_cmp_func
memncmp
,
memnrcmp
,
intcmp
;
#ifdef _WIN32
static
SECURITY_DESCRIPTOR
mdb_null_sd
;
...
...
@@ -540,39 +539,6 @@ static SECURITY_ATTRIBUTES mdb_all_sa;
static
int
mdb_sec_inited
;
#endif
static
int
memncmp
(
const
void
*
s1
,
size_t
n1
,
const
void
*
s2
,
size_t
n2
)
{
int
diff
,
len_diff
=
-
1
;
if
(
n1
>=
n2
)
{
len_diff
=
(
n1
>
n2
);
n1
=
n2
;
}
diff
=
memcmp
(
s1
,
s2
,
n1
);
return
diff
?
diff
:
len_diff
;
}
static
int
memnrcmp
(
const
void
*
s1
,
size_t
n1
,
const
void
*
s2
,
size_t
n2
)
{
const
unsigned
char
*
p1
,
*
p2
,
*
p1_lim
;
if
(
n2
==
0
)
return
n1
!=
0
;
if
(
n1
==
0
)
return
-
1
;
p1
=
(
const
unsigned
char
*
)
s1
+
n1
-
1
;
p2
=
(
const
unsigned
char
*
)
s2
+
n2
-
1
;
for
(
p1_lim
=
(
n1
<=
n2
?
s1
:
s2
);
*
p1
==
*
p2
;
p1
--
,
p2
--
)
{
if
(
p1
==
p1_lim
)
return
(
p1
!=
s1
)
?
(
p1
!=
p2
)
:
(
p2
!=
s2
)
?
-
1
:
0
;
}
return
*
p1
-
*
p2
;
}
char
*
mdb_version
(
int
*
maj
,
int
*
min
,
int
*
pat
)
{
...
...
@@ -625,17 +591,7 @@ mdb_dkey(MDB_val *key, char *buf)
int
mdb_cmp
(
MDB_txn
*
txn
,
MDB_dbi
dbi
,
const
MDB_val
*
a
,
const
MDB_val
*
b
)
{
if
(
txn
->
mt_dbxs
[
dbi
].
md_cmp
)
return
txn
->
mt_dbxs
[
dbi
].
md_cmp
(
a
,
b
);
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
(
MDB_REVERSEKEY
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
MDB_INTEGERKEY
#endif
))
return
memnrcmp
(
a
->
mv_data
,
a
->
mv_size
,
b
->
mv_data
,
b
->
mv_size
);
else
return
memncmp
((
char
*
)
a
->
mv_data
,
a
->
mv_size
,
b
->
mv_data
,
b
->
mv_size
);
return
txn
->
mt_dbxs
[
dbi
].
md_cmp
(
a
,
b
);
}
int
...
...
@@ -643,15 +599,8 @@ mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
{
if
(
txn
->
mt_dbxs
[
dbi
].
md_dcmp
)
return
txn
->
mt_dbxs
[
dbi
].
md_dcmp
(
a
,
b
);
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
(
0
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
MDB_INTEGERDUP
#endif
))
return
memnrcmp
(
a
->
mv_data
,
a
->
mv_size
,
b
->
mv_data
,
b
->
mv_size
);
else
return
memncmp
((
char
*
)
a
->
mv_data
,
a
->
mv_size
,
b
->
mv_data
,
b
->
mv_size
);
return
EINVAL
;
/* too bad you can't distinguish this from a valid result */
}
/* Allocate new page(s) for writing */
...
...
@@ -1979,6 +1928,67 @@ mdb_env_close(MDB_env *env)
free
(
env
);
}
static
int
intcmp
(
const
MDB_val
*
a
,
const
MDB_val
*
b
)
{
if
(
a
->
mv_size
==
sizeof
(
long
))
{
unsigned
long
*
la
,
*
lb
;
la
=
a
->
mv_data
;
lb
=
b
->
mv_data
;
return
*
la
-
*
lb
;
}
else
{
unsigned
int
*
ia
,
*
ib
;
ia
=
a
->
mv_data
;
ib
=
b
->
mv_data
;
return
*
ia
-
*
ib
;
}
}
static
int
memncmp
(
const
MDB_val
*
a
,
const
MDB_val
*
b
)
{
int
diff
,
len_diff
;
unsigned
int
len
;
len
=
a
->
mv_size
;
len_diff
=
a
->
mv_size
-
b
->
mv_size
;
if
(
len_diff
>
0
)
len
=
b
->
mv_size
;
diff
=
memcmp
(
a
->
mv_data
,
b
->
mv_data
,
len
);
return
diff
?
diff
:
len_diff
;
}
static
int
memnrcmp
(
const
MDB_val
*
a
,
const
MDB_val
*
b
)
{
const
unsigned
char
*
p1
,
*
p2
,
*
p1_lim
;
int
diff
,
len_diff
;
if
(
b
->
mv_size
==
0
)
return
a
->
mv_size
!=
0
;
if
(
a
->
mv_size
==
0
)
return
-
1
;
p1
=
(
const
unsigned
char
*
)
a
->
mv_data
+
a
->
mv_size
-
1
;
p2
=
(
const
unsigned
char
*
)
b
->
mv_data
+
b
->
mv_size
-
1
;
len_diff
=
a
->
mv_size
-
b
->
mv_size
;
if
(
len_diff
<
0
)
p1_lim
=
p1
-
a
->
mv_size
;
else
p1_lim
=
p1
-
b
->
mv_size
;
while
(
p1
>=
p1_lim
)
{
diff
=
*
p1
-
*
p2
;
if
(
diff
)
return
diff
;
p1
--
;
p2
--
;
}
return
len_diff
;
}
/* Search for key within a leaf page, using binary search.
* Returns the smallest entry larger or equal to the key.
* If exactp is non-null, stores whether the found entry was an exact match
...
...
@@ -1990,29 +2000,33 @@ static MDB_node *
mdb_search_node
(
MDB_txn
*
txn
,
MDB_dbi
dbi
,
MDB_page
*
mp
,
MDB_val
*
key
,
int
*
exactp
,
unsigned
int
*
kip
)
{
unsigned
int
i
=
0
;
unsigned
int
i
=
0
,
nkeys
;
int
low
,
high
;
int
rc
=
0
;
MDB_node
*
node
=
NULL
;
MDB_val
nodekey
;
MDB_cmp_func
*
cmp
;
DKBUF
;
nkeys
=
NUMKEYS
(
mp
);
DPRINTF
(
"searching %u keys in %s page %lu"
,
NUMKEYS
(
mp
),
IS_LEAF
(
mp
)
?
"leaf"
:
"branch"
,
nkeys
,
IS_LEAF
(
mp
)
?
"leaf"
:
"branch"
,
mp
->
mp_pgno
);
assert
(
NUMKEYS
(
mp
)
>
0
);
memset
(
&
nodekey
,
0
,
sizeof
(
nodekey
));
assert
(
nkeys
>
0
);
low
=
IS_LEAF
(
mp
)
?
0
:
1
;
high
=
NUMKEYS
(
mp
)
-
1
;
high
=
nkeys
-
1
;
cmp
=
txn
->
mt_dbxs
[
dbi
].
md_cmp
;
if
(
IS_LEAF2
(
mp
))
{
nodekey
.
mv_size
=
txn
->
mt_dbs
[
dbi
].
md_pad
;
node
=
NODEPTR
(
mp
,
0
);
/* fake */
}
while
(
low
<=
high
)
{
i
=
(
low
+
high
)
>>
1
;
if
(
IS_LEAF2
(
mp
))
{
nodekey
.
mv_size
=
txn
->
mt_dbs
[
dbi
].
md_pad
;
nodekey
.
mv_data
=
LEAF2KEY
(
mp
,
i
,
nodekey
.
mv_size
);
}
else
{
node
=
NODEPTR
(
mp
,
i
);
...
...
@@ -2021,14 +2035,16 @@ mdb_search_node(MDB_txn *txn, MDB_dbi dbi, MDB_page *mp, MDB_val *key,
nodekey
.
mv_data
=
NODEKEY
(
node
);
}
rc
=
mdb_cmp
(
txn
,
dbi
,
key
,
&
nodekey
);
rc
=
cmp
(
key
,
&
nodekey
);
#if DEBUG
if
(
IS_LEAF
(
mp
))
DPRINTF
(
"found leaf index %u [%s], rc = %i"
,
i
,
DKEY
(
&
nodekey
),
rc
);
else
DPRINTF
(
"found branch index %u [%s -> %lu], rc = %i"
,
i
,
DKEY
(
&
nodekey
),
NODEPGNO
(
node
),
rc
);
#endif
if
(
rc
==
0
)
break
;
...
...
@@ -2045,12 +2061,12 @@ mdb_search_node(MDB_txn *txn, MDB_dbi dbi, MDB_page *mp, MDB_val *key,
*
exactp
=
(
rc
==
0
);
if
(
kip
)
/* Store the key index if requested. */
*
kip
=
i
;
if
(
i
>=
NUMKEYS
(
mp
)
)
if
(
i
>=
nkeys
)
/* There is no entry larger or equal to the key. */
return
NULL
;
/* nodeptr is fake for LEAF2 */
return
IS_LEAF2
(
mp
)
?
NODEPTR
(
mp
,
0
)
:
NODEPTR
(
mp
,
i
)
;
return
node
;
}
static
void
...
...
@@ -2163,7 +2179,7 @@ mdb_search_page_root(MDB_txn *txn, MDB_dbi dbi, MDB_val *key,
return
ENOMEM
;
if
(
modify
)
{
MDB_dhead
*
dh
=
((
MDB_dhead
*
)
mp
)
-
1
;
MDB_dhead
*
dh
;
if
((
rc
=
mdb_touch
(
txn
,
dbi
,
mpp
))
!=
0
)
return
rc
;
dh
=
((
MDB_dhead
*
)
mpp
->
mp_page
)
-
1
;
...
...
@@ -2524,7 +2540,7 @@ mdb_cursor_set(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
leaf
=
NODEPTR
(
top
->
mp_page
,
0
);
MDB_SET_KEY
(
leaf
,
&
nodekey
);
}
rc
=
mdb_cmp
(
cursor
->
mc_txn
,
cursor
->
mc_dbi
,
key
,
&
nodekey
);
rc
=
cursor
->
mc_txn
->
mt_dbxs
[
cursor
->
mc_dbi
].
md_cmp
(
key
,
&
nodekey
);
if
(
rc
==
0
)
{
set1:
/* we're already on the right page */
...
...
@@ -2542,7 +2558,7 @@ set1:
leaf
=
NODEPTR
(
top
->
mp_page
,
NUMKEYS
(
top
->
mp_page
)
-
1
);
MDB_SET_KEY
(
leaf
,
&
nodekey
);
}
rc
=
mdb_cmp
(
cursor
->
mc_txn
,
cursor
->
mc_dbi
,
key
,
&
nodekey
);
rc
=
cursor
->
mc_txn
->
mt_dbxs
[
cursor
->
mc_dbi
].
md_cmp
(
key
,
&
nodekey
);
if
(
rc
<=
0
)
goto
set1
;
}
/* If any parents have right-sibs, search.
...
...
@@ -2618,7 +2634,7 @@ set2:
MDB_val
d2
;
if
((
rc
=
mdb_read_data
(
cursor
->
mc_txn
,
leaf
,
&
d2
))
!=
MDB_SUCCESS
)
return
rc
;
rc
=
mdb_dcmp
(
cursor
->
mc_txn
,
cursor
->
mc_dbi
,
data
,
&
d2
);
rc
=
cursor
->
mc_txn
->
mt_dbxs
[
cursor
->
mc_dbi
].
md_cmp
(
data
,
&
d2
);
if
(
rc
)
{
if
(
op
==
MDB_GET_BOTH
||
rc
>
0
)
return
MDB_NOTFOUND
;
...
...
@@ -2941,7 +2957,7 @@ top:
if
(
rc
==
MDB_SUCCESS
)
{
/* there's only a key anyway, so this is a no-op */
if
(
IS_LEAF2
(
top
->
mp_page
))
{
int
ksize
=
mc
->
mc_txn
->
mt_dbs
[
mc
->
mc_dbi
].
md_pad
;
unsigned
int
ksize
=
mc
->
mc_txn
->
mt_dbs
[
mc
->
mc_dbi
].
md_pad
;
if
(
key
->
mv_size
!=
ksize
)
return
EINVAL
;
if
(
flags
==
MDB_CURRENT
)
{
...
...
@@ -3103,11 +3119,13 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
NULL
,
&
mc
->
mc_xcursor
->
mx_cursor
,
0
,
&
mp2
);
if
(
rc
==
MDB_SUCCESS
)
{
MDB_ppage
*
top
,
*
parent
;
MDB_dpage
*
dp
;
ID2
mid
;
MDB_node
*
ni
;
unsigned
int
i
;
#if 0
MDB_dpage *dp;
ID2 mid;
int dirty_root = 0;
#endif
mc
->
mc_txn
->
mt_dbs
[
mc
->
mc_dbi
].
md_entries
-=
mc
->
mc_xcursor
->
mx_txn
.
mt_dbs
[
mc
->
mc_xcursor
->
mx_cursor
.
mc_dbi
].
md_entries
;
...
...
@@ -4353,7 +4371,6 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
{
MDB_cursor
mc
;
MDB_xcursor
mx
;
int
rc
;
assert
(
key
!=
NULL
);
assert
(
data
!=
NULL
);
...
...
@@ -4443,6 +4460,38 @@ mdb_env_stat(MDB_env *env, MDB_stat *arg)
return
mdb_stat0
(
env
,
&
env
->
me_metas
[
toggle
]
->
mm_dbs
[
MAIN_DBI
],
arg
);
}
static
void
mdb_default_cmp
(
MDB_txn
*
txn
,
MDB_dbi
dbi
)
{
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
(
MDB_REVERSEKEY
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
MDB_INTEGERKEY
#endif
))
txn
->
mt_dbxs
[
dbi
].
md_cmp
=
memnrcmp
;
else
txn
->
mt_dbxs
[
dbi
].
md_cmp
=
memncmp
;
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
MDB_DUPSORT
)
{
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
MDB_INTEGERDUP
)
{
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
MDB_DUPFIXED
)
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
intcmp
;
else
#if __BYTE_ORDER == __LITTLE_ENDIAN
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
memnrcmp
;
#else
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
memncmp
;
#endif
}
else
if
(
txn
->
mt_dbs
[
dbi
].
md_flags
&
MDB_REVERSEDUP
)
{
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
memnrcmp
;
}
else
{
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
memncmp
;
}
}
else
{
txn
->
mt_dbxs
[
dbi
].
md_dcmp
=
NULL
;
}
}
int
mdb_open
(
MDB_txn
*
txn
,
const
char
*
name
,
unsigned
int
flags
,
MDB_dbi
*
dbi
)
{
MDB_val
key
,
data
;
...
...
@@ -4450,14 +4499,23 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
int
rc
,
dirty
=
0
;
size_t
len
;
if
(
txn
->
mt_dbxs
[
FREE_DBI
].
md_cmp
==
NULL
)
{
mdb_default_cmp
(
txn
,
FREE_DBI
);
}
/* main DB? */
if
(
!
name
)
{
*
dbi
=
MAIN_DBI
;
if
(
flags
&
(
MDB_DUPSORT
|
MDB_REVERSEKEY
|
MDB_INTEGERKEY
))
txn
->
mt_dbs
[
MAIN_DBI
].
md_flags
|=
(
flags
&
(
MDB_DUPSORT
|
MDB_REVERSEKEY
|
MDB_INTEGERKEY
));
mdb_default_cmp
(
txn
,
MAIN_DBI
);
return
MDB_SUCCESS
;
}
if
(
txn
->
mt_dbxs
[
MAIN_DBI
].
md_cmp
==
NULL
)
{
mdb_default_cmp
(
txn
,
MAIN_DBI
);
}
/* Is the DB already open? */
len
=
strlen
(
name
);
for
(
i
=
2
;
i
<
txn
->
mt_numdbs
;
i
++
)
{
...
...
@@ -4496,8 +4554,6 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
if
(
rc
==
MDB_SUCCESS
)
{
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_name
.
mv_data
=
strdup
(
name
);
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_name
.
mv_size
=
len
;
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_cmp
=
NULL
;
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_dcmp
=
NULL
;
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_rel
=
NULL
;
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_parent
=
MAIN_DBI
;
txn
->
mt_dbxs
[
txn
->
mt_numdbs
].
md_dirty
=
dirty
;
...
...
@@ -4505,6 +4561,7 @@ int mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
*
dbi
=
txn
->
mt_numdbs
;
txn
->
mt_env
->
me_dbs
[
0
][
txn
->
mt_numdbs
]
=
txn
->
mt_dbs
[
txn
->
mt_numdbs
];
txn
->
mt_env
->
me_dbs
[
1
][
txn
->
mt_numdbs
]
=
txn
->
mt_dbs
[
txn
->
mt_numdbs
];
mdb_default_cmp
(
txn
,
txn
->
mt_numdbs
);
txn
->
mt_numdbs
++
;
}
...
...
libraries/libmdb/mdb.h
View file @
70a4f6f2
...
...
@@ -157,6 +157,8 @@ typedef void (MDB_rel_func)(void *newptr, void *oldptr, size_t size);
#define MDB_DUPFIXED 0x10
/** with #MDB_DUPSORT, dups are numeric in native byte order */
#define MDB_INTEGERDUP 0x20
/** with #MDB_DUPSORT, use reverse string dups */
#define MDB_REVERSEDUP 0x40
/** create DB if not already existing */
#define MDB_CREATE 0x40000
/** @} */
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment