kyotocabinet-java 0.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/ext/kyotocabinet-java/.gitignore +2 -0
- data/ext/kyotocabinet-java/COPYING +674 -0
- data/ext/kyotocabinet-java/Cursor.java +268 -0
- data/ext/kyotocabinet-java/DB.java +650 -0
- data/ext/kyotocabinet-java/Error.java +257 -0
- data/ext/kyotocabinet-java/FileProcessor.java +42 -0
- data/ext/kyotocabinet-java/Loader.java +60 -0
- data/ext/kyotocabinet-java/Makefile.in +246 -0
- data/ext/kyotocabinet-java/MapReduce.java +127 -0
- data/ext/kyotocabinet-java/README +26 -0
- data/ext/kyotocabinet-java/Test.java +1494 -0
- data/ext/kyotocabinet-java/Utility.java +131 -0
- data/ext/kyotocabinet-java/VCmakefile +150 -0
- data/ext/kyotocabinet-java/ValueIterator.java +49 -0
- data/ext/kyotocabinet-java/Visitor.java +56 -0
- data/ext/kyotocabinet-java/configure.in +310 -0
- data/ext/kyotocabinet-java/doc/allclasses-frame.html +26 -0
- data/ext/kyotocabinet-java/doc/allclasses-noframe.html +26 -0
- data/ext/kyotocabinet-java/doc/constant-values.html +344 -0
- data/ext/kyotocabinet-java/doc/index-all.html +848 -0
- data/ext/kyotocabinet-java/doc/index.html +30 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/Cursor.html +711 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/DB.html +1674 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/Error.html +604 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/FileProcessor.html +210 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/MapReduce.html +461 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/Test.html +220 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/Utility.html +413 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/ValueIterator.html +221 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/Visitor.html +283 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/package-frame.html +33 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/package-summary.html +199 -0
- data/ext/kyotocabinet-java/doc/kyotocabinet/package-tree.html +141 -0
- data/ext/kyotocabinet-java/doc/overview-summary.html +285 -0
- data/ext/kyotocabinet-java/doc/overview-tree.html +145 -0
- data/ext/kyotocabinet-java/doc/package-list +1 -0
- data/ext/kyotocabinet-java/doc/resources/background.gif +0 -0
- data/ext/kyotocabinet-java/doc/resources/tab.gif +0 -0
- data/ext/kyotocabinet-java/doc/resources/titlebar.gif +0 -0
- data/ext/kyotocabinet-java/doc/resources/titlebar_end.gif +0 -0
- data/ext/kyotocabinet-java/doc/serialized-form.html +141 -0
- data/ext/kyotocabinet-java/doc/stylesheet.css +474 -0
- data/ext/kyotocabinet-java/example/KCDBEX1.java +44 -0
- data/ext/kyotocabinet-java/example/KCDBEX2.java +44 -0
- data/ext/kyotocabinet-java/example/Makefile +59 -0
- data/ext/kyotocabinet-java/kyotocabinet.cc +2187 -0
- data/ext/kyotocabinet-java/kyotocabinet_Cursor.h +157 -0
- data/ext/kyotocabinet-java/kyotocabinet_DB.h +353 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error.h +49 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XBROKEN.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XDUPREC.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XINVALID.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XLOGIC.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XMISC.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XNOIMPL.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XNOPERM.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XNOREC.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XNOREPOS.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XSUCCESS.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_Error_XSYSTEM.h +41 -0
- data/ext/kyotocabinet-java/kyotocabinet_MapReduce.h +33 -0
- data/ext/kyotocabinet-java/kyotocabinet_Utility.h +101 -0
- data/ext/kyotocabinet-java/kyotocabinet_ValueIterator.h +21 -0
- data/ext/kyotocabinet-java/overview.html +177 -0
- data/kyotocabinet-java.gemspec +129 -0
- data/lib/kyotocabinet-java.rb +141 -0
- data/lib/kyotocabinet-java/version.rb +5 -0
- metadata +222 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/*************************************************************************************************
|
|
2
|
+
* Java binding of Kyoto Cabinet.
|
|
3
|
+
* Copyright (C) 2009-2011 FAL Labs
|
|
4
|
+
* This file is part of Kyoto Cabinet.
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify it under the terms of
|
|
6
|
+
* the GNU General Public License as published by the Free Software Foundation, either version
|
|
7
|
+
* 3 of the License, or any later version.
|
|
8
|
+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
9
|
+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
* See the GNU General Public License for more details.
|
|
11
|
+
* You should have received a copy of the GNU General Public License along with this program.
|
|
12
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
*************************************************************************************************/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
package kyotocabinet;
|
|
17
|
+
|
|
18
|
+
import java.util.*;
|
|
19
|
+
import java.io.*;
|
|
20
|
+
import java.net.*;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* MapReduce framework.
|
|
25
|
+
*/
|
|
26
|
+
public abstract class MapReduce {
|
|
27
|
+
//----------------------------------------------------------------
|
|
28
|
+
// static initializer
|
|
29
|
+
//----------------------------------------------------------------
|
|
30
|
+
static {
|
|
31
|
+
Loader.load();
|
|
32
|
+
}
|
|
33
|
+
//----------------------------------------------------------------
|
|
34
|
+
// public constants
|
|
35
|
+
//----------------------------------------------------------------
|
|
36
|
+
/** execution option: avoid locking against update operations */
|
|
37
|
+
public static final int XNOLOCK = 1 << 0;
|
|
38
|
+
/** execution option: avoid compression of temporary databases */
|
|
39
|
+
public static final int XNOCOMP = 1 << 8;
|
|
40
|
+
//----------------------------------------------------------------
|
|
41
|
+
// public methods
|
|
42
|
+
//---------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Map a record data.
|
|
45
|
+
* @param key specifies the key.
|
|
46
|
+
* @param value specifies the value.
|
|
47
|
+
* @return true on success, or false on failure.
|
|
48
|
+
* @note This method can call the MapReduce::emit method to emit a record. To avoid
|
|
49
|
+
* deadlock, any explicit database operation must not be performed in this method.
|
|
50
|
+
*/
|
|
51
|
+
public abstract boolean map(byte[] key, byte[] value);
|
|
52
|
+
/**
|
|
53
|
+
* Reduce a record data.
|
|
54
|
+
* @param key specifies the key.
|
|
55
|
+
* @param iter the iterator to get the values.
|
|
56
|
+
* @return true on success, or false on failure.
|
|
57
|
+
* @note To avoid deadlock, any explicit database operation must not be performed in this
|
|
58
|
+
* method.
|
|
59
|
+
*/
|
|
60
|
+
public abstract boolean reduce(byte[] key, ValueIterator iter);
|
|
61
|
+
/**
|
|
62
|
+
* Preprocess the map operations.
|
|
63
|
+
* @return true on success, or false on failure.
|
|
64
|
+
* @note This method can call the MapReduce::emit method to emit a record. To avoid
|
|
65
|
+
* deadlock, any explicit database operation must not be performed in this method.
|
|
66
|
+
*/
|
|
67
|
+
public boolean preprocess() {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mediate between the map and the reduce phases.
|
|
72
|
+
* @return true on success, or false on failure.
|
|
73
|
+
* @note This method can call the MapReduce::emit method to emit a record. To avoid
|
|
74
|
+
* deadlock, any explicit database operation must not be performed in this method.
|
|
75
|
+
*/
|
|
76
|
+
public boolean midprocess() {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Postprocess the reduce operations.
|
|
81
|
+
* @return true on success, or false on failure.
|
|
82
|
+
* @note To avoid deadlock, any explicit database operation must not be performed in this
|
|
83
|
+
* method.
|
|
84
|
+
*/
|
|
85
|
+
public boolean postprocess() {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Process a log message.
|
|
90
|
+
* @param name the name of the event.
|
|
91
|
+
* @param message a supplement message.
|
|
92
|
+
* @return true on success, or false on failure.
|
|
93
|
+
*/
|
|
94
|
+
public boolean log(String name, String message) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Execute the MapReduce process about a database.
|
|
99
|
+
* @param db the source database.
|
|
100
|
+
* @param tmppath the path of a directory for the temporary data storage. If it is an empty
|
|
101
|
+
* string, temporary data are handled on memory.
|
|
102
|
+
* @param opts the optional features by bitwise-or: MapReduce::XNOLOCK to avoid locking
|
|
103
|
+
* against update operations by other threads, MapReduce::XNOCOMP to avoid compression of
|
|
104
|
+
* temporary databases.
|
|
105
|
+
* @return true on success, or false on failure.
|
|
106
|
+
*/
|
|
107
|
+
public native boolean execute(DB db, String tmppath, int opts);
|
|
108
|
+
//----------------------------------------------------------------
|
|
109
|
+
// protected methods
|
|
110
|
+
//---------------------------------------------------------------
|
|
111
|
+
/**
|
|
112
|
+
* Emit a record from the mapper.
|
|
113
|
+
* @param key specifies the key.
|
|
114
|
+
* @param value specifies the value.
|
|
115
|
+
* @return true on success, or false on failure.
|
|
116
|
+
*/
|
|
117
|
+
protected native boolean emit(byte[] key, byte[] value);
|
|
118
|
+
//----------------------------------------------------------------
|
|
119
|
+
// private fields
|
|
120
|
+
//----------------------------------------------------------------
|
|
121
|
+
/** The pointer to the native object */
|
|
122
|
+
private long ptr_ = 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
// END OF FILE
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
================================================================
|
|
2
|
+
Kyoto Cabinet: a straightforward implementation of DBM
|
|
3
|
+
Copyright (C) 2009-2010 FAL Labs
|
|
4
|
+
================================================================
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Please read the following documents with a WWW browser.
|
|
8
|
+
How to install Kyoto Cabinet is explained in the API document.
|
|
9
|
+
|
|
10
|
+
README - this file
|
|
11
|
+
COPYING - license
|
|
12
|
+
doc/index.html - index of documents
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Kyoto Cabinet is released under the terms of the GNU General Public
|
|
16
|
+
License version 3. See the file `COPYING' for details.
|
|
17
|
+
|
|
18
|
+
Kyoto Cabinet was written by FAL Labs. You can contact the author
|
|
19
|
+
by e-mail to `info@fallabs.com'.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Thanks.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
== END OF FILE ==
|
|
@@ -0,0 +1,1494 @@
|
|
|
1
|
+
/*************************************************************************************************
|
|
2
|
+
* Java binding of Kyoto Cabinet.
|
|
3
|
+
* Copyright (C) 2009-2011 FAL Labs
|
|
4
|
+
* This file is part of Kyoto Cabinet.
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify it under the terms of
|
|
6
|
+
* the GNU General Public License as published by the Free Software Foundation, either version
|
|
7
|
+
* 3 of the License, or any later version.
|
|
8
|
+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
9
|
+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
* See the GNU General Public License for more details.
|
|
11
|
+
* You should have received a copy of the GNU General Public License along with this program.
|
|
12
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
*************************************************************************************************/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
package kyotocabinet;
|
|
17
|
+
|
|
18
|
+
import java.util.*;
|
|
19
|
+
import java.io.*;
|
|
20
|
+
import java.net.*;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Test cases.
|
|
25
|
+
*/
|
|
26
|
+
public class Test {
|
|
27
|
+
//----------------------------------------------------------------
|
|
28
|
+
// public static methods
|
|
29
|
+
//----------------------------------------------------------------
|
|
30
|
+
/** main routine of the test command */
|
|
31
|
+
public static void main(String[] args) {
|
|
32
|
+
if (args.length < 1) usage();
|
|
33
|
+
int rv = 0;
|
|
34
|
+
if (args[0].equals("order")) {
|
|
35
|
+
rv = runorder(args);
|
|
36
|
+
} else if (args[0].equals("wicked")) {
|
|
37
|
+
rv = runwicked(args);
|
|
38
|
+
} else if (args[0].equals("misc")) {
|
|
39
|
+
rv = runmisc(args);
|
|
40
|
+
} else if (args[0].equals("memsize")) {
|
|
41
|
+
rv = runmemsize(args);
|
|
42
|
+
} else {
|
|
43
|
+
usage();
|
|
44
|
+
}
|
|
45
|
+
System.gc();
|
|
46
|
+
System.exit(rv);
|
|
47
|
+
}
|
|
48
|
+
//----------------------------------------------------------------
|
|
49
|
+
// private static methods
|
|
50
|
+
//----------------------------------------------------------------
|
|
51
|
+
/** print the usage and exit */
|
|
52
|
+
private static void usage() {
|
|
53
|
+
STDERR.printf("test cases of the Java binding\n");
|
|
54
|
+
STDERR.printf("\n");
|
|
55
|
+
STDERR.printf("synopsis:\n");
|
|
56
|
+
STDERR.printf(" java %s arguments...\n", Test.class.getName());
|
|
57
|
+
STDERR.printf("\n");
|
|
58
|
+
STDERR.printf("arguments:\n");
|
|
59
|
+
STDERR.printf(" order [-th num] [-rnd] [-etc] path rnum\n");
|
|
60
|
+
STDERR.printf(" wicked [-th num] [-it num] path rnum\n");
|
|
61
|
+
STDERR.printf(" misc path\n");
|
|
62
|
+
STDERR.printf(" memsize [rnum [path]]\n");
|
|
63
|
+
STDERR.printf("\n");
|
|
64
|
+
System.exit(1);
|
|
65
|
+
}
|
|
66
|
+
/** print the error message of the database */
|
|
67
|
+
private static void dberrprint(DB db, String func) {
|
|
68
|
+
Error err = db.error();
|
|
69
|
+
printf("%s: %s: %d: %s: %s\n",
|
|
70
|
+
Test.class.getName(), func, err.code(), err.name(), err.message());
|
|
71
|
+
}
|
|
72
|
+
/** print members of a database */
|
|
73
|
+
private static void dbmetaprint(DB db, boolean verbose) {
|
|
74
|
+
if (verbose) {
|
|
75
|
+
Map<String, String> status = db.status();
|
|
76
|
+
if (status != null) {
|
|
77
|
+
for (Map.Entry<String, String> rec : status.entrySet()) {
|
|
78
|
+
printf("%s: %s\n", rec.getKey(), rec.getValue());
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
printf("count: %d\n", db.count());
|
|
83
|
+
printf("size: %d\n", db.size());
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** parse arguments of order command */
|
|
87
|
+
private static int runorder(String[] args) {
|
|
88
|
+
String path = null;
|
|
89
|
+
String rstr = null;
|
|
90
|
+
int thnum = 1;
|
|
91
|
+
boolean rnd = false;
|
|
92
|
+
boolean etc = false;
|
|
93
|
+
for (int i = 1; i < args.length; i++) {
|
|
94
|
+
String arg = args[i];
|
|
95
|
+
if (path == null && arg.startsWith("-")) {
|
|
96
|
+
if (arg.equals("-th")) {
|
|
97
|
+
if (++i >= args.length) usage();
|
|
98
|
+
thnum = (int)Utility.atoix(args[i]);
|
|
99
|
+
} else if (arg.equals("-rnd")) {
|
|
100
|
+
rnd = true;
|
|
101
|
+
} else if (arg.equals("-etc")) {
|
|
102
|
+
etc = true;
|
|
103
|
+
} else {
|
|
104
|
+
usage();
|
|
105
|
+
}
|
|
106
|
+
} else if (path == null) {
|
|
107
|
+
path = arg;
|
|
108
|
+
} else if (rstr == null) {
|
|
109
|
+
rstr = arg;
|
|
110
|
+
} else {
|
|
111
|
+
usage();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (path == null || rstr == null) usage();
|
|
115
|
+
long rnum = Utility.atoix(rstr);
|
|
116
|
+
if (rnum < 1 || thnum < 1) usage();
|
|
117
|
+
int rv = procorder(path, rnum, thnum, rnd, etc);
|
|
118
|
+
return rv;
|
|
119
|
+
}
|
|
120
|
+
/** parse arguments of wicked command */
|
|
121
|
+
private static int runwicked(String[] args) {
|
|
122
|
+
String path = null;
|
|
123
|
+
String rstr = null;
|
|
124
|
+
int thnum = 1;
|
|
125
|
+
int itnum = 1;
|
|
126
|
+
for (int i = 1; i < args.length; i++) {
|
|
127
|
+
String arg = args[i];
|
|
128
|
+
if (path == null && arg.startsWith("-")) {
|
|
129
|
+
if (arg.equals("-th")) {
|
|
130
|
+
if (++i >= args.length) usage();
|
|
131
|
+
thnum = (int)Utility.atoix(args[i]);
|
|
132
|
+
} else if (arg.equals("-it")) {
|
|
133
|
+
if (++i >= args.length) usage();
|
|
134
|
+
itnum = (int)Utility.atoix(args[i]);
|
|
135
|
+
} else {
|
|
136
|
+
usage();
|
|
137
|
+
}
|
|
138
|
+
} else if (path == null) {
|
|
139
|
+
path = arg;
|
|
140
|
+
} else if (rstr == null) {
|
|
141
|
+
rstr = arg;
|
|
142
|
+
} else {
|
|
143
|
+
usage();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (path == null || rstr == null) usage();
|
|
147
|
+
long rnum = Utility.atoix(rstr);
|
|
148
|
+
if (rnum < 1 || thnum < 1 || itnum < 1) usage();
|
|
149
|
+
int rv = procwicked(path, rnum, thnum, itnum);
|
|
150
|
+
return rv;
|
|
151
|
+
}
|
|
152
|
+
/** parse arguments of misc command */
|
|
153
|
+
private static int runmisc(String[] args) {
|
|
154
|
+
String path = null;
|
|
155
|
+
for (int i = 1; i < args.length; i++) {
|
|
156
|
+
String arg = args[i];
|
|
157
|
+
if (path == null && arg.startsWith("-")) {
|
|
158
|
+
usage();
|
|
159
|
+
} else if (path == null) {
|
|
160
|
+
path = arg;
|
|
161
|
+
} else {
|
|
162
|
+
usage();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (path == null) usage();
|
|
166
|
+
int rv = procmisc(path);
|
|
167
|
+
return rv;
|
|
168
|
+
}
|
|
169
|
+
/** parse arguments of memsize command */
|
|
170
|
+
private static int runmemsize(String[] args) {
|
|
171
|
+
String rstr = null;
|
|
172
|
+
String path = null;
|
|
173
|
+
for (int i = 1; i < args.length; i++) {
|
|
174
|
+
String arg = args[i];
|
|
175
|
+
if (path == null && arg.startsWith("-")) {
|
|
176
|
+
usage();
|
|
177
|
+
} else if (rstr == null) {
|
|
178
|
+
rstr = arg;
|
|
179
|
+
} else if (path == null) {
|
|
180
|
+
path = arg;
|
|
181
|
+
} else {
|
|
182
|
+
usage();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
long rnum = rstr != null ? Utility.atoix(rstr) : 1000000;
|
|
186
|
+
if (rnum < 1) usage();
|
|
187
|
+
int rv = procmemsize(rnum, path);
|
|
188
|
+
return rv;
|
|
189
|
+
}
|
|
190
|
+
/** perform order command */
|
|
191
|
+
private static int procorder(String path, long rnum, int thnum, boolean rnd, boolean etc) {
|
|
192
|
+
printf("<In-order Test>\n path=%s rnum=%d thnum=%d rnd=%s etc=%s\n\n",
|
|
193
|
+
path, rnum, thnum, rnd, etc);
|
|
194
|
+
boolean err = false;
|
|
195
|
+
printf("calling utility functions:\n");
|
|
196
|
+
Utility.atoi("123.456mikio");
|
|
197
|
+
Utility.atoix("123.456mikio");
|
|
198
|
+
Utility.atof("123.456mikio");
|
|
199
|
+
Utility.hash_murmur(path.getBytes());
|
|
200
|
+
Utility.hash_fnv(path.getBytes());
|
|
201
|
+
Utility.levdist(path, "casket");
|
|
202
|
+
Utility.levdist(path.getBytes(), "casket".getBytes());
|
|
203
|
+
DB db = new DB();
|
|
204
|
+
int[] codes = { Error.SUCCESS, Error.NOIMPL, Error.MISC };
|
|
205
|
+
db.tune_exception_rule(codes);
|
|
206
|
+
db.tune_encoding("UTF-8");
|
|
207
|
+
printf("opening the database:\n");
|
|
208
|
+
double stime = Utility.time();
|
|
209
|
+
if (!db.open(path, DB.OWRITER | DB.OCREATE | DB.OTRUNCATE)) {
|
|
210
|
+
dberrprint(db, "DB::open");
|
|
211
|
+
err = true;
|
|
212
|
+
}
|
|
213
|
+
double etime = Utility.time();
|
|
214
|
+
printf("time: %.3f\n", etime - stime);
|
|
215
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
216
|
+
printf("setting records:\n");
|
|
217
|
+
stime = Utility.time();
|
|
218
|
+
class Setter extends Thread {
|
|
219
|
+
public Setter(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
220
|
+
id_ = id;
|
|
221
|
+
rnum_ = rnum;
|
|
222
|
+
thnum_ = thnum;
|
|
223
|
+
rnd_ = rnd;
|
|
224
|
+
db_ = db;
|
|
225
|
+
err_ = false;
|
|
226
|
+
}
|
|
227
|
+
public boolean error() {
|
|
228
|
+
return err_;
|
|
229
|
+
}
|
|
230
|
+
public void run() {
|
|
231
|
+
long base = id_ * rnum_;
|
|
232
|
+
long range = rnum_ * thnum_;
|
|
233
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
234
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
235
|
+
if (!db_.set(key, key)) {
|
|
236
|
+
dberrprint(db_, "DB::set");
|
|
237
|
+
err_ = true;
|
|
238
|
+
}
|
|
239
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
240
|
+
printf(".");
|
|
241
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
private int id_;
|
|
246
|
+
private long rnum_;
|
|
247
|
+
private int thnum_;
|
|
248
|
+
private boolean rnd_;
|
|
249
|
+
private DB db_;
|
|
250
|
+
private boolean err_;
|
|
251
|
+
}
|
|
252
|
+
Setter[] setters = new Setter[thnum];
|
|
253
|
+
for (int i = 0; i < thnum; i++) {
|
|
254
|
+
setters[i] = new Setter(i, rnum, thnum, rnd, db);
|
|
255
|
+
setters[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
256
|
+
setters[i].start();
|
|
257
|
+
}
|
|
258
|
+
for (int i = 0; i < thnum; i++) {
|
|
259
|
+
try {
|
|
260
|
+
setters[i].join();
|
|
261
|
+
} catch (java.lang.InterruptedException e) {
|
|
262
|
+
e.printStackTrace();
|
|
263
|
+
err = true;
|
|
264
|
+
}
|
|
265
|
+
if (setters[i].error()) err = true;
|
|
266
|
+
}
|
|
267
|
+
etime = Utility.time();
|
|
268
|
+
dbmetaprint(db, false);
|
|
269
|
+
printf("time: %.3f\n", etime - stime);
|
|
270
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
271
|
+
if (etc) {
|
|
272
|
+
printf("adding records:\n");
|
|
273
|
+
stime = Utility.time();
|
|
274
|
+
class Adder extends Thread {
|
|
275
|
+
public Adder(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
276
|
+
id_ = id;
|
|
277
|
+
rnum_ = rnum;
|
|
278
|
+
thnum_ = thnum;
|
|
279
|
+
rnd_ = rnd;
|
|
280
|
+
db_ = db;
|
|
281
|
+
err_ = false;
|
|
282
|
+
}
|
|
283
|
+
public boolean error() {
|
|
284
|
+
return err_;
|
|
285
|
+
}
|
|
286
|
+
public void run() {
|
|
287
|
+
long base = id_ * rnum_;
|
|
288
|
+
long range = rnum_ * thnum_;
|
|
289
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
290
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
291
|
+
if (!db_.add(key, key) && db_.error().code() != Error.DUPREC) {
|
|
292
|
+
dberrprint(db_, "DB::add");
|
|
293
|
+
err_ = true;
|
|
294
|
+
}
|
|
295
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
296
|
+
printf(".");
|
|
297
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
private int id_;
|
|
302
|
+
private long rnum_;
|
|
303
|
+
private int thnum_;
|
|
304
|
+
private boolean rnd_;
|
|
305
|
+
private DB db_;
|
|
306
|
+
private boolean err_;
|
|
307
|
+
}
|
|
308
|
+
Adder[] adders = new Adder[thnum];
|
|
309
|
+
for (int i = 0; i < thnum; i++) {
|
|
310
|
+
adders[i] = new Adder(i, rnum, thnum, rnd, db);
|
|
311
|
+
adders[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
312
|
+
adders[i].start();
|
|
313
|
+
}
|
|
314
|
+
for (int i = 0; i < thnum; i++) {
|
|
315
|
+
try {
|
|
316
|
+
adders[i].join();
|
|
317
|
+
} catch (java.lang.InterruptedException e) {
|
|
318
|
+
e.printStackTrace();
|
|
319
|
+
err = true;
|
|
320
|
+
}
|
|
321
|
+
if (adders[i].error()) err = true;
|
|
322
|
+
}
|
|
323
|
+
etime = Utility.time();
|
|
324
|
+
dbmetaprint(db, false);
|
|
325
|
+
printf("time: %.3f\n", etime - stime);
|
|
326
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
327
|
+
}
|
|
328
|
+
if (etc) {
|
|
329
|
+
printf("appending records:\n");
|
|
330
|
+
stime = Utility.time();
|
|
331
|
+
class Appender extends Thread {
|
|
332
|
+
public Appender(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
333
|
+
id_ = id;
|
|
334
|
+
rnum_ = rnum;
|
|
335
|
+
thnum_ = thnum;
|
|
336
|
+
rnd_ = rnd;
|
|
337
|
+
db_ = db;
|
|
338
|
+
err_ = false;
|
|
339
|
+
}
|
|
340
|
+
public boolean error() {
|
|
341
|
+
return err_;
|
|
342
|
+
}
|
|
343
|
+
public void run() {
|
|
344
|
+
long base = id_ * rnum_;
|
|
345
|
+
long range = rnum_ * thnum_;
|
|
346
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
347
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
348
|
+
if (!db_.append(key, key)) {
|
|
349
|
+
dberrprint(db_, "DB::append");
|
|
350
|
+
err_ = true;
|
|
351
|
+
}
|
|
352
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
353
|
+
printf(".");
|
|
354
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
private int id_;
|
|
359
|
+
private long rnum_;
|
|
360
|
+
private int thnum_;
|
|
361
|
+
private boolean rnd_;
|
|
362
|
+
private DB db_;
|
|
363
|
+
private boolean err_;
|
|
364
|
+
}
|
|
365
|
+
Appender[] appenders = new Appender[thnum];
|
|
366
|
+
for (int i = 0; i < thnum; i++) {
|
|
367
|
+
appenders[i] = new Appender(i, rnum, thnum, rnd, db);
|
|
368
|
+
appenders[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
369
|
+
appenders[i].start();
|
|
370
|
+
}
|
|
371
|
+
for (int i = 0; i < thnum; i++) {
|
|
372
|
+
try {
|
|
373
|
+
appenders[i].join();
|
|
374
|
+
} catch (java.lang.InterruptedException e) {
|
|
375
|
+
e.printStackTrace();
|
|
376
|
+
err = true;
|
|
377
|
+
}
|
|
378
|
+
if (appenders[i].error()) err = true;
|
|
379
|
+
}
|
|
380
|
+
etime = Utility.time();
|
|
381
|
+
dbmetaprint(db, false);
|
|
382
|
+
printf("time: %.3f\n", etime - stime);
|
|
383
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
384
|
+
}
|
|
385
|
+
if (etc) {
|
|
386
|
+
printf("accepting records:\n");
|
|
387
|
+
stime = Utility.time();
|
|
388
|
+
class Accepter extends Thread {
|
|
389
|
+
public Accepter(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
390
|
+
id_ = id;
|
|
391
|
+
rnum_ = rnum;
|
|
392
|
+
thnum_ = thnum;
|
|
393
|
+
rnd_ = rnd;
|
|
394
|
+
db_ = db;
|
|
395
|
+
err_ = false;
|
|
396
|
+
}
|
|
397
|
+
public boolean error() {
|
|
398
|
+
return err_;
|
|
399
|
+
}
|
|
400
|
+
public void run() {
|
|
401
|
+
class VisitorImpl implements Visitor {
|
|
402
|
+
public VisitorImpl(boolean rnd) {
|
|
403
|
+
rnd_ = rnd;
|
|
404
|
+
cnt_ = 0;
|
|
405
|
+
}
|
|
406
|
+
public byte[] visit_full(byte[] key, byte[] value) {
|
|
407
|
+
cnt_++;
|
|
408
|
+
if (cnt_ % 100 == 0) Thread.yield();
|
|
409
|
+
byte[] rv = NOP;
|
|
410
|
+
if (rnd_) {
|
|
411
|
+
switch ((int)rand(7)) {
|
|
412
|
+
case 0: {
|
|
413
|
+
rv = String.format("%d", cnt_).getBytes();
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
case 1: {
|
|
417
|
+
rv = REMOVE;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return rv;
|
|
423
|
+
}
|
|
424
|
+
public byte[] visit_empty(byte[] key) {
|
|
425
|
+
return visit_full(key, key);
|
|
426
|
+
}
|
|
427
|
+
private boolean rnd_;
|
|
428
|
+
private long cnt_;
|
|
429
|
+
}
|
|
430
|
+
Visitor visitor = new VisitorImpl(rnd_);
|
|
431
|
+
long base = id_ * rnum_;
|
|
432
|
+
long range = rnum_ * thnum_;
|
|
433
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
434
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
435
|
+
if (!db_.accept(key.getBytes(), visitor, rnd_)) {
|
|
436
|
+
dberrprint(db_, "DB::accept");
|
|
437
|
+
err_ = true;
|
|
438
|
+
}
|
|
439
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
440
|
+
printf(".");
|
|
441
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
private int id_;
|
|
446
|
+
private long rnum_;
|
|
447
|
+
private int thnum_;
|
|
448
|
+
private boolean rnd_;
|
|
449
|
+
private DB db_;
|
|
450
|
+
private boolean err_;
|
|
451
|
+
}
|
|
452
|
+
Accepter[] accepters = new Accepter[thnum];
|
|
453
|
+
for (int i = 0; i < thnum; i++) {
|
|
454
|
+
accepters[i] = new Accepter(i, rnum, thnum, rnd, db);
|
|
455
|
+
accepters[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
456
|
+
accepters[i].start();
|
|
457
|
+
}
|
|
458
|
+
for (int i = 0; i < thnum; i++) {
|
|
459
|
+
try {
|
|
460
|
+
accepters[i].join();
|
|
461
|
+
} catch (java.lang.InterruptedException e) {
|
|
462
|
+
e.printStackTrace();
|
|
463
|
+
err = true;
|
|
464
|
+
}
|
|
465
|
+
if (accepters[i].error()) err = true;
|
|
466
|
+
}
|
|
467
|
+
etime = Utility.time();
|
|
468
|
+
dbmetaprint(db, false);
|
|
469
|
+
printf("time: %.3f\n", etime - stime);
|
|
470
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
471
|
+
}
|
|
472
|
+
printf("getting records:\n");
|
|
473
|
+
stime = Utility.time();
|
|
474
|
+
class Getter extends Thread {
|
|
475
|
+
public Getter(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
476
|
+
id_ = id;
|
|
477
|
+
rnum_ = rnum;
|
|
478
|
+
thnum_ = thnum;
|
|
479
|
+
rnd_ = rnd;
|
|
480
|
+
db_ = db;
|
|
481
|
+
err_ = false;
|
|
482
|
+
}
|
|
483
|
+
public boolean error() {
|
|
484
|
+
return err_;
|
|
485
|
+
}
|
|
486
|
+
public void run() {
|
|
487
|
+
long base = id_ * rnum_;
|
|
488
|
+
long range = rnum_ * thnum_;
|
|
489
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
490
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
491
|
+
if (db_.get(key) == null && db_.error().code() != Error.NOREC) {
|
|
492
|
+
dberrprint(db_, "DB::get");
|
|
493
|
+
err_ = true;
|
|
494
|
+
}
|
|
495
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
496
|
+
printf(".");
|
|
497
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
private int id_;
|
|
502
|
+
private long rnum_;
|
|
503
|
+
private int thnum_;
|
|
504
|
+
private boolean rnd_;
|
|
505
|
+
private DB db_;
|
|
506
|
+
private boolean err_;
|
|
507
|
+
}
|
|
508
|
+
Getter[] getters = new Getter[thnum];
|
|
509
|
+
for (int i = 0; i < thnum; i++) {
|
|
510
|
+
getters[i] = new Getter(i, rnum, thnum, rnd, db);
|
|
511
|
+
getters[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
512
|
+
getters[i].start();
|
|
513
|
+
}
|
|
514
|
+
for (int i = 0; i < thnum; i++) {
|
|
515
|
+
try {
|
|
516
|
+
getters[i].join();
|
|
517
|
+
} catch (java.lang.InterruptedException e) {
|
|
518
|
+
e.printStackTrace();
|
|
519
|
+
err = true;
|
|
520
|
+
}
|
|
521
|
+
if (getters[i].error()) err = true;
|
|
522
|
+
}
|
|
523
|
+
etime = Utility.time();
|
|
524
|
+
dbmetaprint(db, false);
|
|
525
|
+
printf("time: %.3f\n", etime - stime);
|
|
526
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
527
|
+
if (etc) {
|
|
528
|
+
printf("traversing the database by the inner iterator:\n");
|
|
529
|
+
stime = Utility.time();
|
|
530
|
+
class InnerTraverser extends Thread {
|
|
531
|
+
public InnerTraverser(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
532
|
+
id_ = id;
|
|
533
|
+
rnum_ = rnum;
|
|
534
|
+
thnum_ = thnum;
|
|
535
|
+
rnd_ = rnd;
|
|
536
|
+
db_ = db;
|
|
537
|
+
err_ = false;
|
|
538
|
+
}
|
|
539
|
+
public boolean error() {
|
|
540
|
+
return err_;
|
|
541
|
+
}
|
|
542
|
+
public void run() {
|
|
543
|
+
class VisitorImpl implements Visitor {
|
|
544
|
+
public VisitorImpl(int id, boolean rnd) {
|
|
545
|
+
id_ = id;
|
|
546
|
+
rnd_ = rnd;
|
|
547
|
+
cnt_ = 0;
|
|
548
|
+
}
|
|
549
|
+
public byte[] visit_full(byte[] key, byte[] value) {
|
|
550
|
+
cnt_++;
|
|
551
|
+
if (cnt_ % 100 == 0) Thread.yield();
|
|
552
|
+
byte[] rv = NOP;
|
|
553
|
+
if (rnd_) {
|
|
554
|
+
switch ((int)rand(7)) {
|
|
555
|
+
case 0: {
|
|
556
|
+
rv = String.format("%d%d", cnt_, cnt_).getBytes();
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
case 1: {
|
|
560
|
+
rv = REMOVE;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (id_ < 1 && rnum_ > 250 && cnt_ % (rnum_ / 250) == 0) {
|
|
566
|
+
printf(".");
|
|
567
|
+
if (cnt_ == rnum_ || cnt_ % (rnum_ / 10) == 0) printf(" (%08d)\n", cnt_);
|
|
568
|
+
}
|
|
569
|
+
return rv;
|
|
570
|
+
}
|
|
571
|
+
public byte[] visit_empty(byte[] key) {
|
|
572
|
+
return NOP;
|
|
573
|
+
}
|
|
574
|
+
private int id_;
|
|
575
|
+
private boolean rnd_;
|
|
576
|
+
private long cnt_;
|
|
577
|
+
}
|
|
578
|
+
Visitor visitor = new VisitorImpl(id_, rnd_);
|
|
579
|
+
if (!db_.iterate(visitor, rnd_)) {
|
|
580
|
+
dberrprint(db_, "DB::iterate");
|
|
581
|
+
err_ = true;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
private int id_;
|
|
585
|
+
private long rnum_;
|
|
586
|
+
private int thnum_;
|
|
587
|
+
private boolean rnd_;
|
|
588
|
+
private DB db_;
|
|
589
|
+
private boolean err_;
|
|
590
|
+
}
|
|
591
|
+
InnerTraverser[] itraversers = new InnerTraverser[thnum];
|
|
592
|
+
for (int i = 0; i < thnum; i++) {
|
|
593
|
+
itraversers[i] = new InnerTraverser(i, rnum, thnum, rnd, db);
|
|
594
|
+
itraversers[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
595
|
+
itraversers[i].start();
|
|
596
|
+
}
|
|
597
|
+
for (int i = 0; i < thnum; i++) {
|
|
598
|
+
try {
|
|
599
|
+
itraversers[i].join();
|
|
600
|
+
} catch (java.lang.InterruptedException e) {
|
|
601
|
+
e.printStackTrace();
|
|
602
|
+
err = true;
|
|
603
|
+
}
|
|
604
|
+
if (itraversers[i].error()) err = true;
|
|
605
|
+
}
|
|
606
|
+
if (rnd) printf(" (end)\n");
|
|
607
|
+
etime = Utility.time();
|
|
608
|
+
dbmetaprint(db, false);
|
|
609
|
+
printf("time: %.3f\n", etime - stime);
|
|
610
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
611
|
+
}
|
|
612
|
+
if (etc) {
|
|
613
|
+
printf("traversing the database by the outer cursor:\n");
|
|
614
|
+
stime = Utility.time();
|
|
615
|
+
class OuterTraverser extends Thread {
|
|
616
|
+
public OuterTraverser(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
617
|
+
id_ = id;
|
|
618
|
+
rnum_ = rnum;
|
|
619
|
+
thnum_ = thnum;
|
|
620
|
+
rnd_ = rnd;
|
|
621
|
+
db_ = db;
|
|
622
|
+
err_ = false;
|
|
623
|
+
}
|
|
624
|
+
public boolean error() {
|
|
625
|
+
return err_;
|
|
626
|
+
}
|
|
627
|
+
public void run() {
|
|
628
|
+
class VisitorImpl implements Visitor {
|
|
629
|
+
public VisitorImpl(int id, long rnum, boolean rnd) {
|
|
630
|
+
id_ = id;
|
|
631
|
+
rnum_ = rnum;
|
|
632
|
+
rnd_ = rnd;
|
|
633
|
+
cnt_ = 0;
|
|
634
|
+
}
|
|
635
|
+
public byte[] visit_full(byte[] key, byte[] value) {
|
|
636
|
+
cnt_++;
|
|
637
|
+
if (cnt_ % 100 == 0) Thread.yield();
|
|
638
|
+
byte[] rv = NOP;
|
|
639
|
+
if (rnd_) {
|
|
640
|
+
switch ((int)rand(7)) {
|
|
641
|
+
case 0: {
|
|
642
|
+
rv = String.format("%d%d", cnt_, cnt_).getBytes();
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
case 1: {
|
|
646
|
+
rv = REMOVE;
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (id_ < 1 && rnum_ > 250 && cnt_ % (rnum_ / 250) == 0) {
|
|
652
|
+
printf(".");
|
|
653
|
+
if (cnt_ == rnum_ || cnt_ % (rnum_ / 10) == 0) printf(" (%08d)\n", cnt_);
|
|
654
|
+
}
|
|
655
|
+
return rv;
|
|
656
|
+
}
|
|
657
|
+
public byte[] visit_empty(byte[] key) {
|
|
658
|
+
return NOP;
|
|
659
|
+
}
|
|
660
|
+
private int id_;
|
|
661
|
+
private long rnum_;
|
|
662
|
+
private boolean rnd_;
|
|
663
|
+
private long cnt_;
|
|
664
|
+
}
|
|
665
|
+
Visitor visitor = new VisitorImpl(id_, rnum_, rnd_);
|
|
666
|
+
Cursor cur = db_.cursor();
|
|
667
|
+
if (!cur.jump() && db_.error().code() != Error.NOREC) {
|
|
668
|
+
dberrprint(db_, "Cursor::jump");
|
|
669
|
+
err_ = true;
|
|
670
|
+
}
|
|
671
|
+
while (cur.accept(visitor, rnd_, false)) {
|
|
672
|
+
if (!cur.step() && db_.error().code() != Error.NOREC) {
|
|
673
|
+
dberrprint(db_, "Cursor::step");
|
|
674
|
+
err_ = true;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (db_.error().code() != Error.NOREC) {
|
|
678
|
+
dberrprint(db_, "Cursor::jump");
|
|
679
|
+
err_ = true;
|
|
680
|
+
}
|
|
681
|
+
if (!rnd_ || rand(2) == 0) cur.disable();
|
|
682
|
+
}
|
|
683
|
+
private int id_;
|
|
684
|
+
private long rnum_;
|
|
685
|
+
private int thnum_;
|
|
686
|
+
private boolean rnd_;
|
|
687
|
+
private DB db_;
|
|
688
|
+
private boolean err_;
|
|
689
|
+
}
|
|
690
|
+
OuterTraverser[] otraversers = new OuterTraverser[thnum];
|
|
691
|
+
for (int i = 0; i < thnum; i++) {
|
|
692
|
+
otraversers[i] = new OuterTraverser(i, rnum, thnum, rnd, db);
|
|
693
|
+
otraversers[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
694
|
+
otraversers[i].start();
|
|
695
|
+
}
|
|
696
|
+
for (int i = 0; i < thnum; i++) {
|
|
697
|
+
try {
|
|
698
|
+
otraversers[i].join();
|
|
699
|
+
} catch (java.lang.InterruptedException e) {
|
|
700
|
+
e.printStackTrace();
|
|
701
|
+
err = true;
|
|
702
|
+
}
|
|
703
|
+
if (otraversers[i].error()) err = true;
|
|
704
|
+
}
|
|
705
|
+
printf(" (end)\n");
|
|
706
|
+
etime = Utility.time();
|
|
707
|
+
dbmetaprint(db, false);
|
|
708
|
+
printf("time: %.3f\n", etime - stime);
|
|
709
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
710
|
+
}
|
|
711
|
+
printf("removing records:\n");
|
|
712
|
+
stime = Utility.time();
|
|
713
|
+
class Remover extends Thread {
|
|
714
|
+
public Remover(int id, long rnum, int thnum, boolean rnd, DB db) {
|
|
715
|
+
id_ = id;
|
|
716
|
+
rnum_ = rnum;
|
|
717
|
+
thnum_ = thnum;
|
|
718
|
+
rnd_ = rnd;
|
|
719
|
+
db_ = db;
|
|
720
|
+
err_ = false;
|
|
721
|
+
}
|
|
722
|
+
public boolean error() {
|
|
723
|
+
return err_;
|
|
724
|
+
}
|
|
725
|
+
public void run() {
|
|
726
|
+
long base = id_ * rnum_;
|
|
727
|
+
long range = rnum_ * thnum_;
|
|
728
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
729
|
+
String key = String.format("%08d", rnd_ ? rand(range) + 1 : base + i);
|
|
730
|
+
if (!db_.remove(key) && db_.error().code() != Error.NOREC) {
|
|
731
|
+
dberrprint(db_, "DB::remove");
|
|
732
|
+
err_ = true;
|
|
733
|
+
}
|
|
734
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
735
|
+
printf(".");
|
|
736
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
private int id_;
|
|
741
|
+
private long rnum_;
|
|
742
|
+
private int thnum_;
|
|
743
|
+
private boolean rnd_;
|
|
744
|
+
private DB db_;
|
|
745
|
+
private boolean err_;
|
|
746
|
+
}
|
|
747
|
+
Remover[] removers = new Remover[thnum];
|
|
748
|
+
for (int i = 0; i < thnum; i++) {
|
|
749
|
+
removers[i] = new Remover(i, rnum, thnum, rnd, db);
|
|
750
|
+
removers[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
751
|
+
removers[i].start();
|
|
752
|
+
}
|
|
753
|
+
for (int i = 0; i < thnum; i++) {
|
|
754
|
+
try {
|
|
755
|
+
removers[i].join();
|
|
756
|
+
} catch (java.lang.InterruptedException e) {
|
|
757
|
+
e.printStackTrace();
|
|
758
|
+
err = true;
|
|
759
|
+
}
|
|
760
|
+
if (removers[i].error()) err = true;
|
|
761
|
+
}
|
|
762
|
+
etime = Utility.time();
|
|
763
|
+
dbmetaprint(db, true);
|
|
764
|
+
printf("time: %.3f\n", etime - stime);
|
|
765
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
766
|
+
printf("closing the database:\n");
|
|
767
|
+
stime = Utility.time();
|
|
768
|
+
if (!db.close()) {
|
|
769
|
+
dberrprint(db, "DB::close");
|
|
770
|
+
err = true;
|
|
771
|
+
}
|
|
772
|
+
etime = Utility.time();
|
|
773
|
+
printf("time: %.3f\n", etime - stime);
|
|
774
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
775
|
+
printf("%s\n\n", err ? "error" : "ok");
|
|
776
|
+
return err ? 1 : 0;
|
|
777
|
+
}
|
|
778
|
+
/** perform wicked command */
|
|
779
|
+
private static int procwicked(String path, long rnum, int thnum, int itnum) {
|
|
780
|
+
printf("<Wicked Test>\n path=%s rnum=%d thnum=%d itnum=%d\n\n",
|
|
781
|
+
path, rnum, thnum, itnum);
|
|
782
|
+
boolean err = false;
|
|
783
|
+
DB db = new DB();
|
|
784
|
+
int[] codes = { Error.SUCCESS, Error.NOIMPL, Error.MISC };
|
|
785
|
+
db.tune_exception_rule(codes);
|
|
786
|
+
db.tune_encoding("UTF-8");
|
|
787
|
+
for (int itcnt = 1; itcnt <= itnum; itcnt++) {
|
|
788
|
+
if (itnum > 1) printf("iteration %d:\n", itcnt);
|
|
789
|
+
double stime = Utility.time();
|
|
790
|
+
int omode = DB.OWRITER | DB.OCREATE;
|
|
791
|
+
if (itcnt == 1) omode |= DB.OTRUNCATE;
|
|
792
|
+
if (!db.open(path, omode)) {
|
|
793
|
+
dberrprint(db, "DB::open");
|
|
794
|
+
err = true;
|
|
795
|
+
}
|
|
796
|
+
class Operator extends Thread {
|
|
797
|
+
public Operator(int id, long rnum, int thnum, DB db) {
|
|
798
|
+
id_ = id;
|
|
799
|
+
rnum_ = rnum;
|
|
800
|
+
thnum_ = thnum;
|
|
801
|
+
db_ = db;
|
|
802
|
+
err_ = false;
|
|
803
|
+
}
|
|
804
|
+
public boolean error() {
|
|
805
|
+
return err_;
|
|
806
|
+
}
|
|
807
|
+
public void run() {
|
|
808
|
+
class VisitorImpl implements Visitor {
|
|
809
|
+
public VisitorImpl() {
|
|
810
|
+
cnt_ = 0;
|
|
811
|
+
}
|
|
812
|
+
public byte[] visit_full(byte[] key, byte[] value) {
|
|
813
|
+
cnt_++;
|
|
814
|
+
if (cnt_ % 100 == 0) Thread.yield();
|
|
815
|
+
byte[] rv = NOP;
|
|
816
|
+
switch ((int)rand(7)) {
|
|
817
|
+
case 0: {
|
|
818
|
+
rv = String.format("%d", cnt_).getBytes();
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
case 1: {
|
|
822
|
+
rv = REMOVE;
|
|
823
|
+
break;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return rv;
|
|
827
|
+
}
|
|
828
|
+
public byte[] visit_empty(byte[] key) {
|
|
829
|
+
return visit_full(key, key);
|
|
830
|
+
}
|
|
831
|
+
private long cnt_;
|
|
832
|
+
}
|
|
833
|
+
Visitor visitor = new VisitorImpl();
|
|
834
|
+
Cursor cur = db_.cursor();
|
|
835
|
+
long range = rnum_ * thnum_;
|
|
836
|
+
for (long i = 1; !err_ && i <= rnum_; i++) {
|
|
837
|
+
boolean tran = rand(100) == 0;
|
|
838
|
+
if (tran && !db_.begin_transaction(rand(rnum_) == 0)) {
|
|
839
|
+
dberrprint(db_, "DB::begin_transaction");
|
|
840
|
+
tran = false;
|
|
841
|
+
err_ = true;
|
|
842
|
+
}
|
|
843
|
+
String key = String.format("%08d", rand(range) + 1);
|
|
844
|
+
switch ((int)rand(12)) {
|
|
845
|
+
case 0: {
|
|
846
|
+
if (!db_.set(key, key)) {
|
|
847
|
+
dberrprint(db_, "DB::set");
|
|
848
|
+
err_ = true;
|
|
849
|
+
}
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
case 1: {
|
|
853
|
+
if (!db_.add(key, key) && db_.error().code() != Error.DUPREC) {
|
|
854
|
+
dberrprint(db_, "DB::add");
|
|
855
|
+
err_ = true;
|
|
856
|
+
}
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
case 2: {
|
|
860
|
+
if (!db_.replace(key, key) && db_.error().code() != Error.NOREC) {
|
|
861
|
+
dberrprint(db_, "DB::replace");
|
|
862
|
+
err_ = true;
|
|
863
|
+
}
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
case 3: {
|
|
867
|
+
if (!db_.append(key, key)) {
|
|
868
|
+
dberrprint(db_, "DB::append");
|
|
869
|
+
err_ = true;
|
|
870
|
+
}
|
|
871
|
+
break;
|
|
872
|
+
}
|
|
873
|
+
case 4: {
|
|
874
|
+
if (rand(2) == 0) {
|
|
875
|
+
if (db_.increment(key, rand(10), 0) == Long.MIN_VALUE &&
|
|
876
|
+
db_.error().code() != Error.LOGIC) {
|
|
877
|
+
dberrprint(db_, "DB::increment");
|
|
878
|
+
err_ = true;
|
|
879
|
+
}
|
|
880
|
+
} else {
|
|
881
|
+
if (Double.isNaN(db_.increment_double(key, rand(1000) / 100.0, 0)) &&
|
|
882
|
+
db_.error().code() != Error.LOGIC) {
|
|
883
|
+
dberrprint(db_, "DB::increment_double");
|
|
884
|
+
err_ = true;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
break;
|
|
888
|
+
}
|
|
889
|
+
case 5: {
|
|
890
|
+
if (!db_.cas(key, key, key) && db_.error().code() != Error.LOGIC) {
|
|
891
|
+
dberrprint(db_, "DB::cas");
|
|
892
|
+
err_ = true;
|
|
893
|
+
}
|
|
894
|
+
break;
|
|
895
|
+
}
|
|
896
|
+
case 6: {
|
|
897
|
+
if (!db_.remove(key) && db_.error().code() != Error.NOREC) {
|
|
898
|
+
dberrprint(db_, "DB::remove");
|
|
899
|
+
err_ = true;
|
|
900
|
+
}
|
|
901
|
+
break;
|
|
902
|
+
}
|
|
903
|
+
case 7: {
|
|
904
|
+
if (!db_.accept(key.getBytes(), visitor, true)) {
|
|
905
|
+
dberrprint(db_, "DB::accept");
|
|
906
|
+
err_ = true;
|
|
907
|
+
}
|
|
908
|
+
break;
|
|
909
|
+
}
|
|
910
|
+
case 8: {
|
|
911
|
+
if (rand(10) == 0) {
|
|
912
|
+
if (rand(4) == 0) {
|
|
913
|
+
try {
|
|
914
|
+
if (!cur.jump_back(key) && db_.error().code() != Error.NOREC) {
|
|
915
|
+
dberrprint(db_, "Cursor::jump_back");
|
|
916
|
+
err_ = true;
|
|
917
|
+
}
|
|
918
|
+
} catch (Error.XNOIMPL e) {}
|
|
919
|
+
} else {
|
|
920
|
+
if (!cur.jump(key) && db_.error().code() != Error.NOREC) {
|
|
921
|
+
dberrprint(db_, "Cursor::jump");
|
|
922
|
+
err_ = true;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
} else {
|
|
926
|
+
switch ((int)rand(6)) {
|
|
927
|
+
case 0: {
|
|
928
|
+
if (cur.get_key_str(false) == null &&
|
|
929
|
+
db_.error().code() != Error.NOREC) {
|
|
930
|
+
dberrprint(db_, "Cursor::get_key");
|
|
931
|
+
err_ = true;
|
|
932
|
+
}
|
|
933
|
+
break;
|
|
934
|
+
}
|
|
935
|
+
case 1: {
|
|
936
|
+
if (cur.get_value_str(false) == null &&
|
|
937
|
+
db_.error().code() != Error.NOREC) {
|
|
938
|
+
dberrprint(db_, "Cursor::get_value");
|
|
939
|
+
err_ = true;
|
|
940
|
+
}
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
case 2: {
|
|
944
|
+
if (cur.get_str(false) == null &&
|
|
945
|
+
db_.error().code() != Error.NOREC) {
|
|
946
|
+
dberrprint(db_, "Cursor::get");
|
|
947
|
+
err_ = true;
|
|
948
|
+
}
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
case 3: {
|
|
952
|
+
if (!cur.remove() && db_.error().code() != Error.NOREC) {
|
|
953
|
+
dberrprint(db_, "Cursor::remove");
|
|
954
|
+
err_ = true;
|
|
955
|
+
}
|
|
956
|
+
break;
|
|
957
|
+
}
|
|
958
|
+
default: {
|
|
959
|
+
if (!cur.accept(visitor, true, rand(2) == 0) &&
|
|
960
|
+
db_.error().code() != Error.NOREC) {
|
|
961
|
+
dberrprint(db_, "Cursor::accept");
|
|
962
|
+
err_ = true;
|
|
963
|
+
}
|
|
964
|
+
break;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
if (rand(2) == 0) {
|
|
969
|
+
if (!cur.step() && db_.error().code() != Error.NOREC) {
|
|
970
|
+
dberrprint(db_, "Cursor::step");
|
|
971
|
+
err_ = true;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
if (rand(rnum_ / 50 + 1) == 0) {
|
|
975
|
+
String prefix = key.substring(0, key.length() - 1);
|
|
976
|
+
if (db_.match_prefix(prefix, rand(10)) == null) {
|
|
977
|
+
dberrprint(db_, "DB::match_prefix");
|
|
978
|
+
err_ = true;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
if (rand(rnum_ / 50 + 1) == 0) {
|
|
982
|
+
String regex = key.substring(0, key.length() - 1);
|
|
983
|
+
if (db_.match_regex(regex, rand(10)) == null &&
|
|
984
|
+
db_.error().code() != Error.LOGIC) {
|
|
985
|
+
dberrprint(db_, "DB::match_regex");
|
|
986
|
+
err_ = true;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (rand(rnum_ / 50 + 1) == 0) {
|
|
990
|
+
String origin = key.substring(0, key.length() - 1);
|
|
991
|
+
if (db_.match_similar(origin, 3, rand(2) == 0, rand(10)) == null) {
|
|
992
|
+
dberrprint(db_, "DB::match_similar");
|
|
993
|
+
err_ = true;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
if (rand(10) == 0) {
|
|
997
|
+
Cursor paracur = db_.cursor();
|
|
998
|
+
paracur.jump(key);
|
|
999
|
+
if (!paracur.accept(visitor, true, rand(2) == 0) &&
|
|
1000
|
+
db_.error().code() != Error.NOREC) {
|
|
1001
|
+
dberrprint(db_, "Cursor::accept");
|
|
1002
|
+
err_ = true;
|
|
1003
|
+
}
|
|
1004
|
+
paracur.disable();
|
|
1005
|
+
}
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
default: {
|
|
1009
|
+
if (db_.get(key) == null && db_.error().code() != Error.NOREC) {
|
|
1010
|
+
dberrprint(db_, "DB::get");
|
|
1011
|
+
err_ = true;
|
|
1012
|
+
}
|
|
1013
|
+
break;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
if (tran) {
|
|
1017
|
+
if (rand(10) == 0) Thread.yield();
|
|
1018
|
+
if (!db_.end_transaction(rand(10) > 0)) {
|
|
1019
|
+
dberrprint(db_, "DB::end_transaction");
|
|
1020
|
+
err_ = true;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
|
|
1024
|
+
printf(".");
|
|
1025
|
+
if (i == rnum_ || i % (rnum_ / 10) == 0) printf(" (%08d)\n", i);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
if (rand(2) == 0) cur.disable();
|
|
1029
|
+
}
|
|
1030
|
+
private int id_;
|
|
1031
|
+
private long rnum_;
|
|
1032
|
+
private int thnum_;
|
|
1033
|
+
private DB db_;
|
|
1034
|
+
private boolean err_;
|
|
1035
|
+
}
|
|
1036
|
+
Operator[] operators = new Operator[thnum];
|
|
1037
|
+
for (int i = 0; i < thnum; i++) {
|
|
1038
|
+
operators[i] = new Operator(i, rnum, thnum, db);
|
|
1039
|
+
operators[i].setDefaultUncaughtExceptionHandler(EXH);
|
|
1040
|
+
operators[i].start();
|
|
1041
|
+
}
|
|
1042
|
+
for (int i = 0; i < thnum; i++) {
|
|
1043
|
+
try {
|
|
1044
|
+
operators[i].join();
|
|
1045
|
+
} catch (java.lang.InterruptedException e) {
|
|
1046
|
+
e.printStackTrace();
|
|
1047
|
+
err = true;
|
|
1048
|
+
}
|
|
1049
|
+
if (operators[i].error()) err = true;
|
|
1050
|
+
}
|
|
1051
|
+
dbmetaprint(db, itcnt == itnum);
|
|
1052
|
+
if (!db.close()) {
|
|
1053
|
+
dberrprint(db, "DB::close");
|
|
1054
|
+
err = true;
|
|
1055
|
+
}
|
|
1056
|
+
double etime = Utility.time();
|
|
1057
|
+
printf("time: %.3f\n", etime - stime);
|
|
1058
|
+
printf("memory: %.3f\n", memusage() / 1024.0 / 1024.0);
|
|
1059
|
+
}
|
|
1060
|
+
printf("%s\n\n", err ? "error" : "ok");
|
|
1061
|
+
return err ? 1 : 0;
|
|
1062
|
+
}
|
|
1063
|
+
/** perform order command */
|
|
1064
|
+
private static int procmisc(String path) {
|
|
1065
|
+
printf("<Miscellaneous Test>\n path=%s\n\n", path);
|
|
1066
|
+
boolean err = false;
|
|
1067
|
+
Utility.atoi("123.456abc");
|
|
1068
|
+
Utility.atoix("123.456abc");
|
|
1069
|
+
Utility.atof("123.456abc");
|
|
1070
|
+
Utility.hash_murmur(path.getBytes());
|
|
1071
|
+
Utility.hash_fnv(path.getBytes());
|
|
1072
|
+
List<Cursor> dcurs = new ArrayList<Cursor>();
|
|
1073
|
+
printf("opening the database:\n");
|
|
1074
|
+
DB db = new DB();
|
|
1075
|
+
try {
|
|
1076
|
+
if (!db.open(path, DB.OWRITER | DB.OCREATE | DB.OTRUNCATE)) {
|
|
1077
|
+
dberrprint(db, "DB::open");
|
|
1078
|
+
err = true;
|
|
1079
|
+
}
|
|
1080
|
+
int[] codes = { Error.SUCCESS, Error.NOIMPL, Error.MISC };
|
|
1081
|
+
db.tune_exception_rule(codes);
|
|
1082
|
+
db.tune_encoding("UTF-8");
|
|
1083
|
+
db.toString();
|
|
1084
|
+
long rnum = 10000;
|
|
1085
|
+
printf("setting records:\n");
|
|
1086
|
+
for (long i = 0; i < rnum; i++) {
|
|
1087
|
+
String key = String.format("%d", i);
|
|
1088
|
+
db.set(key, key);
|
|
1089
|
+
}
|
|
1090
|
+
if (db.count() != rnum) {
|
|
1091
|
+
dberrprint(db, "DB::count");
|
|
1092
|
+
err = true;
|
|
1093
|
+
}
|
|
1094
|
+
printf("deploying cursors:\n");
|
|
1095
|
+
for (int i = 1; i < 100; i++) {
|
|
1096
|
+
Cursor cur = db.cursor();
|
|
1097
|
+
String key = String.format("%d", i);
|
|
1098
|
+
if (!cur.jump(key)) {
|
|
1099
|
+
dberrprint(db, "Cursor::jump");
|
|
1100
|
+
err = true;
|
|
1101
|
+
}
|
|
1102
|
+
switch (i % 3) {
|
|
1103
|
+
case 0: {
|
|
1104
|
+
dcurs.add(cur);
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
case 1: {
|
|
1108
|
+
cur.disable();
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
cur.toString();
|
|
1113
|
+
}
|
|
1114
|
+
printf("getting records:\n");
|
|
1115
|
+
for (Cursor cur : dcurs) {
|
|
1116
|
+
if (cur.get_key(false) == null) {
|
|
1117
|
+
dberrprint(db, "Cursor::get_key");
|
|
1118
|
+
err = true;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
printf("accepting visitor:\n");
|
|
1122
|
+
class VisitorImpl implements Visitor {
|
|
1123
|
+
public byte[] visit_full(byte[] key, byte[] value) {
|
|
1124
|
+
byte[] rv = NOP;
|
|
1125
|
+
String kstr = new String(key);
|
|
1126
|
+
switch (Integer.parseInt(kstr) % 3) {
|
|
1127
|
+
case 0: {
|
|
1128
|
+
rv = String.format("full:%s", kstr).getBytes();
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
case 1: {
|
|
1132
|
+
rv = REMOVE;
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return rv;
|
|
1137
|
+
}
|
|
1138
|
+
public byte[] visit_empty(byte[] key) {
|
|
1139
|
+
byte[] rv = NOP;
|
|
1140
|
+
String kstr = new String(key);
|
|
1141
|
+
switch (Integer.parseInt(kstr) % 3) {
|
|
1142
|
+
case 0: {
|
|
1143
|
+
rv = String.format("empty:%s", kstr).getBytes();
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
case 1: {
|
|
1147
|
+
rv = REMOVE;
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return rv;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
VisitorImpl visitor = new VisitorImpl();
|
|
1155
|
+
long end = rnum * 2;
|
|
1156
|
+
for (long i = 0; i < end; i++) {
|
|
1157
|
+
byte[] key = String.format("%d", i).getBytes();
|
|
1158
|
+
if (!db.accept(key, visitor, true)) {
|
|
1159
|
+
dberrprint(db, "DB::accept");
|
|
1160
|
+
err = true;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
printf("accepting visitor with a cursor:\n");
|
|
1164
|
+
Cursor cur = db.cursor();
|
|
1165
|
+
try {
|
|
1166
|
+
if (!cur.jump_back()) {
|
|
1167
|
+
dberrprint(db, "Cursor::jump");
|
|
1168
|
+
err = true;
|
|
1169
|
+
}
|
|
1170
|
+
while (cur.accept(visitor, true, false)) {
|
|
1171
|
+
cur.step_back();
|
|
1172
|
+
}
|
|
1173
|
+
} catch (Error.XNOIMPL e) {
|
|
1174
|
+
if (!cur.jump()) {
|
|
1175
|
+
dberrprint(db, "Cursor::jump");
|
|
1176
|
+
err = true;
|
|
1177
|
+
}
|
|
1178
|
+
while (cur.accept(visitor, true, false)) {
|
|
1179
|
+
cur.step();
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
printf("accepting visitor in bulk:\n");
|
|
1183
|
+
byte[][] keys = new byte[10][];
|
|
1184
|
+
for (int i = 0; i < keys.length; i++) {
|
|
1185
|
+
keys[i] = String.format("%d", i).getBytes();
|
|
1186
|
+
}
|
|
1187
|
+
if (!db.accept_bulk(keys, visitor, true)) {
|
|
1188
|
+
dberrprint(db, "DB::accept_bulk");
|
|
1189
|
+
err = true;
|
|
1190
|
+
}
|
|
1191
|
+
byte[][] recs = new byte[20][];
|
|
1192
|
+
for (int i = 0; i < recs.length; i++) {
|
|
1193
|
+
recs[i] = String.format("%d", i).getBytes();
|
|
1194
|
+
}
|
|
1195
|
+
if (db.set_bulk(recs, true) != recs.length / 2) {
|
|
1196
|
+
dberrprint(db, "DB::set_bulk");
|
|
1197
|
+
err = true;
|
|
1198
|
+
}
|
|
1199
|
+
if (db.get_bulk(keys, true) == null) {
|
|
1200
|
+
dberrprint(db, "DB::get_bulk");
|
|
1201
|
+
err = true;
|
|
1202
|
+
}
|
|
1203
|
+
if (db.remove_bulk(keys, true) < 0) {
|
|
1204
|
+
dberrprint(db, "DB::remove_bulk");
|
|
1205
|
+
err = true;
|
|
1206
|
+
}
|
|
1207
|
+
Map<String, String> recmap = new HashMap<String, String>();
|
|
1208
|
+
recmap.put("one", "first");
|
|
1209
|
+
recmap.put("two", "second");
|
|
1210
|
+
if (db.set_bulk(recmap, false) != recmap.size()) {
|
|
1211
|
+
dberrprint(db, "DB::set_bulk");
|
|
1212
|
+
err = true;
|
|
1213
|
+
}
|
|
1214
|
+
List<String> keylist = new ArrayList<String>();
|
|
1215
|
+
keylist.add("one");
|
|
1216
|
+
keylist.add("two");
|
|
1217
|
+
recmap = db.get_bulk(keylist, false);
|
|
1218
|
+
if (recmap == null || recmap.size() != keylist.size()) {
|
|
1219
|
+
dberrprint(db, "DB::get_bulk");
|
|
1220
|
+
err = true;
|
|
1221
|
+
}
|
|
1222
|
+
if (db.remove_bulk(keylist, false) != keylist.size()) {
|
|
1223
|
+
dberrprint(db, "DB::remove_bulk");
|
|
1224
|
+
err = true;
|
|
1225
|
+
}
|
|
1226
|
+
printf("synchronizing the database:\n");
|
|
1227
|
+
class Informer implements FileProcessor {
|
|
1228
|
+
public boolean process(String path, long count, long size) {
|
|
1229
|
+
return true;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
Informer informer = new Informer();
|
|
1233
|
+
if (!db.synchronize(false, informer)) {
|
|
1234
|
+
dberrprint(db, "DB::synchronize");
|
|
1235
|
+
err = true;
|
|
1236
|
+
}
|
|
1237
|
+
if (!db.occupy(false, informer)) {
|
|
1238
|
+
dberrprint(db, "DB::occupy");
|
|
1239
|
+
err = true;
|
|
1240
|
+
}
|
|
1241
|
+
printf("performing transaction:\n");
|
|
1242
|
+
if (db.begin_transaction(false)) {
|
|
1243
|
+
if (!db.set("tako", "ika")) {
|
|
1244
|
+
dberrprint(db, "DB::set");
|
|
1245
|
+
err = true;
|
|
1246
|
+
}
|
|
1247
|
+
if (!db.end_transaction(true)) {
|
|
1248
|
+
dberrprint(db, "DB::end_transaction");
|
|
1249
|
+
err = true;
|
|
1250
|
+
}
|
|
1251
|
+
} else {
|
|
1252
|
+
dberrprint(db, "DB::begin_transaction");
|
|
1253
|
+
err = true;
|
|
1254
|
+
}
|
|
1255
|
+
String value = db.get("tako");
|
|
1256
|
+
if (value == null || !value.equals("ika")) {
|
|
1257
|
+
dberrprint(db, "DB::get");
|
|
1258
|
+
err = true;
|
|
1259
|
+
}
|
|
1260
|
+
if (!db.remove("tako")) {
|
|
1261
|
+
dberrprint(db, "DB::remove");
|
|
1262
|
+
err = true;
|
|
1263
|
+
}
|
|
1264
|
+
long cnt = db.count();
|
|
1265
|
+
if (db.begin_transaction(false)) {
|
|
1266
|
+
if (!db.set("tako", "ika") || !db.set("kani", "ebi")) {
|
|
1267
|
+
dberrprint(db, "DB::set");
|
|
1268
|
+
err = true;
|
|
1269
|
+
}
|
|
1270
|
+
if (!db.end_transaction(false)) {
|
|
1271
|
+
dberrprint(db, "DB::end_transaction");
|
|
1272
|
+
err = true;
|
|
1273
|
+
}
|
|
1274
|
+
} else {
|
|
1275
|
+
dberrprint(db, "DB::begin_transaction");
|
|
1276
|
+
err = true;
|
|
1277
|
+
}
|
|
1278
|
+
if (db.get("tako") != null || db.get("kani") != null || db.count() != cnt) {
|
|
1279
|
+
dberrprint(db, "DB::transaction");
|
|
1280
|
+
err = true;
|
|
1281
|
+
}
|
|
1282
|
+
String corepath = db.path();
|
|
1283
|
+
String suffix = null;
|
|
1284
|
+
if (corepath.endsWith(".kch")) {
|
|
1285
|
+
suffix = ".kch";
|
|
1286
|
+
} else if (corepath.endsWith(".kct")) {
|
|
1287
|
+
suffix = ".kct";
|
|
1288
|
+
} else if (corepath.endsWith(".kcd")) {
|
|
1289
|
+
suffix = ".kcd";
|
|
1290
|
+
} else if (corepath.endsWith(".kcf")) {
|
|
1291
|
+
suffix = ".kcf";
|
|
1292
|
+
}
|
|
1293
|
+
if (suffix != null) {
|
|
1294
|
+
printf("performing copy and merge:\n");
|
|
1295
|
+
String[] copypaths = new String[2];
|
|
1296
|
+
for (int i = 0; i < copypaths.length; i++) {
|
|
1297
|
+
copypaths[i] = String.format("%s.%d%s", corepath, i + 1, suffix);
|
|
1298
|
+
}
|
|
1299
|
+
DB[] srcary = new DB[copypaths.length];
|
|
1300
|
+
for (int i = 0; i < copypaths.length; i++) {
|
|
1301
|
+
if (!db.copy(copypaths[i])) {
|
|
1302
|
+
dberrprint(db, "DB::copy");
|
|
1303
|
+
err = true;
|
|
1304
|
+
}
|
|
1305
|
+
srcary[i] = new DB();
|
|
1306
|
+
if (!srcary[i].open(copypaths[i], DB.OREADER)) {
|
|
1307
|
+
dberrprint(srcary[i], "DB::open");
|
|
1308
|
+
err = true;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
if (!db.merge(srcary, DB.MAPPEND)) {
|
|
1312
|
+
dberrprint(db, "DB::merge");
|
|
1313
|
+
err = true;
|
|
1314
|
+
}
|
|
1315
|
+
for (int i = 0; i < copypaths.length; i++) {
|
|
1316
|
+
if (!srcary[i].close()) {
|
|
1317
|
+
dberrprint(srcary[i], "DB::close");
|
|
1318
|
+
err = true;
|
|
1319
|
+
}
|
|
1320
|
+
Utility.remove_files_recursively(copypaths[i]);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
printf("executing mapreduce process:\n");
|
|
1324
|
+
class MapReduceImpl extends MapReduce {
|
|
1325
|
+
public boolean map(byte[] key, byte[] value) {
|
|
1326
|
+
mapcnt_++;
|
|
1327
|
+
return emit(value, key);
|
|
1328
|
+
}
|
|
1329
|
+
public boolean reduce(byte[] key, ValueIterator iter) {
|
|
1330
|
+
byte[] value;
|
|
1331
|
+
while ((value = iter.next()) != null) {
|
|
1332
|
+
redcnt_++;
|
|
1333
|
+
}
|
|
1334
|
+
return true;
|
|
1335
|
+
}
|
|
1336
|
+
public boolean preprocess() {
|
|
1337
|
+
emit("pre".getBytes(), "process".getBytes());
|
|
1338
|
+
emit("PROCESS".getBytes(), "PRE".getBytes());
|
|
1339
|
+
return true;
|
|
1340
|
+
}
|
|
1341
|
+
public boolean midprocess() {
|
|
1342
|
+
emit("mid".getBytes(), "process".getBytes());
|
|
1343
|
+
emit("PROCESS".getBytes(), "MID".getBytes());
|
|
1344
|
+
return true;
|
|
1345
|
+
}
|
|
1346
|
+
public boolean postprocess() {
|
|
1347
|
+
return true;
|
|
1348
|
+
}
|
|
1349
|
+
public long mapcnt() {
|
|
1350
|
+
return mapcnt_;
|
|
1351
|
+
}
|
|
1352
|
+
public long redcnt() {
|
|
1353
|
+
return redcnt_;
|
|
1354
|
+
}
|
|
1355
|
+
private long mapcnt_ = 0;
|
|
1356
|
+
private long redcnt_ = 0;
|
|
1357
|
+
}
|
|
1358
|
+
rnum = db.count();
|
|
1359
|
+
MapReduceImpl mr = new MapReduceImpl();
|
|
1360
|
+
if (!mr.execute(db, null, 0)) {
|
|
1361
|
+
dberrprint(db, "MapReduce::execute");
|
|
1362
|
+
err = true;
|
|
1363
|
+
}
|
|
1364
|
+
if (mr.mapcnt() != rnum || mr.redcnt() != rnum + 4) {
|
|
1365
|
+
dberrprint(db, "MapReduce::execute");
|
|
1366
|
+
err = true;
|
|
1367
|
+
}
|
|
1368
|
+
} finally {
|
|
1369
|
+
printf("closing the database:\n");
|
|
1370
|
+
if (!db.close()) {
|
|
1371
|
+
dberrprint(db, "DB::close");
|
|
1372
|
+
err = true;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
printf("checking the exceptional mode:\n");
|
|
1376
|
+
db = new DB(DB.GEXCEPTIONAL);
|
|
1377
|
+
try {
|
|
1378
|
+
db.open("hoge", DB.OREADER);
|
|
1379
|
+
dberrprint(db, "DB::open");
|
|
1380
|
+
err = true;
|
|
1381
|
+
} catch (Error.XINVALID e) {
|
|
1382
|
+
if (e.code() != Error.INVALID) {
|
|
1383
|
+
dberrprint(db, "DB::open");
|
|
1384
|
+
err = true;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
printf("%s\n\n", err ? "error" : "ok");
|
|
1388
|
+
return err ? 1 : 0;
|
|
1389
|
+
}
|
|
1390
|
+
/** perform memsize command */
|
|
1391
|
+
private static int procmemsize(long rnum, String path) {
|
|
1392
|
+
System.gc();
|
|
1393
|
+
long musage = memusagerss();
|
|
1394
|
+
double stime = Utility.time();
|
|
1395
|
+
long count = -1;
|
|
1396
|
+
if (path == null) {
|
|
1397
|
+
int bnum = rnum < Integer.MAX_VALUE ? (int)rnum : Integer.MAX_VALUE;
|
|
1398
|
+
Map<String, String> map = new HashMap<String, String>(bnum, 100);
|
|
1399
|
+
for (long i = 0; i < rnum; i++) {
|
|
1400
|
+
String key = String.format("%08d", i);
|
|
1401
|
+
String value = String.format("%08d", i);
|
|
1402
|
+
map.put(key, value);
|
|
1403
|
+
}
|
|
1404
|
+
count = map.size();
|
|
1405
|
+
} else {
|
|
1406
|
+
DB db = new DB();
|
|
1407
|
+
if (db.open(path, DB.OWRITER | DB.OCREATE | DB.OTRUNCATE)) {
|
|
1408
|
+
for (long i = 0; i < rnum; i++) {
|
|
1409
|
+
String key = String.format("%08d", i);
|
|
1410
|
+
String value = String.format("%08d", i);
|
|
1411
|
+
db.set(key, value);
|
|
1412
|
+
}
|
|
1413
|
+
count = db.count();
|
|
1414
|
+
db.close();
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
printf("count: %d\n", count);
|
|
1418
|
+
double etime = Utility.time();
|
|
1419
|
+
printf("time: %.3f\n", etime - stime);
|
|
1420
|
+
System.gc();
|
|
1421
|
+
printf("usage: %.3f MB\n", (memusagerss() - musage) / 1024.0 / 1024.0);
|
|
1422
|
+
return 0;
|
|
1423
|
+
}
|
|
1424
|
+
/** print formatted information string and flush the buffer */
|
|
1425
|
+
private static void printf(String format, Object... args) {
|
|
1426
|
+
STDOUT.printf(format, args);
|
|
1427
|
+
STDOUT.flush();
|
|
1428
|
+
}
|
|
1429
|
+
/** get a random number */
|
|
1430
|
+
private static long rand(long range) {
|
|
1431
|
+
long num = (long)(RND.nextDouble() * range);
|
|
1432
|
+
return num < range ? num : 0;
|
|
1433
|
+
}
|
|
1434
|
+
/** get the memory usage */
|
|
1435
|
+
private static long memusage() {
|
|
1436
|
+
Runtime rt = Runtime.getRuntime();
|
|
1437
|
+
return rt.totalMemory() - rt.freeMemory();
|
|
1438
|
+
}
|
|
1439
|
+
/** get the memory usage of RSS */
|
|
1440
|
+
private static long memusagerss() {
|
|
1441
|
+
long rss = -1;
|
|
1442
|
+
try {
|
|
1443
|
+
Reader fr = new FileReader("/proc/self/status");
|
|
1444
|
+
LineNumberReader lnr = new LineNumberReader(fr);
|
|
1445
|
+
String line;
|
|
1446
|
+
while ((line = lnr.readLine()) != null) {
|
|
1447
|
+
int idx = line.indexOf(':');
|
|
1448
|
+
if (idx < 0) continue;
|
|
1449
|
+
String name = line.substring(0, idx);
|
|
1450
|
+
idx++;
|
|
1451
|
+
while (idx < line.length() && Character.isWhitespace(line.charAt(idx))) idx++;
|
|
1452
|
+
String value = line.substring(idx, line.length());
|
|
1453
|
+
if (name.equals("VmRSS")) {
|
|
1454
|
+
rss = Utility.atoix(value);
|
|
1455
|
+
break;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
fr.close();
|
|
1459
|
+
} catch (Exception e) {
|
|
1460
|
+
}
|
|
1461
|
+
return rss;
|
|
1462
|
+
}
|
|
1463
|
+
//----------------------------------------------------------------
|
|
1464
|
+
// private static inner classes
|
|
1465
|
+
//----------------------------------------------------------------
|
|
1466
|
+
private static class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
|
1467
|
+
public void uncaughtException(Thread th, Throwable e) {
|
|
1468
|
+
e.printStackTrace();
|
|
1469
|
+
System.exit(1);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
//----------------------------------------------------------------
|
|
1473
|
+
// private constants
|
|
1474
|
+
//----------------------------------------------------------------
|
|
1475
|
+
/** The standard output stream. */
|
|
1476
|
+
private static final PrintStream STDOUT = System.out;
|
|
1477
|
+
/** The standard error stream. */
|
|
1478
|
+
private static final PrintStream STDERR = System.err;
|
|
1479
|
+
/** The rondom generator. */
|
|
1480
|
+
private static final Random RND = new Random();
|
|
1481
|
+
/** The exception handler. */
|
|
1482
|
+
private static final ExceptionHandler EXH = new ExceptionHandler();
|
|
1483
|
+
//----------------------------------------------------------------
|
|
1484
|
+
// private methods
|
|
1485
|
+
//----------------------------------------------------------------
|
|
1486
|
+
/**
|
|
1487
|
+
* Dummy constructor.
|
|
1488
|
+
*/
|
|
1489
|
+
private Test() {}
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
// END OF FILE
|