Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
a8cacc54
Commit
a8cacc54
authored
May 25, 2014
by
John Esmet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
FT-248 Remove dead code from tools/
parent
53d281eb
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
247 additions
and
1979 deletions
+247
-1979
tools/CMakeLists.txt
tools/CMakeLists.txt
+1
-3
tools/parseTraceFiles.py
tools/parseTraceFiles.py
+0
-82
tools/tokudb_common.h
tools/tokudb_common.h
+0
-107
tools/tokudb_common_funcs.h
tools/tokudb_common_funcs.h
+0
-335
tools/tokudb_dump.cc
tools/tokudb_dump.cc
+246
-4
tools/tokudb_gen.cc
tools/tokudb_gen.cc
+0
-471
tools/tokudb_load.cc
tools/tokudb_load.cc
+0
-977
No files found.
tools/CMakeLists.txt
View file @
a8cacc54
set_property
(
DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE DONT_DEPRECATE_ERRNO
)
set
(
utils tokudb_
gen tokudb_load tokudb_
dump
)
set
(
utils tokudb_dump
)
foreach
(
util
${
utils
}
)
add_executable
(
${
util
}
${
util
}
)
set_target_properties
(
${
util
}
PROPERTIES
COMPILE_DEFINITIONS
"IS_TDB=1;USE_TDB=1;TDB_IS_STATIC=1"
)
target_link_libraries
(
${
util
}
${
LIBTOKUDB
}
_static ft_static z lzma
${
LIBTOKUPORTABILITY
}
_static
${
CMAKE_THREAD_LIBS_INIT
}
${
EXTRA_SYSTEM_LIBS
}
)
add_space_separated_property
(
TARGET
${
util
}
COMPILE_FLAGS -fvisibility=hidden
)
...
...
tools/parseTraceFiles.py
deleted
100755 → 0
View file @
53d281eb
#!/usr/bin/env python
import
sys
try
:
data
=
open
(
sys
.
argv
[
1
])
except
:
print
"Could not open '%s'"
%
(
sys
.
argv
[
1
][
0
])
exit
(
0
)
ts_factor
=
1.
ts_prev
=
0.
threadlist
=
[]
for
line
in
data
:
line
=
line
.
rstrip
(
"
\
n
"
)
vals
=
line
.
split
()
[
n
,
tid
,
ts
,
funcline
]
=
vals
[
0
:
4
]
# 'note' is all text following funcline
note
=
''
for
v
in
vals
[
4
:
-
1
]:
note
+=
v
+
' '
note
+=
vals
[
-
1
]
if
(
note
==
'calibrate done'
):
ts_factor
=
float
(
ts
)
-
ts_prev
print
"Factor = "
,
ts_factor
,
"("
+
str
(
ts_factor
/
1000000000
)[
0
:
4
]
+
"GHz)"
time
=
(
float
(
ts
)
-
ts_prev
)
/
ts_factor
# create a list of threads
# - each thread has a list of <note,time> pairs, where time is the accumulated time for that note
# - search threadlist for thread_id (tid)
# - if found, search corresponding list of <note,time> pairs for the current note
# - if found, update (+=) the time
# - if not found, create a new <note,time> pair
# - if not found, create a new thread,<note,time> entry
found_thread
=
0
for
thread
in
threadlist
:
if
tid
==
thread
[
0
]:
found_thread
=
1
notetimelist
=
thread
[
1
]
found_note
=
0
for
notetime
in
notetimelist
:
if
note
==
notetime
[
0
]:
found_note
=
1
notetime
[
1
]
+=
time
break
if
found_note
==
0
:
thread
[
1
].
append
([
note
,
time
])
break
if
found_thread
==
0
:
notetime
=
[]
notetime
.
append
([
note
,
time
])
threadlist
.
append
([
tid
,
notetime
])
ts_prev
=
float
(
ts
)
# trim out unneeded
for
thread
in
threadlist
:
trimlist
=
[]
for
notetime
in
thread
[
1
]:
if
notetime
[
0
][
0
:
9
]
==
'calibrate'
:
trimlist
.
append
(
notetime
)
for
notetime
in
trimlist
:
thread
[
1
].
remove
(
notetime
)
print
''
# sum times to calculate percent (of 100)
total_time
=
0
for
thread
in
threadlist
:
for
[
note
,
time
]
in
thread
[
1
]:
total_time
+=
time
print
' thread operation time(sec) percent'
for
thread
in
threadlist
:
print
'tid : %5s'
%
thread
[
0
]
for
[
note
,
time
]
in
thread
[
1
]:
print
' %20s %f %5d'
%
(
note
,
time
,
100.
*
time
/
total_time
)
tools/tokudb_common.h
deleted
100644 → 0
View file @
53d281eb
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
/*
COPYING CONDITIONS NOTICE:
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation, and provided that the
following conditions are met:
* Redistributions of source code must retain this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below).
* Redistributions in binary form must reproduce this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below) in the documentation and/or other materials
provided with the distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
COPYRIGHT NOTICE:
TokuDB, Tokutek Fractal Tree Indexing Library.
Copyright (C) 2007-2013 Tokutek, Inc.
DISCLAIMER:
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
UNIVERSITY PATENT NOTICE:
The technology is licensed by the Massachusetts Institute of
Technology, Rutgers State University of New Jersey, and the Research
Foundation of State University of New York at Stony Brook under
United States of America Serial No. 11/760379 and to the patents
and/or patent applications resulting from it.
PATENT MARKING NOTICE:
This software is covered by US Patent No. 8,185,551.
This software is covered by US Patent No. 8,489,638.
PATENT RIGHTS GRANT:
"THIS IMPLEMENTATION" means the copyrightable works distributed by
Tokutek as part of the Fractal Tree project.
"PATENT CLAIMS" means the claims of patents that are owned or
licensable by Tokutek, both currently or in the future; and that in
the absence of this license would be infringed by THIS
IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
"PATENT CHALLENGE" shall mean a challenge to the validity,
patentability, enforceability and/or non-infringement of any of the
PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
Tokutek hereby grants to you, for the term and geographical scope of
the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to
make, have made, use, offer to sell, sell, import, transfer, and
otherwise run, modify, and propagate the contents of THIS
IMPLEMENTATION, where such license applies only to the PATENT
CLAIMS. This grant does not include claims that would be infringed
only as a consequence of further modifications of THIS
IMPLEMENTATION. If you or your agent or licensee institute or order
or agree to the institution of patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that
THIS IMPLEMENTATION constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any rights
granted to you under this License shall terminate as of the date
such litigation is filed. If you or your agent or exclusive
licensee institute or order or agree to the institution of a PATENT
CHALLENGE, then Tokutek may terminate any rights granted to you
under this License.
*/
#pragma once
#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <db.h>
#include <inttypes.h>
#include <signal.h>
#include <memory.h>
#define SET_BITS(bitvector, bits) ((bitvector) |= (bits))
#define REMOVE_BITS(bitvector, bits) ((bitvector) &= ~(bits))
#define IS_SET_ANY(bitvector, bits) ((bitvector) & (bits))
#define IS_SET_ALL(bitvector, bits) (((bitvector) & (bits)) == (bits))
#define IS_POWER_OF_2(num) ((num) > 0 && ((num) & ((num) - 1)) == 0)
tools/tokudb_common_funcs.h
deleted
100644 → 0
View file @
53d281eb
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
/*
COPYING CONDITIONS NOTICE:
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation, and provided that the
following conditions are met:
* Redistributions of source code must retain this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below).
* Redistributions in binary form must reproduce this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below) in the documentation and/or other materials
provided with the distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
COPYRIGHT NOTICE:
TokuDB, Tokutek Fractal Tree Indexing Library.
Copyright (C) 2007-2013 Tokutek, Inc.
DISCLAIMER:
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
UNIVERSITY PATENT NOTICE:
The technology is licensed by the Massachusetts Institute of
Technology, Rutgers State University of New Jersey, and the Research
Foundation of State University of New York at Stony Brook under
United States of America Serial No. 11/760379 and to the patents
and/or patent applications resulting from it.
PATENT MARKING NOTICE:
This software is covered by US Patent No. 8,185,551.
This software is covered by US Patent No. 8,489,638.
PATENT RIGHTS GRANT:
"THIS IMPLEMENTATION" means the copyrightable works distributed by
Tokutek as part of the Fractal Tree project.
"PATENT CLAIMS" means the claims of patents that are owned or
licensable by Tokutek, both currently or in the future; and that in
the absence of this license would be infringed by THIS
IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
"PATENT CHALLENGE" shall mean a challenge to the validity,
patentability, enforceability and/or non-infringement of any of the
PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
Tokutek hereby grants to you, for the term and geographical scope of
the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to
make, have made, use, offer to sell, sell, import, transfer, and
otherwise run, modify, and propagate the contents of THIS
IMPLEMENTATION, where such license applies only to the PATENT
CLAIMS. This grant does not include claims that would be infringed
only as a consequence of further modifications of THIS
IMPLEMENTATION. If you or your agent or licensee institute or order
or agree to the institution of patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that
THIS IMPLEMENTATION constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any rights
granted to you under this License shall terminate as of the date
such litigation is filed. If you or your agent or exclusive
licensee institute or order or agree to the institution of a PATENT
CHALLENGE, then Tokutek may terminate any rights granted to you
under this License.
*/
#pragma once
#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
#include "tokudb_common.h"
//DB_ENV->err disabled since it does not use db_strerror
#define PRINT_ERROR(retval, ...) \
do { \
if (0) g.dbenv->err(g.dbenv, retval, __VA_ARGS__); \
else { \
fprintf(stderr, "\tIn %s:%d %s()\n", __FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, "%s: %s:", g.progname, db_strerror(retval)); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
} \
} while (0)
//DB_ENV->err disabled since it does not use db_strerror, errx does not exist.
#define PRINT_ERRORX(...) \
do { \
if (0) g.dbenv->err(g.dbenv, 0, __VA_ARGS__); \
else { \
fprintf(stderr, "\tIn %s:%d %s()\n", __FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, "%s: ", g.progname); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
} \
} while (0)
int
strtoint32
(
char
*
str
,
int32_t
*
num
,
int32_t
min
,
int32_t
max
,
int
base
);
int
strtouint32
(
char
*
str
,
uint32_t
*
num
,
uint32_t
min
,
uint32_t
max
,
int
base
);
int
strtoint64
(
char
*
str
,
int64_t
*
num
,
int64_t
min
,
int64_t
max
,
int
base
);
int
strtouint64
(
char
*
str
,
uint64_t
*
num
,
uint64_t
min
,
uint64_t
max
,
int
base
);
/*
* Convert a string to an integer of type "type".
*
*
* Sets errno and returns:
* EINVAL: str == NULL, num == NULL, or string not of the form [ \t]*[+-]?[0-9]+
* ERANGE: value out of range specified. (Range of [min, max])
*
* *num is unchanged on error.
* Returns:
*
*/
#define DEF_STR_TO(name, type, bigtype, strtofunc, frmt) \
int name(char* str, type* num, type min, type max, int base) \
{ \
char* test; \
bigtype value; \
\
assert(str); \
assert(num); \
assert(min <= max); \
assert(g.dbenv || g.progname); \
assert(base == 0 || (base >= 2 && base <= 36)); \
\
errno = 0; \
while (isspace(*str)) str++; \
value = strtofunc(str, &test, base); \
if ((*test != '\0' && *test != '\n') || test == str) { \
PRINT_ERRORX("%s: Invalid numeric argument\n", str); \
errno = EINVAL; \
goto error; \
} \
if (errno != 0) { \
PRINT_ERROR(errno, "%s\n", str); \
} \
if (value < min) { \
PRINT_ERRORX("%s: Less than minimum value (%" frmt ")\n", str, min); \
goto error; \
} \
if (value > max) { \
PRINT_ERRORX("%s: Greater than maximum value (%" frmt ")\n", str, max); \
goto error; \
} \
*num = value; \
return EXIT_SUCCESS; \
error: \
return errno; \
}
DEF_STR_TO
(
strtoint32
,
int32_t
,
int64_t
,
strtoll
,
PRId32
)
DEF_STR_TO
(
strtouint32
,
uint32_t
,
uint64_t
,
strtoull
,
PRIu32
)
DEF_STR_TO
(
strtoint64
,
int64_t
,
int64_t
,
strtoll
,
PRId64
)
DEF_STR_TO
(
strtouint64
,
uint64_t
,
uint64_t
,
strtoull
,
PRIu64
)
static
inline
void
outputbyte
(
uint8_t
ch
)
{
if
(
g
.
plaintext
)
{
if
(
ch
==
'\\'
)
printf
(
"
\\\\
"
);
else
if
(
isprint
(
ch
))
printf
(
"%c"
,
ch
);
else
printf
(
"
\\
%02x"
,
ch
);
}
else
printf
(
"%02x"
,
ch
);
}
static
inline
void
outputstring
(
char
*
str
)
{
char
*
p
;
for
(
p
=
str
;
*
p
!=
'\0'
;
p
++
)
{
outputbyte
((
uint8_t
)
*
p
);
}
}
static
inline
void
outputplaintextstring
(
char
*
str
)
{
bool
old_plaintext
=
g
.
plaintext
;
g
.
plaintext
=
true
;
outputstring
(
str
);
g
.
plaintext
=
old_plaintext
;
}
static
inline
int
hextoint
(
int
ch
)
{
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
return
ch
-
'0'
;
}
if
(
ch
>=
'a'
&&
ch
<=
'z'
)
{
return
ch
-
'a'
+
10
;
}
if
(
ch
>=
'A'
&&
ch
<=
'Z'
)
{
return
ch
-
'A'
+
10
;
}
return
EOF
;
}
static
inline
int
printabletocstring
(
char
*
inputstr
,
char
**
poutputstr
)
{
char
highch
;
char
lowch
;
char
nextch
;
char
*
cstring
;
assert
(
inputstr
);
assert
(
poutputstr
);
assert
(
*
poutputstr
==
NULL
);
cstring
=
(
char
*
)
toku_malloc
((
strlen
(
inputstr
)
+
1
)
*
sizeof
(
char
));
if
(
cstring
==
NULL
)
{
PRINT_ERROR
(
errno
,
"printabletocstring"
);
goto
error
;
}
for
(
*
poutputstr
=
cstring
;
*
inputstr
!=
'\0'
;
inputstr
++
)
{
if
(
*
inputstr
==
'\\'
)
{
if
((
highch
=
*++
inputstr
)
==
'\\'
)
{
*
cstring
++
=
'\\'
;
continue
;
}
if
(
highch
==
'\0'
||
(
lowch
=
*++
inputstr
)
==
'\0'
)
{
PRINT_ERROR
(
0
,
"unexpected end of input data or key/data pair"
);
goto
error
;
}
if
(
!
isxdigit
(
highch
))
{
PRINT_ERROR
(
0
,
"Unexpected '%c' (non-hex) input.
\n
"
,
highch
);
goto
error
;
}
if
(
!
isxdigit
(
lowch
))
{
PRINT_ERROR
(
0
,
"Unexpected '%c' (non-hex) input.
\n
"
,
lowch
);
goto
error
;
}
nextch
=
(
char
)((
hextoint
(
highch
)
<<
4
)
|
hextoint
(
lowch
));
if
(
nextch
==
'\0'
)
{
/* Database names are c strings, and cannot have extra NULL terminators. */
PRINT_ERROR
(
0
,
"Unexpected '
\\
00' in input.
\n
"
);
goto
error
;
}
*
cstring
++
=
nextch
;
}
else
*
cstring
++
=
*
inputstr
;
}
/* Terminate the string. */
*
cstring
=
'\0'
;
return
EXIT_SUCCESS
;
error:
PRINT_ERROR
(
0
,
"Quitting out due to errors.
\n
"
);
return
EXIT_FAILURE
;
}
static
inline
int
verify_library_version
(
void
)
{
int
major
;
int
minor
;
db_version
(
&
major
,
&
minor
,
NULL
);
if
(
major
!=
DB_VERSION_MAJOR
||
minor
!=
DB_VERSION_MINOR
)
{
PRINT_ERRORX
(
"version %d.%d doesn't match library version %d.%d
\n
"
,
DB_VERSION_MAJOR
,
DB_VERSION_MINOR
,
major
,
minor
);
return
EXIT_FAILURE
;
}
return
EXIT_SUCCESS
;
}
static
int
last_caught
=
0
;
static
void
catch_signal
(
int
which_signal
)
{
last_caught
=
which_signal
;
if
(
last_caught
==
0
)
last_caught
=
SIGINT
;
}
static
inline
void
init_catch_signals
(
void
)
{
signal
(
SIGINT
,
catch_signal
);
signal
(
SIGTERM
,
catch_signal
);
#ifdef SIGHUP
signal
(
SIGHUP
,
catch_signal
);
#endif
#ifdef SIGPIPE
signal
(
SIGPIPE
,
catch_signal
);
#endif
}
static
inline
int
caught_any_signals
(
void
)
{
return
last_caught
!=
0
;
}
static
inline
void
resend_signals
(
void
)
{
if
(
last_caught
)
{
signal
(
last_caught
,
SIG_DFL
);
raise
(
last_caught
);
}
}
#include <memory.h>
static
int
test_main
(
int
argc
,
char
*
const
argv
[]);
int
main
(
int
argc
,
char
*
const
argv
[])
{
int
r
;
r
=
test_main
(
argc
,
argv
);
return
r
;
}
tools/tokudb_dump.cc
View file @
a8cacc54
...
...
@@ -88,6 +88,10 @@ PATENT RIGHTS GRANT:
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <db.h>
#include <toku_stdlib.h>
#include <toku_stdint.h>
#include <toku_portability.h>
#include <toku_assert.h>
#include <stdio.h>
...
...
@@ -97,8 +101,8 @@ PATENT RIGHTS GRANT:
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <
db
.h>
#include
"tokudb_common.h"
#include <
signal
.h>
#include
<memory.h>
typedef
struct
{
bool
leadingspace
;
...
...
@@ -120,7 +124,245 @@ typedef struct {
}
dump_globals
;
dump_globals
g
;
#include "tokudb_common_funcs.h"
#define SET_BITS(bitvector, bits) ((bitvector) |= (bits))
#define REMOVE_BITS(bitvector, bits) ((bitvector) &= ~(bits))
#define IS_SET_ANY(bitvector, bits) ((bitvector) & (bits))
#define IS_SET_ALL(bitvector, bits) (((bitvector) & (bits)) == (bits))
#define IS_POWER_OF_2(num) ((num) > 0 && ((num) & ((num) - 1)) == 0)
//DB_ENV->err disabled since it does not use db_strerror
#define PRINT_ERROR(retval, ...) \
do { \
if (0) g.dbenv->err(g.dbenv, retval, __VA_ARGS__); \
else { \
fprintf(stderr, "\tIn %s:%d %s()\n", __FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, "%s: %s:", g.progname, db_strerror(retval)); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
} \
} while (0)
//DB_ENV->err disabled since it does not use db_strerror, errx does not exist.
#define PRINT_ERRORX(...) \
do { \
if (0) g.dbenv->err(g.dbenv, 0, __VA_ARGS__); \
else { \
fprintf(stderr, "\tIn %s:%d %s()\n", __FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, "%s: ", g.progname); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
} \
} while (0)
int
strtoint32
(
char
*
str
,
int32_t
*
num
,
int32_t
min
,
int32_t
max
,
int
base
);
int
strtouint32
(
char
*
str
,
uint32_t
*
num
,
uint32_t
min
,
uint32_t
max
,
int
base
);
int
strtoint64
(
char
*
str
,
int64_t
*
num
,
int64_t
min
,
int64_t
max
,
int
base
);
int
strtouint64
(
char
*
str
,
uint64_t
*
num
,
uint64_t
min
,
uint64_t
max
,
int
base
);
/*
* Convert a string to an integer of type "type".
*
*
* Sets errno and returns:
* EINVAL: str == NULL, num == NULL, or string not of the form [ \t]*[+-]?[0-9]+
* ERANGE: value out of range specified. (Range of [min, max])
*
* *num is unchanged on error.
* Returns:
*
*/
#define DEF_STR_TO(name, type, bigtype, strtofunc, frmt) \
int name(char* str, type* num, type min, type max, int base) \
{ \
char* test; \
bigtype value; \
\
assert(str); \
assert(num); \
assert(min <= max); \
assert(g.dbenv || g.progname); \
assert(base == 0 || (base >= 2 && base <= 36)); \
\
errno = 0; \
while (isspace(*str)) str++; \
value = strtofunc(str, &test, base); \
if ((*test != '\0' && *test != '\n') || test == str) { \
PRINT_ERRORX("%s: Invalid numeric argument\n", str); \
errno = EINVAL; \
goto error; \
} \
if (errno != 0) { \
PRINT_ERROR(errno, "%s\n", str); \
} \
if (value < min) { \
PRINT_ERRORX("%s: Less than minimum value (%" frmt ")\n", str, min); \
goto error; \
} \
if (value > max) { \
PRINT_ERRORX("%s: Greater than maximum value (%" frmt ")\n", str, max); \
goto error; \
} \
*num = value; \
return EXIT_SUCCESS; \
error: \
return errno; \
}
DEF_STR_TO
(
strtoint32
,
int32_t
,
int64_t
,
strtoll
,
PRId32
)
DEF_STR_TO
(
strtouint32
,
uint32_t
,
uint64_t
,
strtoull
,
PRIu32
)
DEF_STR_TO
(
strtoint64
,
int64_t
,
int64_t
,
strtoll
,
PRId64
)
DEF_STR_TO
(
strtouint64
,
uint64_t
,
uint64_t
,
strtoull
,
PRIu64
)
static
inline
void
outputbyte
(
uint8_t
ch
)
{
if
(
g
.
plaintext
)
{
if
(
ch
==
'\\'
)
printf
(
"
\\\\
"
);
else
if
(
isprint
(
ch
))
printf
(
"%c"
,
ch
);
else
printf
(
"
\\
%02x"
,
ch
);
}
else
printf
(
"%02x"
,
ch
);
}
static
inline
void
outputstring
(
char
*
str
)
{
char
*
p
;
for
(
p
=
str
;
*
p
!=
'\0'
;
p
++
)
{
outputbyte
((
uint8_t
)
*
p
);
}
}
static
inline
void
outputplaintextstring
(
char
*
str
)
{
bool
old_plaintext
=
g
.
plaintext
;
g
.
plaintext
=
true
;
outputstring
(
str
);
g
.
plaintext
=
old_plaintext
;
}
static
inline
int
hextoint
(
int
ch
)
{
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
return
ch
-
'0'
;
}
if
(
ch
>=
'a'
&&
ch
<=
'z'
)
{
return
ch
-
'a'
+
10
;
}
if
(
ch
>=
'A'
&&
ch
<=
'Z'
)
{
return
ch
-
'A'
+
10
;
}
return
EOF
;
}
static
inline
int
printabletocstring
(
char
*
inputstr
,
char
**
poutputstr
)
{
char
highch
;
char
lowch
;
char
nextch
;
char
*
cstring
;
assert
(
inputstr
);
assert
(
poutputstr
);
assert
(
*
poutputstr
==
NULL
);
cstring
=
(
char
*
)
toku_malloc
((
strlen
(
inputstr
)
+
1
)
*
sizeof
(
char
));
if
(
cstring
==
NULL
)
{
PRINT_ERROR
(
errno
,
"printabletocstring"
);
goto
error
;
}
for
(
*
poutputstr
=
cstring
;
*
inputstr
!=
'\0'
;
inputstr
++
)
{
if
(
*
inputstr
==
'\\'
)
{
if
((
highch
=
*++
inputstr
)
==
'\\'
)
{
*
cstring
++
=
'\\'
;
continue
;
}
if
(
highch
==
'\0'
||
(
lowch
=
*++
inputstr
)
==
'\0'
)
{
PRINT_ERROR
(
0
,
"unexpected end of input data or key/data pair"
);
goto
error
;
}
if
(
!
isxdigit
(
highch
))
{
PRINT_ERROR
(
0
,
"Unexpected '%c' (non-hex) input.
\n
"
,
highch
);
goto
error
;
}
if
(
!
isxdigit
(
lowch
))
{
PRINT_ERROR
(
0
,
"Unexpected '%c' (non-hex) input.
\n
"
,
lowch
);
goto
error
;
}
nextch
=
(
char
)((
hextoint
(
highch
)
<<
4
)
|
hextoint
(
lowch
));
if
(
nextch
==
'\0'
)
{
/* Database names are c strings, and cannot have extra NULL terminators. */
PRINT_ERROR
(
0
,
"Unexpected '
\\
00' in input.
\n
"
);
goto
error
;
}
*
cstring
++
=
nextch
;
}
else
*
cstring
++
=
*
inputstr
;
}
/* Terminate the string. */
*
cstring
=
'\0'
;
return
EXIT_SUCCESS
;
error:
PRINT_ERROR
(
0
,
"Quitting out due to errors.
\n
"
);
return
EXIT_FAILURE
;
}
static
inline
int
verify_library_version
(
void
)
{
int
major
;
int
minor
;
db_version
(
&
major
,
&
minor
,
NULL
);
if
(
major
!=
DB_VERSION_MAJOR
||
minor
!=
DB_VERSION_MINOR
)
{
PRINT_ERRORX
(
"version %d.%d doesn't match library version %d.%d
\n
"
,
DB_VERSION_MAJOR
,
DB_VERSION_MINOR
,
major
,
minor
);
return
EXIT_FAILURE
;
}
return
EXIT_SUCCESS
;
}
static
int
last_caught
=
0
;
static
void
catch_signal
(
int
which_signal
)
{
last_caught
=
which_signal
;
if
(
last_caught
==
0
)
last_caught
=
SIGINT
;
}
static
inline
void
init_catch_signals
(
void
)
{
signal
(
SIGINT
,
catch_signal
);
signal
(
SIGTERM
,
catch_signal
);
#ifdef SIGHUP
signal
(
SIGHUP
,
catch_signal
);
#endif
#ifdef SIGPIPE
signal
(
SIGPIPE
,
catch_signal
);
#endif
}
static
inline
int
caught_any_signals
(
void
)
{
return
last_caught
!=
0
;
}
static
inline
void
resend_signals
(
void
)
{
if
(
last_caught
)
{
signal
(
last_caught
,
SIG_DFL
);
raise
(
last_caught
);
}
}
static
int
usage
(
void
);
static
int
create_init_env
(
void
);
...
...
@@ -131,7 +373,7 @@ static int dump_footer (void);
static
int
dump_header
(
void
);
static
int
close_database
(
void
);
int
test_
main
(
int
argc
,
char
*
const
argv
[])
{
int
main
(
int
argc
,
char
*
const
argv
[])
{
int
ch
;
int
retval
;
...
...
tools/tokudb_gen.cc
deleted
100644 → 0
View file @
53d281eb
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
/*
COPYING CONDITIONS NOTICE:
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation, and provided that the
following conditions are met:
* Redistributions of source code must retain this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below).
* Redistributions in binary form must reproduce this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below) in the documentation and/or other materials
provided with the distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
COPYRIGHT NOTICE:
TokuDB, Tokutek Fractal Tree Indexing Library.
Copyright (C) 2007-2013 Tokutek, Inc.
DISCLAIMER:
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
UNIVERSITY PATENT NOTICE:
The technology is licensed by the Massachusetts Institute of
Technology, Rutgers State University of New Jersey, and the Research
Foundation of State University of New York at Stony Brook under
United States of America Serial No. 11/760379 and to the patents
and/or patent applications resulting from it.
PATENT MARKING NOTICE:
This software is covered by US Patent No. 8,185,551.
This software is covered by US Patent No. 8,489,638.
PATENT RIGHTS GRANT:
"THIS IMPLEMENTATION" means the copyrightable works distributed by
Tokutek as part of the Fractal Tree project.
"PATENT CLAIMS" means the claims of patents that are owned or
licensable by Tokutek, both currently or in the future; and that in
the absence of this license would be infringed by THIS
IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
"PATENT CHALLENGE" shall mean a challenge to the validity,
patentability, enforceability and/or non-infringement of any of the
PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
Tokutek hereby grants to you, for the term and geographical scope of
the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to
make, have made, use, offer to sell, sell, import, transfer, and
otherwise run, modify, and propagate the contents of THIS
IMPLEMENTATION, where such license applies only to the PATENT
CLAIMS. This grant does not include claims that would be infringed
only as a consequence of further modifications of THIS
IMPLEMENTATION. If you or your agent or licensee institute or order
or agree to the institution of patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that
THIS IMPLEMENTATION constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any rights
granted to you under this License shall terminate as of the date
such litigation is filed. If you or your agent or exclusive
licensee institute or order or agree to the institution of a PATENT
CHALLENGE, then Tokutek may terminate any rights granted to you
under this License.
*/
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <toku_portability.h>
#include <toku_assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <db.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <src/ydb.h>
#include "tokudb_common.h"
typedef
struct
{
DB_ENV
*
dbenv
;
bool
plaintext
;
char
*
progname
;
}
gen_globals
;
gen_globals
g
;
#include "tokudb_common_funcs.h"
static
int
usage
(
void
);
static
void
generate_keys
(
void
);
static
int
get_delimiter
(
char
*
str
);
char
dbt_delimiter
=
'\n'
;
char
sort_delimiter
[
3
];
uint32_t
lengthmin
=
0
;
bool
set_lengthmin
=
false
;
uint32_t
lengthlimit
=
0
;
bool
set_lengthlimit
=
false
;
uint64_t
numkeys
=
0
;
bool
set_numkeys
=
false
;
bool
header
=
true
;
bool
footer
=
true
;
bool
justheader
=
false
;
bool
justfooter
=
false
;
bool
outputkeys
=
true
;
uint32_t
seed
=
1
;
bool
set_seed
=
false
;
bool
printableonly
=
false
;
bool
leadingspace
=
true
;
bool
force_unique
=
true
;
bool
dupsort
=
false
;
static
int
test_main
(
int
argc
,
char
*
const
argv
[])
{
int
ch
;
/* Set up the globals. */
memset
(
&
g
,
0
,
sizeof
(
g
));
g
.
progname
=
argv
[
0
];
if
(
verify_library_version
()
!=
0
)
goto
error
;
strcpy
(
sort_delimiter
,
""
);
while
((
ch
=
getopt
(
argc
,
argv
,
"PpTo:r:m:M:n:uVhHfFd:s:DS"
))
!=
EOF
)
{
switch
(
ch
)
{
case
(
'P'
):
{
printableonly
=
true
;
break
;
}
case
(
'p'
):
{
g
.
plaintext
=
true
;
leadingspace
=
true
;
break
;
}
case
(
'T'
):
{
g
.
plaintext
=
true
;
leadingspace
=
false
;
header
=
false
;
footer
=
false
;
break
;
}
case
(
'o'
):
{
if
(
freopen
(
optarg
,
"w"
,
stdout
)
==
NULL
)
{
PRINT_ERROR
(
errno
,
"%s: reopen
\n
"
,
optarg
);
goto
error
;
}
break
;
}
case
(
'r'
):
{
if
(
strtouint32
(
optarg
,
&
seed
,
0
,
UINT32_MAX
,
10
))
{
PRINT_ERRORX
(
"%s: (-r) Random seed invalid."
,
optarg
);
goto
error
;
}
set_seed
=
true
;
break
;
}
case
(
'm'
):
{
if
(
strtouint32
(
optarg
,
&
lengthmin
,
0
,
UINT32_MAX
,
10
))
{
PRINT_ERRORX
(
"%s: (-m) Min length of keys/values invalid."
,
optarg
);
goto
error
;
}
set_lengthmin
=
true
;
break
;
}
case
(
'M'
):
{
if
(
strtouint32
(
optarg
,
&
lengthlimit
,
1
,
UINT32_MAX
,
10
))
{
PRINT_ERRORX
(
"%s: (-M) Limit of key/value length invalid."
,
optarg
);
goto
error
;
}
set_lengthlimit
=
true
;
break
;
}
case
(
'n'
):
{
if
(
strtouint64
(
optarg
,
&
numkeys
,
0
,
UINT64_MAX
,
10
))
{
PRINT_ERRORX
(
"%s: (-n) Number of keys to generate invalid."
,
optarg
);
goto
error
;
}
set_numkeys
=
true
;
break
;
}
case
(
'u'
):
{
force_unique
=
false
;
break
;
}
case
(
'h'
):
{
header
=
false
;
break
;
}
case
(
'H'
):
{
justheader
=
true
;
break
;
}
case
(
'f'
):
{
footer
=
false
;
break
;
}
case
(
'F'
):
{
justfooter
=
true
;
break
;
}
case
(
'd'
):
{
int
temp
=
get_delimiter
(
optarg
);
if
(
temp
==
EOF
)
{
PRINT_ERRORX
(
"%s: (-d) Key (or value) delimiter must be one character."
,
optarg
);
goto
error
;
}
if
(
isxdigit
(
temp
))
{
PRINT_ERRORX
(
"%c: (-d) Key (or value) delimiter cannot be a hex digit."
,
temp
);
goto
error
;
}
dbt_delimiter
=
(
char
)
temp
;
break
;
}
case
(
's'
):
{
int
temp
=
get_delimiter
(
optarg
);
if
(
temp
==
EOF
)
{
PRINT_ERRORX
(
"%s: (-s) Sorting (Between key/value pairs) delimiter must be one character."
,
optarg
);
goto
error
;
}
if
(
isxdigit
(
temp
))
{
PRINT_ERRORX
(
"%c: (-s) Sorting (Between key/value pairs) delimiter cannot be a hex digit."
,
temp
);
goto
error
;
}
sort_delimiter
[
0
]
=
(
char
)
temp
;
sort_delimiter
[
1
]
=
'\0'
;
break
;
}
case
(
'V'
):
{
printf
(
"%s
\n
"
,
db_version
(
NULL
,
NULL
,
NULL
));
return
EXIT_SUCCESS
;
}
case
'D'
:
{
fprintf
(
stderr
,
"Duplicates no longer supported by tokudb
\n
"
);
return
EXIT_FAILURE
;
}
case
'S'
:
{
fprintf
(
stderr
,
"Dupsort no longer supported by tokudb
\n
"
);
return
EXIT_FAILURE
;
}
case
(
'?'
):
default:
{
return
(
usage
());
}
}
}
argc
-=
optind
;
argv
+=
optind
;
if
(
justheader
&&
!
header
)
{
PRINT_ERRORX
(
"The -h and -H options may not both be specified.
\n
"
);
goto
error
;
}
if
(
justfooter
&&
!
footer
)
{
PRINT_ERRORX
(
"The -f and -F options may not both be specified.
\n
"
);
goto
error
;
}
if
(
justfooter
&&
justheader
)
{
PRINT_ERRORX
(
"The -H and -F options may not both be specified.
\n
"
);
goto
error
;
}
if
(
justfooter
&&
header
)
{
PRINT_ERRORX
(
"-F implies -h
\n
"
);
header
=
false
;
}
if
(
justheader
&&
footer
)
{
PRINT_ERRORX
(
"-H implies -f
\n
"
);
footer
=
false
;
}
if
(
!
leadingspace
)
{
if
(
footer
)
{
PRINT_ERRORX
(
"-p implies -f
\n
"
);
footer
=
false
;
}
if
(
header
)
{
PRINT_ERRORX
(
"-p implies -h
\n
"
);
header
=
false
;
}
}
if
(
justfooter
||
justheader
)
outputkeys
=
false
;
else
if
(
!
set_numkeys
)
{
PRINT_ERRORX
(
"Using default number of keys. (-n 1024).
\n
"
);
numkeys
=
1024
;
}
if
(
outputkeys
&&
!
set_seed
)
{
PRINT_ERRORX
(
"Using default seed. (-r 1).
\n
"
);
seed
=
1
;
}
if
(
outputkeys
&&
!
set_lengthmin
)
{
PRINT_ERRORX
(
"Using default lengthmin. (-m 0).
\n
"
);
lengthmin
=
0
;
}
if
(
outputkeys
&&
!
set_lengthlimit
)
{
PRINT_ERRORX
(
"Using default lengthlimit. (-M 1024).
\n
"
);
lengthlimit
=
1024
;
}
if
(
outputkeys
&&
lengthmin
>=
lengthlimit
)
{
PRINT_ERRORX
(
"Max key size must be greater than min key size.
\n
"
);
goto
error
;
}
if
(
argc
!=
0
)
{
return
usage
();
}
if
(
header
)
{
printf
(
"VERSION=3
\n
"
);
printf
(
"format=%s
\n
"
,
g
.
plaintext
?
"print"
:
"bytevalue"
);
printf
(
"type=btree
\n
"
);
// printf("db_pagesize=%d\n", 4096); //Don't write pagesize which would be useless.
if
(
dupsort
)
printf
(
"dupsort=%d
\n
"
,
dupsort
);
printf
(
"HEADER=END
\n
"
);
}
if
(
outputkeys
)
generate_keys
();
if
(
footer
)
printf
(
"DATA=END
\n
"
);
return
EXIT_SUCCESS
;
error:
fprintf
(
stderr
,
"Quitting out due to errors.
\n
"
);
return
EXIT_FAILURE
;
}
static
int
usage
()
{
fprintf
(
stderr
,
"usage: %s [-PpTuVhHfFDS] [-o output] [-r seed] [-m minsize] [-M limitsize]
\n
"
" %*s[-n numpairs] [-d delimiter] [-s delimiter]
\n
"
,
g
.
progname
,
(
int
)
strlen
(
g
.
progname
)
+
1
,
""
);
return
EXIT_FAILURE
;
}
static
uint8_t
randbyte
(
void
)
{
static
uint32_t
numsavedbits
=
0
;
static
uint64_t
savedbits
=
0
;
uint8_t
retval
;
if
(
numsavedbits
<
8
)
{
savedbits
|=
((
uint64_t
)
random
())
<<
numsavedbits
;
numsavedbits
+=
31
;
/* Random generates 31 random bits. */
}
retval
=
savedbits
&
0xff
;
numsavedbits
-=
8
;
savedbits
>>=
8
;
return
retval
;
}
/* Almost-uniformly random int from [0,limit) */
static
int32_t
random_below
(
int32_t
limit
)
{
assert
(
limit
>
0
);
return
random
()
%
limit
;
}
static
void
generate_keys
()
{
bool
usedemptykey
=
false
;
uint64_t
numgenerated
=
0
;
uint64_t
totalsize
=
0
;
char
identifier
[
24
];
/* 8 bytes * 2 = 16; 16+1=17; 17+null terminator = 18. Extra padding. */
int
length
;
int
i
;
uint8_t
ch
;
srandom
(
seed
);
while
(
numgenerated
<
numkeys
)
{
numgenerated
++
;
/* Each key is preceded by a space (unless using -T). */
if
(
leadingspace
)
printf
(
" "
);
/* Generate a key. */
{
/* Pick a key length. */
length
=
random_below
(
lengthlimit
-
lengthmin
)
+
lengthmin
;
/* Output 'length' random bytes. */
for
(
i
=
0
;
i
<
length
;
i
++
)
{
do
{
ch
=
randbyte
();}
while
(
printableonly
&&
!
isprint
(
ch
));
outputbyte
(
ch
);
}
totalsize
+=
length
;
if
(
force_unique
)
{
if
(
length
==
0
&&
!
usedemptykey
)
usedemptykey
=
true
;
else
{
/* Append identifier to ensure uniqueness. */
sprintf
(
identifier
,
"x%"
PRIx64
,
numgenerated
);
outputstring
(
identifier
);
totalsize
+=
strlen
(
identifier
);
}
}
}
printf
(
"%c"
,
dbt_delimiter
);
/* Each value is preceded by a space (unless using -T). */
if
(
leadingspace
)
printf
(
" "
);
/* Generate a value. */
{
/* Pick a key length. */
length
=
random_below
(
lengthlimit
-
lengthmin
)
+
lengthmin
;
/* Output 'length' random bytes. */
for
(
i
=
0
;
i
<
length
;
i
++
)
{
do
{
ch
=
randbyte
();}
while
(
printableonly
&&
!
isprint
(
ch
));
outputbyte
(
ch
);
}
totalsize
+=
length
;
}
printf
(
"%c"
,
dbt_delimiter
);
printf
(
"%s"
,
sort_delimiter
);
}
}
int
get_delimiter
(
char
*
str
)
{
if
(
strlen
(
str
)
==
2
&&
str
[
0
]
==
'\\'
)
{
switch
(
str
[
1
])
{
case
(
'a'
):
return
'\a'
;
case
(
'b'
):
return
'\b'
;
#ifndef __ICL
case
(
'e'
):
return
'\e'
;
#endif
case
(
'f'
):
return
'\f'
;
case
(
'n'
):
return
'\n'
;
case
(
'r'
):
return
'\r'
;
case
(
't'
):
return
'\t'
;
case
(
'v'
):
return
'\v'
;
case
(
'0'
):
return
'\0'
;
case
(
'\\'
):
return
'\\'
;
default:
return
EOF
;
}
}
if
(
strlen
(
str
)
==
1
)
return
str
[
0
];
return
EOF
;
}
tools/tokudb_load.cc
deleted
100644 → 0
View file @
53d281eb
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
/*
COPYING CONDITIONS NOTICE:
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation, and provided that the
following conditions are met:
* Redistributions of source code must retain this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below).
* Redistributions in binary form must reproduce this COPYING
CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
PATENT MARKING NOTICE (below), and the PATENT RIGHTS
GRANT (below) in the documentation and/or other materials
provided with the distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
COPYRIGHT NOTICE:
TokuDB, Tokutek Fractal Tree Indexing Library.
Copyright (C) 2007-2013 Tokutek, Inc.
DISCLAIMER:
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
UNIVERSITY PATENT NOTICE:
The technology is licensed by the Massachusetts Institute of
Technology, Rutgers State University of New Jersey, and the Research
Foundation of State University of New York at Stony Brook under
United States of America Serial No. 11/760379 and to the patents
and/or patent applications resulting from it.
PATENT MARKING NOTICE:
This software is covered by US Patent No. 8,185,551.
This software is covered by US Patent No. 8,489,638.
PATENT RIGHTS GRANT:
"THIS IMPLEMENTATION" means the copyrightable works distributed by
Tokutek as part of the Fractal Tree project.
"PATENT CLAIMS" means the claims of patents that are owned or
licensable by Tokutek, both currently or in the future; and that in
the absence of this license would be infringed by THIS
IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
"PATENT CHALLENGE" shall mean a challenge to the validity,
patentability, enforceability and/or non-infringement of any of the
PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
Tokutek hereby grants to you, for the term and geographical scope of
the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to
make, have made, use, offer to sell, sell, import, transfer, and
otherwise run, modify, and propagate the contents of THIS
IMPLEMENTATION, where such license applies only to the PATENT
CLAIMS. This grant does not include claims that would be infringed
only as a consequence of further modifications of THIS
IMPLEMENTATION. If you or your agent or licensee institute or order
or agree to the institution of patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that
THIS IMPLEMENTATION constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any rights
granted to you under this License shall terminate as of the date
such litigation is filed. If you or your agent or exclusive
licensee institute or order or agree to the institution of a PATENT
CHALLENGE, then Tokutek may terminate any rights granted to you
under this License.
*/
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <toku_portability.h>
#include <toku_assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <db.h>
#include "tokudb_common.h"
typedef
struct
{
bool
leadingspace
;
bool
plaintext
;
bool
overwritekeys
;
bool
header
;
bool
eof
;
bool
keys
;
bool
is_private
;
char
*
progname
;
char
*
homedir
;
char
*
database
;
char
*
subdatabase
;
char
**
config_options
;
int32_t
version
;
int
exitcode
;
uint64_t
linenumber
;
DBTYPE
dbtype
;
DB
*
db
;
DB_ENV
*
dbenv
;
struct
{
char
*
data
[
2
];
}
get_dbt
;
struct
{
char
*
data
;
}
read_header
;
}
load_globals
;
load_globals
g
;
#include "tokudb_common_funcs.h"
static
int
usage
(
void
);
static
int
load_database
(
void
);
static
int
create_init_env
(
void
);
static
int
read_header
(
void
);
static
int
open_database
(
void
);
static
int
read_keys
(
void
);
static
int
apply_commandline_options
(
void
);
static
int
close_database
(
void
);
static
int
doublechararray
(
char
**
pmem
,
uint64_t
*
size
);
int
test_main
(
int
argc
,
char
*
const
argv
[])
{
int
ch
;
int
retval
;
char
**
next_config_option
;
/* Set up the globals. */
memset
(
&
g
,
0
,
sizeof
(
g
));
g
.
leadingspace
=
true
;
g
.
overwritekeys
=
true
;
g
.
dbtype
=
DB_UNKNOWN
;
//g.dbtype = DB_BTREE;
g
.
progname
=
argv
[
0
];
g
.
header
=
true
;
if
(
verify_library_version
()
!=
0
)
goto
error
;
next_config_option
=
g
.
config_options
=
(
char
**
)
calloc
(
argc
,
sizeof
(
char
*
));
if
(
next_config_option
==
NULL
)
{
PRINT_ERROR
(
errno
,
"main: calloc
\n
"
);
goto
error
;
}
while
((
ch
=
getopt
(
argc
,
argv
,
"c:f:h:nP:r:Tt:V"
))
!=
EOF
)
{
switch
(
ch
)
{
case
(
'c'
):
{
*
next_config_option
++
=
optarg
;
break
;
}
case
(
'f'
):
{
if
(
freopen
(
optarg
,
"r"
,
stdin
)
==
NULL
)
{
fprintf
(
stderr
,
"%s: %s: reopen: %s
\n
"
,
g
.
progname
,
optarg
,
strerror
(
errno
));
goto
error
;
}
break
;
}
case
(
'h'
):
{
g
.
homedir
=
optarg
;
break
;
}
case
(
'n'
):
{
/* g.overwritekeys = false; */
PRINT_ERRORX
(
"-%c option not supported.
\n
"
,
ch
);
goto
error
;
}
case
(
'P'
):
{
/* Clear password. */
memset
(
optarg
,
0
,
strlen
(
optarg
));
PRINT_ERRORX
(
"-%c option not supported.
\n
"
,
ch
);
goto
error
;
}
case
(
'r'
):
{
PRINT_ERRORX
(
"-%c option not supported.
\n
"
,
ch
);
goto
error
;
}
case
(
'T'
):
{
g
.
plaintext
=
true
;
g
.
leadingspace
=
false
;
g
.
header
=
false
;
break
;
}
case
(
't'
):
{
if
(
!
strcmp
(
optarg
,
"btree"
))
{
g
.
dbtype
=
DB_BTREE
;
break
;
}
if
(
!
strcmp
(
optarg
,
"hash"
)
||
!
strcmp
(
optarg
,
"recno"
)
||
!
strcmp
(
optarg
,
"queue"
))
{
fprintf
(
stderr
,
"%s: db type %s not supported.
\n
"
,
g
.
progname
,
optarg
);
goto
error
;
}
fprintf
(
stderr
,
"%s: Unrecognized db type %s.
\n
"
,
g
.
progname
,
optarg
);
goto
error
;
}
case
(
'V'
):
{
printf
(
"%s
\n
"
,
db_version
(
NULL
,
NULL
,
NULL
));
goto
cleanup
;
}
case
(
'?'
):
default:
{
g
.
exitcode
=
usage
();
goto
cleanup
;
}
}
}
argc
-=
optind
;
argv
+=
optind
;
if
(
argc
!=
1
)
{
g
.
exitcode
=
usage
();
goto
cleanup
;
}
init_catch_signals
();
g
.
database
=
argv
[
0
];
if
(
create_init_env
()
!=
0
)
goto
error
;
if
(
caught_any_signals
())
goto
cleanup
;
while
(
!
g
.
eof
)
{
if
(
load_database
()
!=
0
)
goto
error
;
if
(
caught_any_signals
())
goto
cleanup
;
}
if
(
false
)
{
error:
g
.
exitcode
=
EXIT_FAILURE
;
fprintf
(
stderr
,
"%s: Quitting out due to errors.
\n
"
,
g
.
progname
);
}
cleanup:
if
(
g
.
dbenv
&&
(
retval
=
g
.
dbenv
->
close
(
g
.
dbenv
,
0
))
!=
0
)
{
g
.
exitcode
=
EXIT_FAILURE
;
fprintf
(
stderr
,
"%s: dbenv->close: %s
\n
"
,
g
.
progname
,
db_strerror
(
retval
));
}
if
(
g
.
config_options
)
toku_free
(
g
.
config_options
);
if
(
g
.
subdatabase
)
toku_free
(
g
.
subdatabase
);
if
(
g
.
read_header
.
data
)
toku_free
(
g
.
read_header
.
data
);
if
(
g
.
get_dbt
.
data
[
0
])
toku_free
(
g
.
get_dbt
.
data
[
0
]);
if
(
g
.
get_dbt
.
data
[
1
])
toku_free
(
g
.
get_dbt
.
data
[
1
]);
resend_signals
();
return
g
.
exitcode
;
}
int
load_database
()
{
int
retval
;
/* Create a database handle. */
retval
=
db_create
(
&
g
.
db
,
g
.
dbenv
,
0
);
if
(
retval
!=
0
)
{
PRINT_ERROR
(
retval
,
"db_create"
);
return
EXIT_FAILURE
;
}
if
(
g
.
header
&&
read_header
()
!=
0
)
goto
error
;
if
(
g
.
eof
)
goto
cleanup
;
if
(
caught_any_signals
())
goto
cleanup
;
if
(
apply_commandline_options
()
!=
0
)
goto
error
;
if
(
g
.
eof
)
goto
cleanup
;
if
(
caught_any_signals
())
goto
cleanup
;
/*
TODO: If/when supporting encryption
if (g.password && (retval = db->set_flags(db, DB_ENCRYPT))) {
PRINT_ERROR(ret, "DB->set_flags: DB_ENCRYPT");
goto error;
}
*/
if
(
open_database
()
!=
0
)
goto
error
;
if
(
g
.
eof
)
goto
cleanup
;
if
(
caught_any_signals
())
goto
cleanup
;
if
(
read_keys
()
!=
0
)
goto
error
;
if
(
g
.
eof
)
goto
cleanup
;
if
(
caught_any_signals
())
goto
cleanup
;
if
(
false
)
{
error:
g
.
exitcode
=
EXIT_FAILURE
;
}
cleanup:
if
(
close_database
()
!=
0
)
g
.
exitcode
=
EXIT_FAILURE
;
return
g
.
exitcode
;
}
int
usage
()
{
fprintf
(
stderr
,
"usage: %s [-TV] [-c name=value] [-f file] [-h home] [-t btree] db_file
\n
"
,
g
.
progname
);
return
EXIT_FAILURE
;
}
int
create_init_env
()
{
int
retval
;
DB_ENV
*
dbenv
;
int
flags
;
//TODO: Experiments to determine right cache size for tokudb, or maybe command line argument.
//int cache = 1 << 20; /* 1 megabyte */
retval
=
db_env_create
(
&
dbenv
,
0
);
if
(
retval
)
{
fprintf
(
stderr
,
"%s: db_dbenv_create: %s
\n
"
,
g
.
progname
,
db_strerror
(
retval
));
goto
error
;
}
///TODO: UNCOMMENT/IMPLEMENT dbenv->set_errfile(dbenv, stderr);
dbenv
->
set_errpfx
(
dbenv
,
g
.
progname
);
/*
TODO: If/when supporting encryption
if (g.password && (retval = dbenv->set_encrypt(dbenv, g.password, DB_ENCRYPT_AES))) {
PRINT_ERROR(retval, "set_passwd");
goto error;
}
*/
/* Open the dbenvironment. */
g
.
is_private
=
false
;
flags
=
DB_INIT_LOCK
|
DB_INIT_LOG
|
DB_INIT_MPOOL
|
DB_INIT_TXN
|
DB_INIT_LOG
;
///TODO: UNCOMMENT/IMPLEMENT | DB_USE_ENVIRON;
//TODO: Transactions.. SET_BITS(flags, DB_INIT_TXN);
/*
///TODO: UNCOMMENT/IMPLEMENT Notes: We require DB_PRIVATE
if (!dbenv->open(dbenv, g.homedir, flags, 0)) goto success;
*/
/*
///TODO: UNCOMMENT/IMPLEMENT
retval = dbenv->set_cachesize(dbenv, 0, cache, 1);
if (retval) {
PRINT_ERROR(retval, "DB_ENV->set_cachesize");
goto error;
}
*/
g
.
is_private
=
true
;
//TODO: Do we want to support transactions/logging even in single-process mode?
//Maybe if the db already exists.
//If db does not exist.. makes sense not to log or have transactions
//REMOVE_BITS(flags, DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
SET_BITS
(
flags
,
DB_CREATE
|
DB_PRIVATE
);
retval
=
dbenv
->
open
(
dbenv
,
g
.
homedir
?
g
.
homedir
:
"."
,
flags
,
0
);
if
(
retval
)
{
PRINT_ERROR
(
retval
,
"DB_ENV->open"
);
goto
error
;
}
g
.
dbenv
=
dbenv
;
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
#define PARSE_NUMBER(match, dbfunction) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 1, INT32_MAX, 10)) goto error; \
if ((retval = dbfunction(db, num)) != 0) goto printerror; \
continue; \
}
#define PARSE_UNSUPPORTEDNUMBER(match, dbfunction) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 1, INT32_MAX, 10)) goto error; \
PRINT_ERRORX("%s option not supported.\n", field); \
goto error; \
}
#define PARSE_IGNOREDNUMBER(match, dbfunction) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 1, INT32_MAX, 10)) goto error; \
PRINT_ERRORX("%s option not supported yet (ignored).\n", field); \
continue; \
}
#define PARSE_FLAG(match, flag) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 0, 1, 10)) { \
PRINT_ERRORX("%s: boolean name=value pairs require a value of 0 or 1", \
field); \
goto error; \
} \
if ((retval = db->set_flags(db, flag)) != 0) { \
PRINT_ERROR(retval, "set_flags: %s", field); \
goto error; \
} \
continue; \
}
#define PARSE_UNSUPPORTEDFLAG(match, flag) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 0, 1, 10)) { \
PRINT_ERRORX("%s: boolean name=value pairs require a value of 0 or 1", \
field); \
goto error; \
} \
PRINT_ERRORX("%s option not supported.\n", field); \
goto error; \
}
#define PARSE_IGNOREDFLAG(match, flag) \
if (!strcmp(field, match)) { \
if (strtoint32(value, &num, 0, 1, 10)) { \
PRINT_ERRORX("%s: boolean name=value pairs require a value of 0 or 1", \
field); \
goto error; \
} \
PRINT_ERRORX("%s option not supported yet (ignored).\n", field); \
continue; \
}
#define PARSE_CHAR(match, dbfunction) \
if (!strcmp(field, match)) { \
if (strlen(value) != 1) { \
PRINT_ERRORX("%s=%s: Expected 1-byte value", \
field, value); \
goto error; \
} \
if ((retval = dbfunction(db, value[0])) != 0) { \
goto printerror; \
} \
continue; \
}
#define PARSE_UNSUPPORTEDCHAR(match, dbfunction) \
if (!strcmp(field, match)) { \
if (strlen(value) != 1) { \
PRINT_ERRORX("%s=%s: Expected 1-byte value", \
field, value); \
goto error; \
} \
PRINT_ERRORX("%s option not supported.\n", field); \
goto error; \
}
#define PARSE_COMMON_CONFIGURATIONS() \
PARSE_IGNOREDNUMBER( "bt_minkey", db->set_bt_minkey); \
PARSE_IGNOREDFLAG( "chksum", DB_CHKSUM); \
PARSE_IGNOREDNUMBER( "db_lorder", db->set_lorder); \
PARSE_IGNOREDNUMBER( "db_pagesize", db->set_pagesize); \
PARSE_UNSUPPORTEDNUMBER("extentsize", db->set_q_extentsize); \
PARSE_UNSUPPORTEDNUMBER("h_ffactor", db->set_h_ffactor); \
PARSE_UNSUPPORTEDNUMBER("h_nelem", db->set_h_nelem); \
PARSE_UNSUPPORTEDNUMBER("re_len", db->set_re_len); \
PARSE_UNSUPPORTEDCHAR( "re_pad", db->set_re_pad); \
PARSE_UNSUPPORTEDFLAG( "recnum", DB_RECNUM); \
PARSE_UNSUPPORTEDFLAG( "renumber", DB_RENUMBER);
int
read_header
()
{
static
uint64_t
datasize
=
1
<<
10
;
uint64_t
idx
=
0
;
char
*
field
;
char
*
value
;
int
ch
;
int32_t
num
;
int
retval
;
int
r
;
assert
(
g
.
header
);
if
(
g
.
read_header
.
data
==
NULL
&&
(
g
.
read_header
.
data
=
(
char
*
)
toku_malloc
(
datasize
*
sizeof
(
char
)))
==
NULL
)
{
PRINT_ERROR
(
errno
,
"read_header: malloc"
);
goto
error
;
}
while
(
!
g
.
eof
)
{
if
(
caught_any_signals
())
goto
success
;
g
.
linenumber
++
;
idx
=
0
;
/* Read a line. */
while
(
true
)
{
if
((
ch
=
getchar
())
==
EOF
)
{
g
.
eof
=
true
;
if
(
ferror
(
stdin
))
goto
formaterror
;
break
;
}
if
(
ch
==
'\n'
)
break
;
g
.
read_header
.
data
[
idx
]
=
(
char
)
ch
;
idx
++
;
/* Ensure room exists for next character/null terminator. */
if
(
idx
==
datasize
&&
doublechararray
(
&
g
.
read_header
.
data
,
&
datasize
))
goto
error
;
}
if
(
idx
==
0
&&
g
.
eof
)
goto
success
;
g
.
read_header
.
data
[
idx
]
=
'\0'
;
field
=
g
.
read_header
.
data
;
if
((
value
=
strchr
(
g
.
read_header
.
data
,
'='
))
==
NULL
)
goto
formaterror
;
value
[
0
]
=
'\0'
;
value
++
;
if
(
field
[
0
]
==
'\0'
||
value
[
0
]
==
'\0'
)
goto
formaterror
;
if
(
!
strcmp
(
field
,
"HEADER"
))
break
;
if
(
!
strcmp
(
field
,
"VERSION"
))
{
if
(
strtoint32
(
value
,
&
g
.
version
,
1
,
INT32_MAX
,
10
))
goto
error
;
if
(
g
.
version
!=
3
)
{
PRINT_ERRORX
(
"line %"
PRIu64
": VERSION %d is unsupported"
,
g
.
linenumber
,
g
.
version
);
goto
error
;
}
continue
;
}
if
(
!
strcmp
(
field
,
"format"
))
{
if
(
!
strcmp
(
value
,
"bytevalue"
))
{
g
.
plaintext
=
false
;
continue
;
}
if
(
!
strcmp
(
value
,
"print"
))
{
g
.
plaintext
=
true
;
continue
;
}
goto
formaterror
;
}
if
(
!
strcmp
(
field
,
"type"
))
{
if
(
!
strcmp
(
value
,
"btree"
))
{
g
.
dbtype
=
DB_BTREE
;
continue
;
}
if
(
!
strcmp
(
value
,
"hash"
)
||
strcmp
(
value
,
"recno"
)
||
strcmp
(
value
,
"queue"
))
{
PRINT_ERRORX
(
"db type %s not supported.
\n
"
,
value
);
goto
error
;
}
PRINT_ERRORX
(
"line %"
PRIu64
": unknown type %s"
,
g
.
linenumber
,
value
);
goto
error
;
}
if
(
!
strcmp
(
field
,
"database"
)
||
!
strcmp
(
field
,
"subdatabase"
))
{
if
(
g
.
subdatabase
!=
NULL
)
{
toku_free
(
g
.
subdatabase
);
g
.
subdatabase
=
NULL
;
}
if
((
retval
=
printabletocstring
(
value
,
&
g
.
subdatabase
)))
{
PRINT_ERROR
(
retval
,
"error reading db name"
);
goto
error
;
}
continue
;
}
if
(
!
strcmp
(
field
,
"keys"
))
{
int32_t
temp
;
if
(
strtoint32
(
value
,
&
temp
,
0
,
1
,
10
))
{
PRINT_ERROR
(
0
,
"%s: boolean name=value pairs require a value of 0 or 1"
,
field
);
goto
error
;
}
g
.
keys
=
(
bool
)
temp
;
if
(
!
g
.
keys
)
{
PRINT_ERRORX
(
"keys=0 not supported"
);
goto
error
;
}
continue
;
}
PARSE_COMMON_CONFIGURATIONS
();
PRINT_ERRORX
(
"unknown input-file header configuration keyword
\"
%s
\"
"
,
field
);
goto
error
;
}
success:
r
=
0
;
if
(
false
)
{
formaterror:
r
=
EXIT_FAILURE
;
PRINT_ERRORX
(
"line %"
PRIu64
": unexpected format"
,
g
.
linenumber
);
}
if
(
false
)
{
error:
r
=
EXIT_FAILURE
;
}
return
r
;
}
int
apply_commandline_options
()
{
int
r
=
-
1
;
unsigned
idx
;
char
*
field
;
char
*
value
=
NULL
;
int32_t
num
;
int
retval
;
for
(
idx
=
0
;
g
.
config_options
[
idx
];
idx
++
)
{
if
(
value
)
{
/* Restore the field=value format. */
value
[
-
1
]
=
'='
;
value
=
NULL
;
}
field
=
g
.
config_options
[
idx
];
if
((
value
=
strchr
(
field
,
'='
))
==
NULL
)
{
PRINT_ERRORX
(
"command-line configuration uses name=value format"
);
goto
error
;
}
value
[
0
]
=
'\0'
;
value
++
;
if
(
field
[
0
]
==
'\0'
||
value
[
0
]
==
'\0'
)
{
PRINT_ERRORX
(
"command-line configuration uses name=value format"
);
goto
error
;
}
if
(
!
strcmp
(
field
,
"database"
)
||
!
strcmp
(
field
,
"subdatabase"
))
{
if
(
g
.
subdatabase
!=
NULL
)
{
toku_free
(
g
.
subdatabase
);
g
.
subdatabase
=
NULL
;
}
if
((
retval
=
printabletocstring
(
value
,
&
g
.
subdatabase
)))
{
PRINT_ERROR
(
retval
,
"error reading db name"
);
goto
error
;
}
continue
;
}
if
(
!
strcmp
(
field
,
"keys"
))
{
int32_t
temp
;
if
(
strtoint32
(
value
,
&
temp
,
0
,
1
,
10
))
{
PRINT_ERROR
(
0
,
"%s: boolean name=value pairs require a value of 0 or 1"
,
field
);
goto
error
;
}
g
.
keys
=
(
bool
)
temp
;
if
(
!
g
.
keys
)
{
PRINT_ERRORX
(
"keys=0 not supported"
);
goto
error
;
}
continue
;
}
PARSE_COMMON_CONFIGURATIONS
();
PRINT_ERRORX
(
"unknown input-file header configuration keyword
\"
%s
\"
"
,
field
);
goto
error
;
}
if
(
value
)
{
/* Restore the field=value format. */
value
[
-
1
]
=
'='
;
value
=
NULL
;
}
r
=
0
;
error:
return
r
;
}
int
open_database
()
{
DB
*
db
=
g
.
db
;
int
retval
;
int
open_flags
=
0
;
//TODO: Transaction auto commit stuff
//if (TXN_ON(dbenv)) SET_BITS(open_flags, DB_AUTO_COMMIT);
//Try to see if it exists first.
retval
=
db
->
open
(
db
,
NULL
,
g
.
database
,
g
.
subdatabase
,
g
.
dbtype
,
open_flags
,
0666
);
if
(
retval
==
ENOENT
)
{
//Does not exist and we did not specify a type.
//TODO: Uncomment when DB_UNKNOWN + db->get_type are implemented.
/*
if (g.dbtype == DB_UNKNOWN) {
PRINT_ERRORX("no database type specified");
goto error;
}*/
SET_BITS
(
open_flags
,
DB_CREATE
);
//Try creating it.
retval
=
db
->
open
(
db
,
NULL
,
g
.
database
,
g
.
subdatabase
,
g
.
dbtype
,
open_flags
,
0666
);
}
if
(
retval
!=
0
)
{
PRINT_ERROR
(
retval
,
"DB->open: %s"
,
g
.
database
);
goto
error
;
}
//TODO: Uncomment when DB_UNKNOWN + db->get_type are implemented.
/*
if ((retval = db->get_type(db, &opened_type)) != 0) {
PRINT_ERROR(retval, "DB->get_type");
goto error;
}
if (opened_type != DB_BTREE) {
PRINT_ERRORX("Unsupported db type %d\n", opened_type);
goto error;
}
if (g.dbtype != DB_UNKNOWN && opened_type != g.dbtype) {
PRINT_ERRORX("DBTYPE %d does not match opened DBTYPE %d.\n", g.dbtype, opened_type);
goto error;
}*/
return
EXIT_SUCCESS
;
error:
fprintf
(
stderr
,
"Quitting out due to errors.
\n
"
);
return
EXIT_FAILURE
;
}
int
doublechararray
(
char
**
pmem
,
uint64_t
*
size
)
{
assert
(
pmem
);
assert
(
size
);
assert
(
IS_POWER_OF_2
(
*
size
));
*
size
<<=
1
;
if
(
*
size
==
0
)
{
/* Overflowed uint64_t. */
PRINT_ERRORX
(
"Line %"
PRIu64
": Line too long.
\n
"
,
g
.
linenumber
);
goto
error
;
}
if
((
*
pmem
=
(
char
*
)
toku_realloc
(
*
pmem
,
*
size
))
==
NULL
)
{
PRINT_ERROR
(
errno
,
"doublechararray: realloc"
);
goto
error
;
}
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
static
int
get_dbt
(
DBT
*
pdbt
)
{
/* Need to store a key and value. */
static
uint64_t
datasize
[
2
]
=
{
1
<<
10
,
1
<<
10
};
static
int
which
=
0
;
char
*
datum
;
uint64_t
idx
=
0
;
int
highch
;
int
lowch
;
/* *pdbt should have been memset to 0 before being called. */
which
=
1
-
which
;
if
(
g
.
get_dbt
.
data
[
which
]
==
NULL
&&
(
g
.
get_dbt
.
data
[
which
]
=
(
char
*
)
toku_malloc
(
datasize
[
which
]
*
sizeof
(
char
)))
==
NULL
)
{
PRINT_ERROR
(
errno
,
"get_dbt: malloc"
);
goto
error
;
}
datum
=
g
.
get_dbt
.
data
[
which
];
if
(
g
.
plaintext
)
{
int
firstch
;
int
nextch
=
EOF
;
for
(
firstch
=
getchar
();
firstch
!=
EOF
;
firstch
=
getchar
())
{
switch
(
firstch
)
{
case
(
'\n'
):
{
/* Done reading this key/value. */
nextch
=
EOF
;
break
;
}
case
(
'\\'
):
{
/* Escaped \ or two hex digits. */
highch
=
getchar
();
if
(
highch
==
'\\'
)
{
nextch
=
'\\'
;
break
;
}
else
if
(
highch
==
EOF
)
{
g
.
eof
=
true
;
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected end of file (2 hex digits per byte).
\n
"
,
g
.
linenumber
);
goto
error
;
}
else
if
(
!
isxdigit
(
highch
))
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected '%c' (non-hex) input.
\n
"
,
g
.
linenumber
,
highch
);
goto
error
;
}
lowch
=
getchar
();
if
(
lowch
==
EOF
)
{
g
.
eof
=
true
;
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected end of file (2 hex digits per byte).
\n
"
,
g
.
linenumber
);
goto
error
;
}
else
if
(
!
isxdigit
(
lowch
))
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected '%c' (non-hex) input.
\n
"
,
g
.
linenumber
,
lowch
);
goto
error
;
}
nextch
=
(
hextoint
(
highch
)
<<
4
)
|
hextoint
(
lowch
);
break
;
}
default:
{
if
(
isprint
(
firstch
))
{
nextch
=
firstch
;
break
;
}
PRINT_ERRORX
(
"Line %"
PRIu64
": Nonprintable character found."
,
g
.
linenumber
);
goto
error
;
}
}
if
(
nextch
==
EOF
)
{
break
;
}
if
(
idx
==
datasize
[
which
])
{
/* Overflow, double the memory. */
if
(
doublechararray
(
&
g
.
get_dbt
.
data
[
which
],
&
datasize
[
which
]))
goto
error
;
datum
=
g
.
get_dbt
.
data
[
which
];
}
datum
[
idx
]
=
(
char
)
nextch
;
idx
++
;
}
if
(
firstch
==
EOF
)
g
.
eof
=
true
;
}
else
{
for
(
highch
=
getchar
();
highch
!=
EOF
;
highch
=
getchar
())
{
if
(
highch
==
'\n'
)
{
/* Done reading this key/value. */
break
;
}
lowch
=
getchar
();
if
(
lowch
==
EOF
)
{
g
.
eof
=
true
;
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected end of file (2 hex digits per byte).
\n
"
,
g
.
linenumber
);
goto
error
;
}
if
(
!
isxdigit
(
highch
))
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected '%c' (non-hex) input.
\n
"
,
g
.
linenumber
,
highch
);
goto
error
;
}
if
(
!
isxdigit
(
lowch
))
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected '%c' (non-hex) input.
\n
"
,
g
.
linenumber
,
lowch
);
goto
error
;
}
if
(
idx
==
datasize
[
which
])
{
/* Overflow, double the memory. */
if
(
doublechararray
(
&
g
.
get_dbt
.
data
[
which
],
&
datasize
[
which
]))
goto
error
;
datum
=
g
.
get_dbt
.
data
[
which
];
}
datum
[
idx
]
=
(
char
)((
hextoint
(
highch
)
<<
4
)
|
hextoint
(
lowch
));
idx
++
;
}
if
(
highch
==
EOF
)
g
.
eof
=
true
;
}
/* Done reading. */
pdbt
->
size
=
idx
;
pdbt
->
data
=
(
void
*
)
datum
;
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
static
int
insert_pair
(
DBT
*
key
,
DBT
*
data
)
{
DB
*
db
=
g
.
db
;
int
retval
=
db
->
put
(
db
,
NULL
,
key
,
data
,
g
.
overwritekeys
?
0
:
DB_NOOVERWRITE
);
if
(
retval
!=
0
)
{
//TODO: Check for transaction failures/etc.. retry if necessary.
PRINT_ERROR
(
retval
,
"DB->put"
);
if
(
!
(
retval
==
DB_KEYEXIST
&&
g
.
overwritekeys
))
goto
error
;
}
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
int
read_keys
()
{
DBT
key
;
DBT
data
;
int
spacech
;
char
footer
[
sizeof
(
"ATA=END
\n
"
)];
memset
(
&
key
,
0
,
sizeof
(
key
));
memset
(
&
data
,
0
,
sizeof
(
data
));
//TODO: Start transaction/end transaction/abort/retry/etc
if
(
!
g
.
leadingspace
)
{
assert
(
g
.
plaintext
);
while
(
!
g
.
eof
)
{
if
(
caught_any_signals
())
goto
success
;
g
.
linenumber
++
;
if
(
get_dbt
(
&
key
)
!=
0
)
goto
error
;
if
(
g
.
eof
)
{
if
(
key
.
size
==
0
)
{
//Last entry had no newline. Done.
break
;
}
PRINT_ERRORX
(
"Line %"
PRIu64
": Key exists but value missing."
,
g
.
linenumber
);
goto
error
;
}
g
.
linenumber
++
;
if
(
get_dbt
(
&
data
)
!=
0
)
goto
error
;
if
(
insert_pair
(
&
key
,
&
data
)
!=
0
)
goto
error
;
}
}
else
while
(
!
g
.
eof
)
{
if
(
caught_any_signals
())
goto
success
;
g
.
linenumber
++
;
spacech
=
getchar
();
switch
(
spacech
)
{
case
(
EOF
):
{
/* Done. */
g
.
eof
=
true
;
goto
success
;
}
case
(
' '
):
{
/* Time to read a key. */
if
(
get_dbt
(
&
key
)
!=
0
)
goto
error
;
break
;
}
case
(
'D'
):
{
if
(
fgets
(
footer
,
sizeof
(
"ATA=END
\n
"
),
stdin
)
!=
NULL
&&
(
!
strcmp
(
footer
,
"ATA=END"
)
||
!
strcmp
(
footer
,
"ATA=END
\n
"
)))
{
goto
success
;
}
goto
unexpectedinput
;
}
default:
{
unexpectedinput:
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected input while reading key.
\n
"
,
g
.
linenumber
);
goto
error
;
}
}
if
(
g
.
eof
)
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Key exists but value missing."
,
g
.
linenumber
);
goto
error
;
}
g
.
linenumber
++
;
spacech
=
getchar
();
switch
(
spacech
)
{
case
(
EOF
):
{
g
.
eof
=
true
;
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected end of file while reading value.
\n
"
,
g
.
linenumber
);
goto
error
;
}
case
(
' '
):
{
/* Time to read a key. */
if
(
get_dbt
(
&
data
)
!=
0
)
goto
error
;
break
;
}
default:
{
PRINT_ERRORX
(
"Line %"
PRIu64
": Unexpected input while reading value.
\n
"
,
g
.
linenumber
);
goto
error
;
}
}
if
(
insert_pair
(
&
key
,
&
data
)
!=
0
)
goto
error
;
}
success:
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
int
close_database
()
{
DB
*
db
=
g
.
db
;
int
retval
;
assert
(
db
);
if
((
retval
=
db
->
close
(
db
,
0
))
!=
0
)
{
PRINT_ERROR
(
retval
,
"DB->close"
);
goto
error
;
}
return
EXIT_SUCCESS
;
error:
return
EXIT_FAILURE
;
}
Write
Preview
Markdown
is supported
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