kyotocabinet-java 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/Gemfile +15 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.rdoc +19 -0
  5. data/Rakefile +62 -0
  6. data/VERSION +1 -0
  7. data/ext/kyotocabinet-java/.gitignore +2 -0
  8. data/ext/kyotocabinet-java/COPYING +674 -0
  9. data/ext/kyotocabinet-java/Cursor.java +268 -0
  10. data/ext/kyotocabinet-java/DB.java +650 -0
  11. data/ext/kyotocabinet-java/Error.java +257 -0
  12. data/ext/kyotocabinet-java/FileProcessor.java +42 -0
  13. data/ext/kyotocabinet-java/Loader.java +60 -0
  14. data/ext/kyotocabinet-java/Makefile.in +246 -0
  15. data/ext/kyotocabinet-java/MapReduce.java +127 -0
  16. data/ext/kyotocabinet-java/README +26 -0
  17. data/ext/kyotocabinet-java/Test.java +1494 -0
  18. data/ext/kyotocabinet-java/Utility.java +131 -0
  19. data/ext/kyotocabinet-java/VCmakefile +150 -0
  20. data/ext/kyotocabinet-java/ValueIterator.java +49 -0
  21. data/ext/kyotocabinet-java/Visitor.java +56 -0
  22. data/ext/kyotocabinet-java/configure.in +310 -0
  23. data/ext/kyotocabinet-java/doc/allclasses-frame.html +26 -0
  24. data/ext/kyotocabinet-java/doc/allclasses-noframe.html +26 -0
  25. data/ext/kyotocabinet-java/doc/constant-values.html +344 -0
  26. data/ext/kyotocabinet-java/doc/index-all.html +848 -0
  27. data/ext/kyotocabinet-java/doc/index.html +30 -0
  28. data/ext/kyotocabinet-java/doc/kyotocabinet/Cursor.html +711 -0
  29. data/ext/kyotocabinet-java/doc/kyotocabinet/DB.html +1674 -0
  30. data/ext/kyotocabinet-java/doc/kyotocabinet/Error.html +604 -0
  31. data/ext/kyotocabinet-java/doc/kyotocabinet/FileProcessor.html +210 -0
  32. data/ext/kyotocabinet-java/doc/kyotocabinet/MapReduce.html +461 -0
  33. data/ext/kyotocabinet-java/doc/kyotocabinet/Test.html +220 -0
  34. data/ext/kyotocabinet-java/doc/kyotocabinet/Utility.html +413 -0
  35. data/ext/kyotocabinet-java/doc/kyotocabinet/ValueIterator.html +221 -0
  36. data/ext/kyotocabinet-java/doc/kyotocabinet/Visitor.html +283 -0
  37. data/ext/kyotocabinet-java/doc/kyotocabinet/package-frame.html +33 -0
  38. data/ext/kyotocabinet-java/doc/kyotocabinet/package-summary.html +199 -0
  39. data/ext/kyotocabinet-java/doc/kyotocabinet/package-tree.html +141 -0
  40. data/ext/kyotocabinet-java/doc/overview-summary.html +285 -0
  41. data/ext/kyotocabinet-java/doc/overview-tree.html +145 -0
  42. data/ext/kyotocabinet-java/doc/package-list +1 -0
  43. data/ext/kyotocabinet-java/doc/resources/background.gif +0 -0
  44. data/ext/kyotocabinet-java/doc/resources/tab.gif +0 -0
  45. data/ext/kyotocabinet-java/doc/resources/titlebar.gif +0 -0
  46. data/ext/kyotocabinet-java/doc/resources/titlebar_end.gif +0 -0
  47. data/ext/kyotocabinet-java/doc/serialized-form.html +141 -0
  48. data/ext/kyotocabinet-java/doc/stylesheet.css +474 -0
  49. data/ext/kyotocabinet-java/example/KCDBEX1.java +44 -0
  50. data/ext/kyotocabinet-java/example/KCDBEX2.java +44 -0
  51. data/ext/kyotocabinet-java/example/Makefile +59 -0
  52. data/ext/kyotocabinet-java/kyotocabinet.cc +2187 -0
  53. data/ext/kyotocabinet-java/kyotocabinet_Cursor.h +157 -0
  54. data/ext/kyotocabinet-java/kyotocabinet_DB.h +353 -0
  55. data/ext/kyotocabinet-java/kyotocabinet_Error.h +49 -0
  56. data/ext/kyotocabinet-java/kyotocabinet_Error_XBROKEN.h +41 -0
  57. data/ext/kyotocabinet-java/kyotocabinet_Error_XDUPREC.h +41 -0
  58. data/ext/kyotocabinet-java/kyotocabinet_Error_XINVALID.h +41 -0
  59. data/ext/kyotocabinet-java/kyotocabinet_Error_XLOGIC.h +41 -0
  60. data/ext/kyotocabinet-java/kyotocabinet_Error_XMISC.h +41 -0
  61. data/ext/kyotocabinet-java/kyotocabinet_Error_XNOIMPL.h +41 -0
  62. data/ext/kyotocabinet-java/kyotocabinet_Error_XNOPERM.h +41 -0
  63. data/ext/kyotocabinet-java/kyotocabinet_Error_XNOREC.h +41 -0
  64. data/ext/kyotocabinet-java/kyotocabinet_Error_XNOREPOS.h +41 -0
  65. data/ext/kyotocabinet-java/kyotocabinet_Error_XSUCCESS.h +41 -0
  66. data/ext/kyotocabinet-java/kyotocabinet_Error_XSYSTEM.h +41 -0
  67. data/ext/kyotocabinet-java/kyotocabinet_MapReduce.h +33 -0
  68. data/ext/kyotocabinet-java/kyotocabinet_Utility.h +101 -0
  69. data/ext/kyotocabinet-java/kyotocabinet_ValueIterator.h +21 -0
  70. data/ext/kyotocabinet-java/overview.html +177 -0
  71. data/kyotocabinet-java.gemspec +129 -0
  72. data/lib/kyotocabinet-java.rb +141 -0
  73. data/lib/kyotocabinet-java/version.rb +5 -0
  74. 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