1 /*************************************************************************************************
2 * C language binding
3 * Copyright (C) 2009-2012 Mikio Hirabayashi
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 #include "kcpolydb.h"
17 #include "kcdbext.h"
18 #include "kclangc.h"
19 #include "myconf.h"
20
21 using namespace kyotocabinet;
22
23 extern "C" {
24
25
26 /** The package version. */
27 const char* const KCVERSION = VERSION;
28
29
30 /** Special pointer for no operation by the visiting function. */
31 const char* const KCVISNOP = DB::Visitor::NOP;
32
33
34 /** Special pointer to remove the record by the visiting function. */
35 const char* const KCVISREMOVE = DB::Visitor::REMOVE;
36
37
38 /**
39 * Allocate a region on memory.
40 */
kcmalloc(size_t size)41 void* kcmalloc(size_t size) {
42 _assert_(size > 0 && size <= MEMMAXSIZ);
43 return new char[size];
44 }
45
46
47 /**
48 * Release a region allocated in the library.
49 */
kcfree(void * ptr)50 void kcfree(void* ptr) {
51 _assert_(true);
52 delete[] (char*)ptr;
53 }
54
55
56 /**
57 * Get the time of day in seconds.
58 */
kctime(void)59 double kctime(void) {
60 _assert_(true);
61 return kyotocabinet::time();
62 }
63
64
65 /**
66 * Convert a string to an integer.
67 */
kcatoi(const char * str)68 int64_t kcatoi(const char* str) {
69 _assert_(str);
70 return kyotocabinet::atoi(str);
71 }
72
73
74 /**
75 * Convert a string with a metric prefix to an integer.
76 */
kcatoix(const char * str)77 int64_t kcatoix(const char* str) {
78 _assert_(str);
79 return kyotocabinet::atoix(str);
80 }
81
82
83 /**
84 * Convert a string to a real number.
85 */
kcatof(const char * str)86 double kcatof(const char* str) {
87 _assert_(str);
88 return kyotocabinet::atof(str);
89 }
90
91
92 /**
93 * Get the hash value by MurMur hashing.
94 */
kchashmurmur(const void * buf,size_t size)95 uint64_t kchashmurmur(const void* buf, size_t size) {
96 _assert_(buf && size <= MEMMAXSIZ);
97 return kyotocabinet::hashmurmur(buf, size);
98 }
99
100
101 /**
102 * Get the hash value by FNV hashing.
103 */
kchashfnv(const void * buf,size_t size)104 uint64_t kchashfnv(const void* buf, size_t size) {
105 _assert_(buf && size <= MEMMAXSIZ);
106 return kyotocabinet::hashfnv(buf, size);
107 }
108
109
110 /**
111 * Calculate the levenshtein distance of two regions.
112 */
kclevdist(const void * abuf,size_t asiz,const void * bbuf,size_t bsiz,int32_t utf)113 size_t kclevdist(const void* abuf, size_t asiz, const void* bbuf, size_t bsiz, int32_t utf) {
114 _assert_(abuf && asiz <= MEMMAXSIZ && bbuf && bsiz <= MEMMAXSIZ);
115 size_t dist;
116 if (utf) {
117 uint32_t astack[128];
118 uint32_t* aary = asiz > sizeof(astack) / sizeof(*astack) ? new uint32_t[asiz] : astack;
119 size_t anum;
120 strutftoucs((const char*)abuf, asiz, aary, &anum);
121 uint32_t bstack[128];
122 uint32_t* bary = bsiz > sizeof(bstack) / sizeof(*bstack) ? new uint32_t[bsiz] : bstack;
123 size_t bnum;
124 strutftoucs((const char*)bbuf, bsiz, bary, &bnum);
125 dist = strucsdist(aary, anum, bary, bnum);
126 if (bary != bstack) delete[] bary;
127 if (aary != astack) delete[] aary;
128 } else {
129 dist = memdist(abuf, asiz, bbuf, bsiz);
130 }
131 return dist;
132 }
133
134
135 /**
136 * Get the quiet Not-a-Number value.
137 */
kcnan()138 double kcnan() {
139 _assert_(true);
140 return kyotocabinet::nan();
141 }
142
143
144 /**
145 * Get the positive infinity value.
146 */
kcinf()147 double kcinf() {
148 _assert_(true);
149 return kyotocabinet::inf();
150 }
151
152
153 /**
154 * Check a number is a Not-a-Number value.
155 */
kcchknan(double num)156 int32_t kcchknan(double num) {
157 _assert_(true);
158 return kyotocabinet::chknan(num);
159 }
160
161
162 /**
163 * Check a number is an infinity value.
164 */
kcchkinf(double num)165 int32_t kcchkinf(double num) {
166 _assert_(true);
167 return kyotocabinet::chkinf(num);
168 }
169
170
171 /**
172 * Get the readable string of an error code.
173 */
kcecodename(int32_t code)174 const char* kcecodename(int32_t code) {
175 _assert_(true);
176 return BasicDB::Error::codename((BasicDB::Error::Code)code);
177 }
178
179
180 /**
181 * Create a database object.
182 */
kcdbnew(void)183 KCDB* kcdbnew(void) {
184 _assert_(true);
185 return (KCDB*)new PolyDB;
186 }
187
188
189 /**
190 * Destroy a database object.
191 */
kcdbdel(KCDB * db)192 void kcdbdel(KCDB* db) {
193 _assert_(db);
194 PolyDB* pdb = (PolyDB*)db;
195 delete pdb;
196 }
197
198
199 /**
200 * Open a database file.
201 */
kcdbopen(KCDB * db,const char * path,uint32_t mode)202 int32_t kcdbopen(KCDB* db, const char* path, uint32_t mode) {
203 _assert_(db && path);
204 PolyDB* pdb = (PolyDB*)db;
205 return pdb->open(path, mode);
206 }
207
208
209 /**
210 * Close the database file.
211 */
kcdbclose(KCDB * db)212 int32_t kcdbclose(KCDB* db) {
213 _assert_(db);
214 PolyDB* pdb = (PolyDB*)db;
215 return pdb->close();
216 }
217
218
219 /**
220 * Get the code of the last happened error.
221 */
kcdbecode(KCDB * db)222 int32_t kcdbecode(KCDB* db) {
223 _assert_(db);
224 PolyDB* pdb = (PolyDB*)db;
225 return pdb->error().code();
226 }
227
228
229 /**
230 * Get the supplement message of the last happened error.
231 */
kcdbemsg(KCDB * db)232 const char* kcdbemsg(KCDB* db) {
233 _assert_(db);
234 PolyDB* pdb = (PolyDB*)db;
235 return pdb->error().message();
236 }
237
238
239 /**
240 * Accept a visitor to a record.
241 */
kcdbaccept(KCDB * db,const char * kbuf,size_t ksiz,KCVISITFULL fullproc,KCVISITEMPTY emptyproc,void * opq,int32_t writable)242 int32_t kcdbaccept(KCDB* db, const char* kbuf, size_t ksiz,
243 KCVISITFULL fullproc, KCVISITEMPTY emptyproc, void* opq, int32_t writable) {
244 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
245 PolyDB* pdb = (PolyDB*)db;
246 class VisitorImpl : public DB::Visitor {
247 public:
248 explicit VisitorImpl(KCVISITFULL fullproc, KCVISITEMPTY emptyproc, void* opq) :
249 fullproc_(fullproc), emptyproc_(emptyproc), opq_(opq) {}
250 const char* visit_full(const char* kbuf, size_t ksiz,
251 const char* vbuf, size_t vsiz, size_t* sp) {
252 if (!fullproc_) return NOP;
253 return fullproc_(kbuf, ksiz, vbuf, vsiz, sp, opq_);
254 }
255 const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) {
256 if (!emptyproc_) return NOP;
257 return emptyproc_(kbuf, ksiz, sp, opq_);
258 }
259 private:
260 KCVISITFULL fullproc_;
261 KCVISITEMPTY emptyproc_;
262 void* opq_;
263 };
264 VisitorImpl visitor(fullproc, emptyproc, opq);
265 return pdb->accept(kbuf, ksiz, &visitor, writable);
266 }
267
268
269 /**
270 * Accept a visitor to multiple records at once.
271 */
kcdbacceptbulk(KCDB * db,const KCSTR * keys,size_t knum,KCVISITFULL fullproc,KCVISITEMPTY emptyproc,void * opq,int32_t writable)272 int32_t kcdbacceptbulk(KCDB* db, const KCSTR* keys, size_t knum,
273 KCVISITFULL fullproc, KCVISITEMPTY emptyproc,
274 void* opq, int32_t writable) {
275 _assert_(db && keys && knum <= MEMMAXSIZ);
276 PolyDB* pdb = (PolyDB*)db;
277 std::vector<std::string> xkeys;
278 xkeys.reserve(knum);
279 for (size_t i = 0; i < knum; i++) {
280 xkeys.push_back(std::string(keys[i].buf, keys[i].size));
281 }
282 class VisitorImpl : public DB::Visitor {
283 public:
284 explicit VisitorImpl(KCVISITFULL fullproc, KCVISITEMPTY emptyproc, void* opq) :
285 fullproc_(fullproc), emptyproc_(emptyproc), opq_(opq) {}
286 const char* visit_full(const char* kbuf, size_t ksiz,
287 const char* vbuf, size_t vsiz, size_t* sp) {
288 if (!fullproc_) return NOP;
289 return fullproc_(kbuf, ksiz, vbuf, vsiz, sp, opq_);
290 }
291 const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) {
292 if (!emptyproc_) return NOP;
293 return emptyproc_(kbuf, ksiz, sp, opq_);
294 }
295 private:
296 KCVISITFULL fullproc_;
297 KCVISITEMPTY emptyproc_;
298 void* opq_;
299 };
300 VisitorImpl visitor(fullproc, emptyproc, opq);
301 return pdb->accept_bulk(xkeys, &visitor, writable);
302 }
303
304
305 /**
306 * Iterate to accept a visitor for each record.
307 */
kcdbiterate(KCDB * db,KCVISITFULL fullproc,void * opq,int32_t writable)308 int32_t kcdbiterate(KCDB* db, KCVISITFULL fullproc, void* opq, int32_t writable) {
309 _assert_(db);
310 PolyDB* pdb = (PolyDB*)db;
311 class VisitorImpl : public DB::Visitor {
312 public:
313 explicit VisitorImpl(KCVISITFULL fullproc, void* opq) : fullproc_(fullproc), opq_(opq) {}
314 const char* visit_full(const char* kbuf, size_t ksiz,
315 const char* vbuf, size_t vsiz, size_t* sp) {
316 if (!fullproc_) return NOP;
317 return fullproc_(kbuf, ksiz, vbuf, vsiz, sp, opq_);
318 }
319 private:
320 KCVISITFULL fullproc_;
321 void* opq_;
322 };
323 VisitorImpl visitor(fullproc, opq);
324 return pdb->iterate(&visitor, writable);
325 }
326
327
328 /**
329 * Scan each record in parallel.
330 */
kcdbscanpara(KCDB * db,KCVISITFULL fullproc,void * opq,size_t thnum)331 int32_t kcdbscanpara(KCDB* db, KCVISITFULL fullproc, void* opq, size_t thnum) {
332 _assert_(db && thnum <= MEMMAXSIZ);
333 PolyDB* pdb = (PolyDB*)db;
334 class VisitorImpl : public DB::Visitor {
335 public:
336 explicit VisitorImpl(KCVISITFULL fullproc, void* opq) : fullproc_(fullproc), opq_(opq) {}
337 const char* visit_full(const char* kbuf, size_t ksiz,
338 const char* vbuf, size_t vsiz, size_t* sp) {
339 if (!fullproc_) return NOP;
340 return fullproc_(kbuf, ksiz, vbuf, vsiz, sp, opq_);
341 }
342 private:
343 KCVISITFULL fullproc_;
344 void* opq_;
345 };
346 VisitorImpl visitor(fullproc, opq);
347 return pdb->scan_parallel(&visitor, thnum);
348 }
349
350
351 /**
352 * Set the value of a record.
353 */
kcdbset(KCDB * db,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)354 int32_t kcdbset(KCDB* db, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
355 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
356 PolyDB* pdb = (PolyDB*)db;
357 return pdb->set(kbuf, ksiz, vbuf, vsiz);
358 }
359
360
361 /**
362 * Add a record.
363 */
kcdbadd(KCDB * db,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)364 int32_t kcdbadd(KCDB* db, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
365 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
366 PolyDB* pdb = (PolyDB*)db;
367 return pdb->add(kbuf, ksiz, vbuf, vsiz);
368 }
369
370
371 /**
372 * Replace the value of a record.
373 */
kcdbreplace(KCDB * db,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)374 int32_t kcdbreplace(KCDB* db, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
375 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
376 PolyDB* pdb = (PolyDB*)db;
377 return pdb->replace(kbuf, ksiz, vbuf, vsiz);
378 }
379
380
381 /**
382 * Append the value of a record.
383 */
kcdbappend(KCDB * db,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)384 int32_t kcdbappend(KCDB* db, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
385 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
386 PolyDB* pdb = (PolyDB*)db;
387 return pdb->append(kbuf, ksiz, vbuf, vsiz);
388 }
389
390
391 /**
392 * Add a number to the numeric value of a record.
393 */
kcdbincrint(KCDB * db,const char * kbuf,size_t ksiz,int64_t num,int64_t orig)394 int64_t kcdbincrint(KCDB* db, const char* kbuf, size_t ksiz, int64_t num, int64_t orig) {
395 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
396 PolyDB* pdb = (PolyDB*)db;
397 return pdb->increment(kbuf, ksiz, num, orig);
398 }
399
400
401 /**
402 * Add a number to the numeric value of a record.
403 */
kcdbincrdouble(KCDB * db,const char * kbuf,size_t ksiz,double num,double orig)404 double kcdbincrdouble(KCDB* db, const char* kbuf, size_t ksiz, double num, double orig) {
405 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
406 PolyDB* pdb = (PolyDB*)db;
407 return pdb->increment_double(kbuf, ksiz, num, orig);
408 }
409
410
411 /**
412 * Perform compare-and-swap.
413 */
kcdbcas(KCDB * db,const char * kbuf,size_t ksiz,const char * ovbuf,size_t ovsiz,const char * nvbuf,size_t nvsiz)414 int32_t kcdbcas(KCDB* db, const char* kbuf, size_t ksiz,
415 const char* ovbuf, size_t ovsiz, const char* nvbuf, size_t nvsiz) {
416 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
417 PolyDB* pdb = (PolyDB*)db;
418 return pdb->cas(kbuf, ksiz, ovbuf, ovsiz, nvbuf, nvsiz);
419 }
420
421
422 /**
423 * Remove a record.
424 */
kcdbremove(KCDB * db,const char * kbuf,size_t ksiz)425 int32_t kcdbremove(KCDB* db, const char* kbuf, size_t ksiz) {
426 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
427 PolyDB* pdb = (PolyDB*)db;
428 return pdb->remove(kbuf, ksiz);
429 }
430
431
432 /**
433 * Retrieve the value of a record.
434 */
kcdbget(KCDB * db,const char * kbuf,size_t ksiz,size_t * sp)435 char* kcdbget(KCDB* db, const char* kbuf, size_t ksiz, size_t* sp) {
436 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && sp);
437 PolyDB* pdb = (PolyDB*)db;
438 return pdb->get(kbuf, ksiz, sp);
439 }
440
441
442 /**
443 * Check the existence of a record.
444 */
kcdbcheck(KCDB * db,const char * kbuf,size_t ksiz)445 int32_t kcdbcheck(KCDB* db, const char* kbuf, size_t ksiz) {
446 _assert_(db && kbuf && ksiz <= MEMMAXSIZ);
447 PolyDB* pdb = (PolyDB*)db;
448 return pdb->check(kbuf, ksiz);
449 }
450
451
452 /**
453 * Retrieve the value of a record.
454 */
kcdbgetbuf(KCDB * db,const char * kbuf,size_t ksiz,char * vbuf,size_t max)455 int32_t kcdbgetbuf(KCDB* db, const char* kbuf, size_t ksiz, char* vbuf, size_t max) {
456 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && vbuf);
457 PolyDB* pdb = (PolyDB*)db;
458 return pdb->get(kbuf, ksiz, vbuf, max);
459 }
460
461
462 /**
463 * Retrieve the value of a record and remove it atomically.
464 */
kcdbseize(KCDB * db,const char * kbuf,size_t ksiz,size_t * sp)465 char* kcdbseize(KCDB* db, const char* kbuf, size_t ksiz, size_t* sp) {
466 _assert_(db && kbuf && ksiz <= MEMMAXSIZ && sp);
467 PolyDB* pdb = (PolyDB*)db;
468 return pdb->seize(kbuf, ksiz, sp);
469 }
470
471
472 /**
473 * Store records at once.
474 */
kcdbsetbulk(KCDB * db,const KCREC * recs,size_t rnum,int32_t atomic)475 int64_t kcdbsetbulk(KCDB* db, const KCREC* recs, size_t rnum, int32_t atomic) {
476 _assert_(db && recs && rnum <= MEMMAXSIZ);
477 PolyDB* pdb = (PolyDB*)db;
478 std::map<std::string, std::string> xrecs;
479 for (size_t i = 0; i < rnum; i++) {
480 const KCREC* rec = recs + i;
481 xrecs[std::string(rec->key.buf, rec->key.size)] =
482 std::string(rec->value.buf, rec->value.size);
483 }
484 return pdb->set_bulk(xrecs, atomic);
485 }
486
487
488 /**
489 * Remove records at once.
490 */
kcdbremovebulk(KCDB * db,const KCSTR * keys,size_t knum,int32_t atomic)491 int64_t kcdbremovebulk(KCDB* db, const KCSTR* keys, size_t knum, int32_t atomic) {
492 _assert_(db && keys && knum <= MEMMAXSIZ);
493 PolyDB* pdb = (PolyDB*)db;
494 std::vector<std::string> xkeys;
495 xkeys.reserve(knum);
496 for (size_t i = 0; i < knum; i++) {
497 const KCSTR* key = keys + i;
498 xkeys.push_back(std::string(key->buf, key->size));
499 }
500 return pdb->remove_bulk(xkeys, atomic);
501 }
502
503
504 /**
505 * Retrieve records at once.
506 */
kcdbgetbulk(KCDB * db,const KCSTR * keys,size_t knum,KCREC * recs,int32_t atomic)507 int64_t kcdbgetbulk(KCDB* db, const KCSTR* keys, size_t knum, KCREC* recs, int32_t atomic) {
508 _assert_(db && keys && knum <= MEMMAXSIZ && recs);
509 PolyDB* pdb = (PolyDB*)db;
510 std::vector<std::string> xkeys;
511 xkeys.reserve(knum);
512 for (size_t i = 0; i < knum; i++) {
513 const KCSTR* key = keys + i;
514 xkeys.push_back(std::string(key->buf, key->size));
515 }
516 std::map<std::string, std::string> xrecs;
517 if (pdb->get_bulk(xkeys, &xrecs, atomic) < 0) return -1;
518 std::map<std::string, std::string>::iterator it = xrecs.begin();
519 std::map<std::string, std::string>::iterator itend = xrecs.end();
520 size_t ridx = 0;
521 while (ridx < knum && it != itend) {
522 size_t ksiz = it->first.size();
523 char* kbuf = new char[ksiz+1];
524 std::memcpy(kbuf, it->first.data(), ksiz);
525 kbuf[ksiz] = '\0';
526 size_t vsiz = it->second.size();
527 char* vbuf = new char[vsiz+1];
528 std::memcpy(vbuf, it->second.data(), vsiz);
529 vbuf[vsiz] = '\0';
530 KCREC* rec = recs + (ridx++);
531 rec->key.buf = kbuf;
532 rec->key.size = ksiz;
533 rec->value.buf = vbuf;
534 rec->value.size = vsiz;
535 ++it;
536 }
537 return ridx;
538 }
539
540
541 /**
542 * Synchronize updated contents with the file and the device.
543 */
kcdbsync(KCDB * db,int32_t hard,KCFILEPROC proc,void * opq)544 int32_t kcdbsync(KCDB* db, int32_t hard, KCFILEPROC proc, void* opq) {
545 _assert_(db);
546 PolyDB* pdb = (PolyDB*)db;
547 class FileProcessorImpl : public BasicDB::FileProcessor {
548 public:
549 explicit FileProcessorImpl(KCFILEPROC proc, void* opq) : proc_(proc), opq_(opq) {}
550 bool process(const std::string& path, int64_t count, int64_t size) {
551 if (!proc_) return true;
552 return proc_(path.c_str(), count, size, opq_);
553 }
554 private:
555 KCFILEPROC proc_;
556 void* opq_;
557 };
558 FileProcessorImpl myproc(proc, opq);
559 return pdb->synchronize(hard, &myproc);
560 }
561
562
563 /**
564 * Occupy database by locking and do something meanwhile.
565 */
kcdboccupy(KCDB * db,int32_t writable,KCFILEPROC proc,void * opq)566 int32_t kcdboccupy(KCDB* db, int32_t writable, KCFILEPROC proc, void* opq) {
567 _assert_(db);
568 PolyDB* pdb = (PolyDB*)db;
569 class FileProcessorImpl : public BasicDB::FileProcessor {
570 public:
571 explicit FileProcessorImpl(KCFILEPROC proc, void* opq) : proc_(proc), opq_(opq) {}
572 bool process(const std::string& path, int64_t count, int64_t size) {
573 if (!proc_) return true;
574 return proc_(path.c_str(), count, size, opq_);
575 }
576 private:
577 KCFILEPROC proc_;
578 void* opq_;
579 };
580 FileProcessorImpl myproc(proc, opq);
581 return pdb->occupy(writable, &myproc);
582 }
583
584
585 /**
586 * Create a copy of the database file.
587 */
kcdbcopy(KCDB * db,const char * dest)588 int32_t kcdbcopy(KCDB* db, const char* dest) {
589 _assert_(db && dest);
590 PolyDB* pdb = (PolyDB*)db;
591 return pdb->copy(dest);
592 }
593
594
595 /**
596 * Begin transaction.
597 */
kcdbbegintran(KCDB * db,int32_t hard)598 int32_t kcdbbegintran(KCDB* db, int32_t hard) {
599 _assert_(db);
600 PolyDB* pdb = (PolyDB*)db;
601 return pdb->begin_transaction(hard);
602 }
603
604
605 /**
606 * Try to begin transaction.
607 */
kcdbbegintrantry(KCDB * db,int32_t hard)608 int32_t kcdbbegintrantry(KCDB* db, int32_t hard) {
609 _assert_(db);
610 PolyDB* pdb = (PolyDB*)db;
611 return pdb->begin_transaction_try(hard);
612 }
613
614
615 /**
616 * End transaction.
617 */
kcdbendtran(KCDB * db,int32_t commit)618 int32_t kcdbendtran(KCDB* db, int32_t commit) {
619 _assert_(db);
620 PolyDB* pdb = (PolyDB*)db;
621 return pdb->end_transaction(commit);
622 }
623
624
625 /**
626 * Remove all records.
627 */
kcdbclear(KCDB * db)628 int32_t kcdbclear(KCDB* db) {
629 _assert_(db);
630 PolyDB* pdb = (PolyDB*)db;
631 return pdb->clear();
632 }
633
634
635 /**
636 * Dump records into a file.
637 */
kcdbdumpsnap(KCDB * db,const char * dest)638 int32_t kcdbdumpsnap(KCDB* db, const char* dest) {
639 _assert_(db && dest);
640 PolyDB* pdb = (PolyDB*)db;
641 return pdb->dump_snapshot(dest);
642 }
643
644
645 /**
646 * Load records from a file.
647 */
kcdbloadsnap(KCDB * db,const char * src)648 int32_t kcdbloadsnap(KCDB* db, const char* src) {
649 _assert_(db && src);
650 PolyDB* pdb = (PolyDB*)db;
651 return pdb->load_snapshot(src);
652 }
653
654
655 /**
656 * Get the number of records.
657 */
kcdbcount(KCDB * db)658 int64_t kcdbcount(KCDB* db) {
659 _assert_(db);
660 PolyDB* pdb = (PolyDB*)db;
661 return pdb->count();
662 }
663
664
665 /**
666 * Get the size of the database file.
667 */
kcdbsize(KCDB * db)668 int64_t kcdbsize(KCDB* db) {
669 _assert_(db);
670 PolyDB* pdb = (PolyDB*)db;
671 return pdb->size();
672 }
673
674
675 /**
676 * Get the path of the database file.
677 */
kcdbpath(KCDB * db)678 char* kcdbpath(KCDB* db) {
679 _assert_(db);
680 PolyDB* pdb = (PolyDB*)db;
681 std::string path = pdb->path();
682 size_t psiz = path.size();
683 char* pbuf = new char[psiz+1];
684 std::memcpy(pbuf, path.c_str(), psiz + 1);
685 return pbuf;
686 }
687
688
689 /**
690 * Get the miscellaneous status information.
691 */
kcdbstatus(KCDB * db)692 char* kcdbstatus(KCDB* db) {
693 _assert_(db);
694 PolyDB* pdb = (PolyDB*)db;
695 std::map<std::string, std::string> status;
696 if (!pdb->status(&status)) return NULL;
697 std::ostringstream obuf;
698 std::map<std::string, std::string>::iterator it = status.begin();
699 std::map<std::string, std::string>::iterator itend = status.end();
700 while (it != itend) {
701 obuf << it->first << "\t" << it->second << "\n";
702 ++it;
703 }
704 std::string sstr = obuf.str();
705 size_t ssiz = sstr.size();
706 char* sbuf = new char[ssiz+1];
707 std::memcpy(sbuf, sstr.c_str(), ssiz + 1);
708 return sbuf;
709 }
710
711
712 /**
713 * Get keys matching a prefix string.
714 */
kcdbmatchprefix(KCDB * db,const char * prefix,char ** strary,size_t max)715 int64_t kcdbmatchprefix(KCDB* db, const char* prefix, char** strary, size_t max) {
716 _assert_(db && prefix && strary && max <= MEMMAXSIZ);
717 PolyDB* pdb = (PolyDB*)db;
718 std::vector<std::string> strvec;
719 if (pdb->match_prefix(prefix, &strvec, max) == -1) return -1;
720 int64_t cnt = 0;
721 std::vector<std::string>::iterator it = strvec.begin();
722 std::vector<std::string>::iterator itend = strvec.end();
723 while (it != itend) {
724 size_t ksiz = it->size();
725 char* kbuf = new char[ksiz+1];
726 std::memcpy(kbuf, it->data(), ksiz);
727 kbuf[ksiz] = '\0';
728 strary[cnt++] = kbuf;
729 ++it;
730 }
731 return cnt;
732 }
733
734
735 /**
736 * Get keys matching a regular expression string.
737 */
kcdbmatchregex(KCDB * db,const char * regex,char ** strary,size_t max)738 int64_t kcdbmatchregex(KCDB* db, const char* regex, char** strary, size_t max) {
739 _assert_(db && regex && strary && max <= MEMMAXSIZ);
740 PolyDB* pdb = (PolyDB*)db;
741 std::vector<std::string> strvec;
742 if (pdb->match_regex(regex, &strvec, max) == -1) return -1;
743 int64_t cnt = 0;
744 std::vector<std::string>::iterator it = strvec.begin();
745 std::vector<std::string>::iterator itend = strvec.end();
746 while (it != itend) {
747 size_t ksiz = it->size();
748 char* kbuf = new char[ksiz+1];
749 std::memcpy(kbuf, it->data(), ksiz);
750 kbuf[ksiz] = '\0';
751 strary[cnt++] = kbuf;
752 ++it;
753 }
754 return cnt;
755 }
756
757
758 /**
759 * Get keys similar to a string in terms of the levenshtein distance.
760 */
kcdbmatchsimilar(KCDB * db,const char * origin,uint32_t range,int32_t utf,char ** strary,size_t max)761 int64_t kcdbmatchsimilar(KCDB* db, const char* origin, uint32_t range, int32_t utf,
762 char** strary, size_t max) {
763 _assert_(db && origin && strary && max <= MEMMAXSIZ);
764 PolyDB* pdb = (PolyDB*)db;
765 std::vector<std::string> strvec;
766 if (pdb->match_similar(origin, range, utf, &strvec, max) == -1) return -1;
767 int64_t cnt = 0;
768 std::vector<std::string>::iterator it = strvec.begin();
769 std::vector<std::string>::iterator itend = strvec.end();
770 while (it != itend) {
771 size_t ksiz = it->size();
772 char* kbuf = new char[ksiz+1];
773 std::memcpy(kbuf, it->data(), ksiz);
774 kbuf[ksiz] = '\0';
775 strary[cnt++] = kbuf;
776 ++it;
777 }
778 return cnt;
779 }
780
781
782 /**
783 * Merge records from other databases.
784 */
kcdbmerge(KCDB * db,KCDB ** srcary,size_t srcnum,uint32_t mode)785 int32_t kcdbmerge(KCDB* db, KCDB** srcary, size_t srcnum, uint32_t mode) {
786 _assert_(db && srcary && srcnum <= MEMMAXSIZ);
787 PolyDB* pdb = (PolyDB*)db;
788 return pdb->merge((BasicDB**)srcary, srcnum, (PolyDB::MergeMode)mode);
789 }
790
791
792 /**
793 * Create a cursor object.
794 */
kcdbcursor(KCDB * db)795 KCCUR* kcdbcursor(KCDB* db) {
796 _assert_(db);
797 PolyDB* pdb = (PolyDB*)db;
798 return (KCCUR*)pdb->cursor();
799 }
800
801
802 /**
803 * Destroy a cursor object.
804 */
kccurdel(KCCUR * cur)805 void kccurdel(KCCUR* cur) {
806 _assert_(cur);
807 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
808 delete pcur;
809 }
810
811
812 /**
813 * Accept a visitor to the current record.
814 */
kccuraccept(KCCUR * cur,KCVISITFULL fullproc,void * opq,int32_t writable,int32_t step)815 int32_t kccuraccept(KCCUR* cur, KCVISITFULL fullproc, void* opq,
816 int32_t writable, int32_t step) {
817 _assert_(cur);
818 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
819 class VisitorImpl : public DB::Visitor {
820 public:
821 explicit VisitorImpl(KCVISITFULL fullproc, void* opq) : fullproc_(fullproc), opq_(opq) {}
822 const char* visit_full(const char* kbuf, size_t ksiz,
823 const char* vbuf, size_t vsiz, size_t* sp) {
824 if (!fullproc_) return NOP;
825 return fullproc_(kbuf, ksiz, vbuf, vsiz, sp, opq_);
826 }
827 private:
828 KCVISITFULL fullproc_;
829 void* opq_;
830 };
831 VisitorImpl visitor(fullproc, opq);
832 return pcur->accept(&visitor, writable, step);
833 }
834
835
836 /**
837 * Set the value of the current record.
838 */
kccursetvalue(KCCUR * cur,const char * vbuf,size_t vsiz,int32_t step)839 int32_t kccursetvalue(KCCUR* cur, const char* vbuf, size_t vsiz, int32_t step) {
840 _assert_(cur && vbuf && vsiz <= MEMMAXSIZ);
841 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
842 return pcur->set_value(vbuf, vsiz, step);
843 }
844
845
846 /**
847 * Remove the current record.
848 */
kccurremove(KCCUR * cur)849 int32_t kccurremove(KCCUR* cur) {
850 _assert_(cur);
851 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
852 return pcur->remove();
853 }
854
855
856 /**
857 * Get the key of the current record.
858 */
kccurgetkey(KCCUR * cur,size_t * sp,int32_t step)859 char* kccurgetkey(KCCUR* cur, size_t* sp, int32_t step) {
860 _assert_(cur && sp);
861 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
862 return pcur->get_key(sp, step);
863 }
864
865
866 /**
867 * Get the value of the current record.
868 */
kccurgetvalue(KCCUR * cur,size_t * sp,int32_t step)869 char* kccurgetvalue(KCCUR* cur, size_t* sp, int32_t step) {
870 _assert_(cur && sp);
871 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
872 return pcur->get_value(sp, step);
873 }
874
875
876 /**
877 * Get a pair of the key and the value of the current record.
878 */
kccurget(KCCUR * cur,size_t * ksp,const char ** vbp,size_t * vsp,int32_t step)879 char* kccurget(KCCUR* cur, size_t* ksp, const char** vbp, size_t* vsp, int32_t step) {
880 _assert_(cur && ksp && vbp && vsp);
881 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
882 return pcur->get(ksp, vbp, vsp, step);
883 }
884
885
886 /**
887 * Get a pair of the key and the value of the current record and remove it atomically.
888 */
kccurseize(KCCUR * cur,size_t * ksp,const char ** vbp,size_t * vsp)889 char* kccurseize(KCCUR* cur, size_t* ksp, const char** vbp, size_t* vsp) {
890 _assert_(cur && ksp && vbp && vsp);
891 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
892 return pcur->seize(ksp, vbp, vsp);
893 }
894
895
896 /**
897 * Jump the cursor to the first record.
898 */
kccurjump(KCCUR * cur)899 int32_t kccurjump(KCCUR* cur) {
900 _assert_(cur);
901 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
902 return pcur->jump();
903 }
904
905
906 /**
907 * Jump the cursor to a record.
908 */
kccurjumpkey(KCCUR * cur,const char * kbuf,size_t ksiz)909 int32_t kccurjumpkey(KCCUR* cur, const char* kbuf, size_t ksiz) {
910 _assert_(cur && kbuf && ksiz <= MEMMAXSIZ);
911 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
912 return pcur->jump(kbuf, ksiz);
913 }
914
915
916 /**
917 * Jump the cursor to the last record for backward scan.
918 */
kccurjumpback(KCCUR * cur)919 int32_t kccurjumpback(KCCUR* cur) {
920 _assert_(cur);
921 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
922 return pcur->jump_back();
923 }
924
925
926 /**
927 * Jump the cursor to a record for backward scan.
928 */
kccurjumpbackkey(KCCUR * cur,const char * kbuf,size_t ksiz)929 int32_t kccurjumpbackkey(KCCUR* cur, const char* kbuf, size_t ksiz) {
930 _assert_(cur && kbuf && ksiz <= MEMMAXSIZ);
931 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
932 return pcur->jump_back(kbuf, ksiz);
933 }
934
935
936 /**
937 * Step the cursor to the next record.
938 */
kccurstep(KCCUR * cur)939 int32_t kccurstep(KCCUR* cur) {
940 _assert_(cur);
941 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
942 return pcur->step();
943 }
944
945
946 /**
947 * Step the cursor to the previous record.
948 */
kccurstepback(KCCUR * cur)949 int32_t kccurstepback(KCCUR* cur) {
950 _assert_(cur);
951 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
952 return pcur->step_back();
953 }
954
955
956 /**
957 * Get the database object.
958 */
kccurdb(KCCUR * cur)959 KCDB* kccurdb(KCCUR* cur) {
960 _assert_(cur);
961 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
962 return (KCDB*)pcur->db();
963 }
964
965
966 /**
967 * Get the code of the last happened error.
968 */
kccurecode(KCCUR * cur)969 int32_t kccurecode(KCCUR* cur) {
970 _assert_(cur);
971 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
972 return pcur->error().code();
973 }
974
975
976 /**
977 * Get the supplement message of the last happened error.
978 */
kccuremsg(KCCUR * cur)979 const char* kccuremsg(KCCUR* cur) {
980 _assert_(cur);
981 PolyDB::Cursor* pcur = (PolyDB::Cursor*)cur;
982 return pcur->error().message();
983 }
984
985
986 /**
987 * Create an index database object.
988 */
kcidxnew(void)989 KCIDX* kcidxnew(void) {
990 _assert_(true);
991 return (KCIDX*)new IndexDB;
992 }
993
994
995 /**
996 * Destroy a database object.
997 */
kcidxdel(KCIDX * idx)998 void kcidxdel(KCIDX* idx) {
999 _assert_(idx);
1000 IndexDB* idb = (IndexDB*)idx;
1001 delete idb;
1002 }
1003
1004
1005 /**
1006 * Open a database file.
1007 */
kcidxopen(KCIDX * idx,const char * path,uint32_t mode)1008 int32_t kcidxopen(KCIDX* idx, const char* path, uint32_t mode) {
1009 _assert_(idx && path);
1010 IndexDB* idb = (IndexDB*)idx;
1011 return idb->open(path, mode);
1012 }
1013
1014
1015 /**
1016 * Close the database file.
1017 */
kcidxclose(KCIDX * idx)1018 int32_t kcidxclose(KCIDX* idx) {
1019 _assert_(idx);
1020 IndexDB* idb = (IndexDB*)idx;
1021 return idb->close();
1022 }
1023
1024
1025 /**
1026 * Get the code of the last happened error.
1027 */
kcidxecode(KCIDX * idx)1028 int32_t kcidxecode(KCIDX* idx) {
1029 _assert_(idx);
1030 IndexDB* idb = (IndexDB*)idx;
1031 return idb->error().code();
1032 }
1033
1034
1035 /**
1036 * Get the supplement message of the last happened error.
1037 */
kcidxemsg(KCIDX * idx)1038 const char* kcidxemsg(KCIDX* idx) {
1039 _assert_(idx);
1040 IndexDB* idb = (IndexDB*)idx;
1041 return idb->error().message();
1042 }
1043
1044
1045 /**
1046 * Set the value of a record.
1047 */
kcidxset(KCIDX * idx,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1048 int32_t kcidxset(KCIDX* idx, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1049 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1050 IndexDB* idb = (IndexDB*)idx;
1051 return idb->set(kbuf, ksiz, vbuf, vsiz);
1052 }
1053
1054
1055 /**
1056 * Add a record.
1057 */
kcidxadd(KCIDX * idx,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1058 int32_t kcidxadd(KCIDX* idx, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1059 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1060 IndexDB* idb = (IndexDB*)idx;
1061 return idb->add(kbuf, ksiz, vbuf, vsiz);
1062 }
1063
1064
1065 /**
1066 * Replace the value of a record.
1067 */
kcidxreplace(KCIDX * idx,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1068 int32_t kcidxreplace(KCIDX* idx, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1069 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1070 IndexDB* idb = (IndexDB*)idx;
1071 return idb->replace(kbuf, ksiz, vbuf, vsiz);
1072 }
1073
1074
1075 /**
1076 * Append the value of a record.
1077 */
kcidxappend(KCIDX * idx,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1078 int32_t kcidxappend(KCIDX* idx, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1079 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1080 IndexDB* idb = (IndexDB*)idx;
1081 return idb->append(kbuf, ksiz, vbuf, vsiz);
1082 }
1083
1084
1085 /**
1086 * Remove a record.
1087 */
kcidxremove(KCIDX * idx,const char * kbuf,size_t ksiz)1088 int32_t kcidxremove(KCIDX* idx, const char* kbuf, size_t ksiz) {
1089 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ);
1090 IndexDB* idb = (IndexDB*)idx;
1091 return idb->remove(kbuf, ksiz);
1092 }
1093
1094
1095 /**
1096 * Retrieve the value of a record.
1097 */
kcidxget(KCIDX * idx,const char * kbuf,size_t ksiz,size_t * sp)1098 char* kcidxget(KCIDX* idx, const char* kbuf, size_t ksiz, size_t* sp) {
1099 _assert_(idx && kbuf && ksiz <= MEMMAXSIZ && sp);
1100 IndexDB* idb = (IndexDB*)idx;
1101 return idb->get(kbuf, ksiz, sp);
1102 }
1103
1104
1105 /**
1106 * Synchronize updated contents with the file and the device.
1107 */
kcidxsync(KCIDX * idx,int32_t hard,KCFILEPROC proc,void * opq)1108 int32_t kcidxsync(KCIDX* idx, int32_t hard, KCFILEPROC proc, void* opq) {
1109 _assert_(idx);
1110 IndexDB* idb = (IndexDB*)idx;
1111 class FileProcessorImpl : public BasicDB::FileProcessor {
1112 public:
1113 explicit FileProcessorImpl(KCFILEPROC proc, void* opq) : proc_(proc), opq_(opq) {}
1114 bool process(const std::string& path, int64_t count, int64_t size) {
1115 if (!proc_) return true;
1116 return proc_(path.c_str(), count, size, opq_);
1117 }
1118 private:
1119 KCFILEPROC proc_;
1120 void* opq_;
1121 };
1122 FileProcessorImpl myproc(proc, opq);
1123 return idb->synchronize(hard, &myproc);
1124 }
1125
1126
1127 /**
1128 * Remove all records.
1129 */
kcidxclear(KCIDX * idx)1130 int32_t kcidxclear(KCIDX* idx) {
1131 _assert_(idx);
1132 IndexDB* idb = (IndexDB*)idx;
1133 return idb->clear();
1134 }
1135
1136
1137 /**
1138 * Get the number of records.
1139 */
kcidxcount(KCIDX * idx)1140 int64_t kcidxcount(KCIDX* idx) {
1141 _assert_(idx);
1142 IndexDB* idb = (IndexDB*)idx;
1143 return idb->count();
1144 }
1145
1146
1147 /**
1148 * Get the size of the database file.
1149 */
kcidxsize(KCIDX * idx)1150 int64_t kcidxsize(KCIDX* idx) {
1151 _assert_(idx);
1152 IndexDB* idb = (IndexDB*)idx;
1153 return idb->size();
1154 }
1155
1156
1157 /**
1158 * Get the path of the database file.
1159 */
kcidxpath(KCIDX * idx)1160 char* kcidxpath(KCIDX* idx) {
1161 _assert_(idx);
1162 IndexDB* idb = (IndexDB*)idx;
1163 std::string path = idb->path();
1164 size_t psiz = path.size();
1165 char* pbuf = new char[psiz+1];
1166 std::memcpy(pbuf, path.c_str(), psiz + 1);
1167 return pbuf;
1168 }
1169
1170
1171 /**
1172 * Get the miscellaneous status information.
1173 */
kcidxstatus(KCIDX * idx)1174 char* kcidxstatus(KCIDX* idx) {
1175 _assert_(idx);
1176 IndexDB* idb = (IndexDB*)idx;
1177 std::map<std::string, std::string> status;
1178 if (!idb->status(&status)) return NULL;
1179 std::ostringstream obuf;
1180 std::map<std::string, std::string>::iterator it = status.begin();
1181 std::map<std::string, std::string>::iterator itend = status.end();
1182 while (it != itend) {
1183 obuf << it->first << "\t" << it->second << "\n";
1184 ++it;
1185 }
1186 std::string sstr = obuf.str();
1187 size_t ssiz = sstr.size();
1188 char* sbuf = new char[ssiz+1];
1189 std::memcpy(sbuf, sstr.c_str(), ssiz + 1);
1190 return sbuf;
1191 }
1192
1193
1194 /**
1195 * Reveal the inner database object.
1196 */
kcidxrevealinnerdb(KCIDX * idx)1197 KCDB* kcidxrevealinnerdb(KCIDX* idx) {
1198 _assert_(idx);
1199 IndexDB* idb = (IndexDB*)idx;
1200 return (KCDB*)idb->reveal_inner_db();
1201 }
1202
1203
1204 /**
1205 * Create a string hash map object.
1206 */
kcmapnew(size_t bnum)1207 KCMAP* kcmapnew(size_t bnum) {
1208 _assert_(true);
1209 return (KCMAP*)new TinyHashMap(bnum);
1210 }
1211
1212
1213 /**
1214 * Destroy a map object.
1215 */
kcmapdel(KCMAP * map)1216 void kcmapdel(KCMAP* map) {
1217 _assert_(map);
1218 TinyHashMap* thm = (TinyHashMap*)map;
1219 delete thm;
1220 }
1221
1222
1223 /**
1224 * Set the value of a record.
1225 */
kcmapset(KCMAP * map,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1226 void kcmapset(KCMAP* map, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1227 _assert_(map && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1228 TinyHashMap* thm = (TinyHashMap*)map;
1229 thm->set(kbuf, ksiz, vbuf, vsiz);
1230 }
1231
1232
1233 /**
1234 * Add a record.
1235 */
kcmapadd(KCMAP * map,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1236 int32_t kcmapadd(KCMAP* map, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1237 _assert_(map && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1238 TinyHashMap* thm = (TinyHashMap*)map;
1239 return thm->add(kbuf, ksiz, vbuf, vsiz);
1240 }
1241
1242
1243 /**
1244 * Replace the value of a record.
1245 */
kcmapreplace(KCMAP * map,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1246 int32_t kcmapreplace(KCMAP* map, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1247 _assert_(map && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1248 TinyHashMap* thm = (TinyHashMap*)map;
1249 return thm->replace(kbuf, ksiz, vbuf, vsiz);
1250 }
1251
1252
1253 /**
1254 * Append the value of a record.
1255 */
kcmapappend(KCMAP * map,const char * kbuf,size_t ksiz,const char * vbuf,size_t vsiz)1256 void kcmapappend(KCMAP* map, const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
1257 _assert_(map && kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
1258 TinyHashMap* thm = (TinyHashMap*)map;
1259 thm->append(kbuf, ksiz, vbuf, vsiz);
1260 }
1261
1262
1263 /**
1264 * Remove a record.
1265 */
kcmapremove(KCMAP * map,const char * kbuf,size_t ksiz)1266 int32_t kcmapremove(KCMAP* map, const char* kbuf, size_t ksiz) {
1267 _assert_(map && kbuf && ksiz <= MEMMAXSIZ);
1268 TinyHashMap* thm = (TinyHashMap*)map;
1269 return thm->remove(kbuf, ksiz);
1270 }
1271
1272
1273 /**
1274 * Retrieve the value of a record.
1275 */
kcmapget(KCMAP * map,const char * kbuf,size_t ksiz,size_t * sp)1276 const char* kcmapget(KCMAP* map, const char* kbuf, size_t ksiz, size_t* sp) {
1277 _assert_(map && kbuf && ksiz <= MEMMAXSIZ && sp);
1278 TinyHashMap* thm = (TinyHashMap*)map;
1279 return thm->get(kbuf, ksiz, sp);
1280 }
1281
1282
1283 /**
1284 * Remove all records.
1285 */
kcmapclear(KCMAP * map)1286 void kcmapclear(KCMAP* map) {
1287 _assert_(map);
1288 TinyHashMap* thm = (TinyHashMap*)map;
1289 thm->clear();
1290 }
1291
1292
1293 /**
1294 * Get the number of records.
1295 */
kcmapcount(KCMAP * map)1296 size_t kcmapcount(KCMAP* map) {
1297 _assert_(map);
1298 TinyHashMap* thm = (TinyHashMap*)map;
1299 return thm->count();
1300 }
1301
1302
1303 /**
1304 * Create a string hash map iterator object.
1305 */
kcmapiterator(KCMAP * map)1306 KCMAPITER* kcmapiterator(KCMAP* map) {
1307 _assert_(map);
1308 TinyHashMap* thm = (TinyHashMap*)map;
1309 return (KCMAPITER*)new TinyHashMap::Iterator(thm);
1310 }
1311
1312
1313 /**
1314 * Destroy an iterator object.
1315 */
kcmapiterdel(KCMAPITER * iter)1316 void kcmapiterdel(KCMAPITER* iter) {
1317 _assert_(iter);
1318 TinyHashMap::Iterator* thmi = (TinyHashMap::Iterator*)iter;
1319 delete thmi;
1320 }
1321
1322
1323 /**
1324 * Get the key of the current record.
1325 */
kcmapitergetkey(KCMAPITER * iter,size_t * sp)1326 const char* kcmapitergetkey(KCMAPITER* iter, size_t* sp) {
1327 _assert_(iter && sp);
1328 TinyHashMap::Iterator* thmi = (TinyHashMap::Iterator*)iter;
1329 return thmi->get_key(sp);
1330 }
1331
1332
1333 /**
1334 * Get the value of the current record.
1335 */
kcmapitergetvalue(KCMAPITER * iter,size_t * sp)1336 const char* kcmapitergetvalue(KCMAPITER* iter, size_t* sp) {
1337 _assert_(iter && sp);
1338 TinyHashMap::Iterator* thmi = (TinyHashMap::Iterator*)iter;
1339 return thmi->get_value(sp);
1340 }
1341
1342
1343 /**
1344 * Get a pair of the key and the value of the current record.
1345 */
kcmapiterget(KCMAPITER * iter,size_t * ksp,const char ** vbp,size_t * vsp)1346 const char* kcmapiterget(KCMAPITER* iter, size_t* ksp, const char** vbp, size_t* vsp) {
1347 _assert_(iter && ksp && vbp && vsp);
1348 TinyHashMap::Iterator* thmi = (TinyHashMap::Iterator*)iter;
1349 return thmi->get(ksp, vbp, vsp);
1350 }
1351
1352
1353 /**
1354 * Step the cursor to the next record.
1355 */
kcmapiterstep(KCMAPITER * iter)1356 void kcmapiterstep(KCMAPITER* iter) {
1357 _assert_(iter);
1358 TinyHashMap::Iterator* thmi = (TinyHashMap::Iterator*)iter;
1359 return thmi->step();
1360 }
1361
1362
1363 /**
1364 * Create a string hash map sorter object.
1365 */
kcmapsorter(KCMAP * map)1366 KCMAPSORT* kcmapsorter(KCMAP* map) {
1367 _assert_(map);
1368 TinyHashMap* thm = (TinyHashMap*)map;
1369 return (KCMAPSORT*)new TinyHashMap::Sorter(thm);
1370 }
1371
1372
1373 /**
1374 * Destroy an sorter object.
1375 */
kcmapsortdel(KCMAPSORT * sort)1376 void kcmapsortdel(KCMAPSORT* sort) {
1377 _assert_(sort);
1378 TinyHashMap::Sorter* thms = (TinyHashMap::Sorter*)sort;
1379 delete thms;
1380 }
1381
1382
1383 /**
1384 * Get the key of the current record.
1385 */
kcmapsortgetkey(KCMAPSORT * sort,size_t * sp)1386 const char* kcmapsortgetkey(KCMAPSORT* sort, size_t* sp) {
1387 _assert_(sort && sp);
1388 TinyHashMap::Sorter* thms = (TinyHashMap::Sorter*)sort;
1389 return thms->get_key(sp);
1390 }
1391
1392
1393 /**
1394 * Get the value of the current record.
1395 */
kcmapsortgetvalue(KCMAPSORT * sort,size_t * sp)1396 const char* kcmapsortgetvalue(KCMAPSORT* sort, size_t* sp) {
1397 _assert_(sort && sp);
1398 TinyHashMap::Sorter* thms = (TinyHashMap::Sorter*)sort;
1399 return thms->get_value(sp);
1400 }
1401
1402
1403 /**
1404 * Get a pair of the key and the value of the current record.
1405 */
kcmapsortget(KCMAPSORT * sort,size_t * ksp,const char ** vbp,size_t * vsp)1406 const char* kcmapsortget(KCMAPSORT* sort, size_t* ksp, const char** vbp, size_t* vsp) {
1407 _assert_(sort && ksp && vbp && vsp);
1408 TinyHashMap::Sorter* thms = (TinyHashMap::Sorter*)sort;
1409 return thms->get(ksp, vbp, vsp);
1410 }
1411
1412
1413 /**
1414 * Step the cursor to the next record.
1415 */
kcmapsortstep(KCMAPSORT * sort)1416 void kcmapsortstep(KCMAPSORT* sort) {
1417 _assert_(sort);
1418 TinyHashMap::Sorter* thms = (TinyHashMap::Sorter*)sort;
1419 return thms->step();
1420 }
1421
1422
1423 /**
1424 * Create a string array list object.
1425 */
kclistnew()1426 KCLIST* kclistnew() {
1427 _assert_(true);
1428 return (KCLIST*)new TinyArrayList();
1429 }
1430
1431
1432 /**
1433 * Destroy a list object.
1434 */
kclistdel(KCLIST * list)1435 void kclistdel(KCLIST* list) {
1436 _assert_(list);
1437 TinyArrayList* tal = (TinyArrayList*)list;
1438 delete tal;
1439 }
1440
1441
1442 /**
1443 * Insert a record at the bottom of the list.
1444 */
kclistpush(KCLIST * list,const char * buf,size_t size)1445 void kclistpush(KCLIST* list, const char* buf, size_t size) {
1446 _assert_(list && buf && size <= MEMMAXSIZ);
1447 TinyArrayList* tal = (TinyArrayList*)list;
1448 tal->push(buf, size);
1449 }
1450
1451
1452 /**
1453 * Remove a record at the bottom of the list.
1454 */
kclistpop(KCLIST * list)1455 int32_t kclistpop(KCLIST* list) {
1456 _assert_(list);
1457 TinyArrayList* tal = (TinyArrayList*)list;
1458 return tal->pop();
1459 }
1460
1461
1462 /**
1463 * Insert a record at the top of the list.
1464 */
kclistunshift(KCLIST * list,const char * buf,size_t size)1465 void kclistunshift(KCLIST* list, const char* buf, size_t size) {
1466 _assert_(list && buf && size <= MEMMAXSIZ);
1467 TinyArrayList* tal = (TinyArrayList*)list;
1468 tal->unshift(buf, size);
1469 }
1470
1471
1472 /**
1473 * Remove a record at the top of the list.
1474 */
kclistshift(KCLIST * list)1475 int32_t kclistshift(KCLIST* list) {
1476 _assert_(list);
1477 TinyArrayList* tal = (TinyArrayList*)list;
1478 return tal->shift();
1479 }
1480
1481
1482 /**
1483 * Insert a record at the position of the given index of the list.
1484 */
kclistinsert(KCLIST * list,const char * buf,size_t size,size_t idx)1485 void kclistinsert(KCLIST* list, const char* buf, size_t size, size_t idx) {
1486 _assert_(list && buf && size <= MEMMAXSIZ);
1487 TinyArrayList* tal = (TinyArrayList*)list;
1488 tal->insert(buf, size, idx);
1489 }
1490
1491
1492 /**
1493 * Remove a record at the position of the given index of the list.
1494 */
kclistremove(KCLIST * list,size_t idx)1495 void kclistremove(KCLIST* list, size_t idx) {
1496 _assert_(list);
1497 TinyArrayList* tal = (TinyArrayList*)list;
1498 return tal->remove(idx);
1499 }
1500
1501
1502 /**
1503 * Retrieve a record at the position of the given index of the list.
1504 */
kclistget(KCLIST * list,size_t idx,size_t * sp)1505 const char* kclistget(KCLIST* list, size_t idx, size_t* sp) {
1506 _assert_(list && sp);
1507 TinyArrayList* tal = (TinyArrayList*)list;
1508 return tal->get(idx, sp);
1509 }
1510
1511
1512 /**
1513 * Remove all records.
1514 */
kclistclear(KCLIST * list)1515 void kclistclear(KCLIST* list) {
1516 _assert_(list);
1517 TinyArrayList* tal = (TinyArrayList*)list;
1518 tal->clear();
1519 }
1520
1521
1522 /**
1523 * Get the number of records.
1524 */
kclistcount(KCLIST * list)1525 size_t kclistcount(KCLIST* list) {
1526 _assert_(list);
1527 TinyArrayList* tal = (TinyArrayList*)list;
1528 return tal->count();
1529 }
1530
1531
1532 }
1533
1534 // END OF FILE
1535