ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/BDB/BDB.xs
Revision: 1.11
Committed: Wed May 9 06:42:24 2007 UTC (17 years ago) by root
Branch: MAIN
Changes since 1.10: +12 -57 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "xthread.h"
2
3 #include <errno.h>
4
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8
9 #include <stddef.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <limits.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17
18 #include <db.h>
19
20 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 5)
21 # error you need Berkeley DB 4.5 or newer installed
22 #endif
23
24 /* number of seconds after which idle threads exit */
25 #define IDLE_TIMEOUT 10
26
27 typedef DB_ENV DB_ENV_ornull;
28 typedef DB_TXN DB_TXN_ornull;
29 typedef DBC DBC_ornull;
30 typedef DB DB_ornull;
31 typedef DB_SEQUENCE DB_SEQUENCE_ornull;
32
33 typedef SV SV8; /* byte-sv, used for argument-checking */
34 typedef char *octetstring;
35
36 static SV *prepare_cb;
37
38 static inline char *
39 strdup_ornull (const char *s)
40 {
41 return s ? strdup (s) : 0;
42 }
43
44 static inline void
45 sv_to_dbt (DBT *dbt, SV *sv)
46 {
47 STRLEN len;
48 char *data = SvPVbyte (sv, len);
49
50 dbt->data = malloc (len);
51 memcpy (dbt->data, data, len);
52 dbt->size = len;
53 dbt->flags = DB_DBT_REALLOC;
54 }
55
56 static inline void
57 dbt_to_sv (SV *sv, DBT *dbt)
58 {
59 if (sv)
60 {
61 SvREADONLY_off (sv);
62 sv_setpvn_mg (sv, dbt->data, dbt->size);
63 SvREFCNT_dec (sv);
64 }
65
66 free (dbt->data);
67 }
68
69 enum {
70 REQ_QUIT,
71 REQ_ENV_OPEN, REQ_ENV_CLOSE, REQ_ENV_TXN_CHECKPOINT, REQ_ENV_LOCK_DETECT,
72 REQ_ENV_MEMP_SYNC, REQ_ENV_MEMP_TRICKLE,
73 REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC,
74 REQ_DB_PUT, REQ_DB_GET, REQ_DB_PGET, REQ_DB_DEL, REQ_DB_KEY_RANGE,
75 REQ_TXN_COMMIT, REQ_TXN_ABORT,
76 REQ_C_CLOSE, REQ_C_COUNT, REQ_C_PUT, REQ_C_GET, REQ_C_PGET, REQ_C_DEL,
77 REQ_SEQ_OPEN, REQ_SEQ_CLOSE, REQ_SEQ_GET, REQ_SEQ_REMOVE,
78 };
79
80 typedef struct aio_cb
81 {
82 struct aio_cb *volatile next;
83 SV *callback;
84 int type, pri, result;
85
86 DB_ENV *env;
87 DB *db;
88 DB_TXN *txn;
89 DBC *dbc;
90
91 UV uv1;
92 int int1, int2;
93 U32 uint1, uint2;
94 char *buf1, *buf2;
95 SV *sv1, *sv2, *sv3;
96
97 DBT dbt1, dbt2, dbt3;
98 DB_KEY_RANGE key_range;
99 DB_SEQUENCE *seq;
100 db_seq_t seq_t;
101 } aio_cb;
102
103 typedef aio_cb *aio_req;
104
105 enum {
106 PRI_MIN = -4,
107 PRI_MAX = 4,
108
109 DEFAULT_PRI = 0,
110 PRI_BIAS = -PRI_MIN,
111 NUM_PRI = PRI_MAX + PRI_BIAS + 1,
112 };
113
114 #define AIO_TICKS ((1000000 + 1023) >> 10)
115
116 static unsigned int max_poll_time = 0;
117 static unsigned int max_poll_reqs = 0;
118
119 /* calculcate time difference in ~1/AIO_TICKS of a second */
120 static int tvdiff (struct timeval *tv1, struct timeval *tv2)
121 {
122 return (tv2->tv_sec - tv1->tv_sec ) * AIO_TICKS
123 + ((tv2->tv_usec - tv1->tv_usec) >> 10);
124 }
125
126 static int next_pri = DEFAULT_PRI + PRI_BIAS;
127
128 static unsigned int started, idle, wanted;
129
130 /* worker threads management */
131 static mutex_t wrklock = MUTEX_INIT;
132
133 typedef struct worker {
134 /* locked by wrklock */
135 struct worker *prev, *next;
136
137 thread_t tid;
138
139 /* locked by reslock, reqlock or wrklock */
140 aio_req req; /* currently processed request */
141 void *dbuf;
142 DIR *dirp;
143 } worker;
144
145 static worker wrk_first = { &wrk_first, &wrk_first, 0 };
146
147 static void worker_clear (worker *wrk)
148 {
149 }
150
151 static void worker_free (worker *wrk)
152 {
153 wrk->next->prev = wrk->prev;
154 wrk->prev->next = wrk->next;
155
156 free (wrk);
157 }
158
159 static volatile unsigned int nreqs, nready, npending;
160 static volatile unsigned int max_idle = 4;
161 static volatile unsigned int max_outstanding = 0xffffffff;
162 static int respipe [2];
163
164 static mutex_t reslock = MUTEX_INIT;
165 static mutex_t reqlock = MUTEX_INIT;
166 static cond_t reqwait = COND_INIT;
167
168 #if WORDACCESS_UNSAFE
169
170 static unsigned int get_nready ()
171 {
172 unsigned int retval;
173
174 LOCK (reqlock);
175 retval = nready;
176 UNLOCK (reqlock);
177
178 return retval;
179 }
180
181 static unsigned int get_npending ()
182 {
183 unsigned int retval;
184
185 LOCK (reslock);
186 retval = npending;
187 UNLOCK (reslock);
188
189 return retval;
190 }
191
192 static unsigned int get_nthreads ()
193 {
194 unsigned int retval;
195
196 LOCK (wrklock);
197 retval = started;
198 UNLOCK (wrklock);
199
200 return retval;
201 }
202
203 #else
204
205 # define get_nready() nready
206 # define get_npending() npending
207 # define get_nthreads() started
208
209 #endif
210
211 /*
212 * a somewhat faster data structure might be nice, but
213 * with 8 priorities this actually needs <20 insns
214 * per shift, the most expensive operation.
215 */
216 typedef struct {
217 aio_req qs[NUM_PRI], qe[NUM_PRI]; /* qstart, qend */
218 int size;
219 } reqq;
220
221 static reqq req_queue;
222 static reqq res_queue;
223
224 int reqq_push (reqq *q, aio_req req)
225 {
226 int pri = req->pri;
227 req->next = 0;
228
229 if (q->qe[pri])
230 {
231 q->qe[pri]->next = req;
232 q->qe[pri] = req;
233 }
234 else
235 q->qe[pri] = q->qs[pri] = req;
236
237 return q->size++;
238 }
239
240 aio_req reqq_shift (reqq *q)
241 {
242 int pri;
243
244 if (!q->size)
245 return 0;
246
247 --q->size;
248
249 for (pri = NUM_PRI; pri--; )
250 {
251 aio_req req = q->qs[pri];
252
253 if (req)
254 {
255 if (!(q->qs[pri] = req->next))
256 q->qe[pri] = 0;
257
258 return req;
259 }
260 }
261
262 abort ();
263 }
264
265 static int poll_cb ();
266 static void req_free (aio_req req);
267 static void req_cancel (aio_req req);
268
269 static int req_invoke (aio_req req)
270 {
271 dSP;
272
273 if (SvOK (req->callback))
274 {
275 ENTER;
276 SAVETMPS;
277 PUSHMARK (SP);
278
279 switch (req->type)
280 {
281 case REQ_DB_CLOSE:
282 SvREFCNT_dec (req->sv1);
283 break;
284
285 case REQ_DB_GET:
286 case REQ_DB_PGET:
287 dbt_to_sv (req->sv3, &req->dbt3);
288 break;
289
290 case REQ_C_GET:
291 case REQ_C_PGET:
292 dbt_to_sv (req->sv1, &req->dbt1);
293 dbt_to_sv (req->sv2, &req->dbt2);
294 dbt_to_sv (req->sv3, &req->dbt3);
295 break;
296
297 case REQ_DB_KEY_RANGE:
298 {
299 AV *av = newAV ();
300
301 av_push (av, newSVnv (req->key_range.less));
302 av_push (av, newSVnv (req->key_range.equal));
303 av_push (av, newSVnv (req->key_range.greater));
304
305 SvREADONLY_off (req->sv1);
306 sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av));
307 SvREFCNT_dec (req->sv1);
308 }
309 break;
310
311 case REQ_SEQ_GET:
312 SvREADONLY_off (req->sv1);
313
314 if (sizeof (IV) > 4)
315 sv_setiv_mg (req->sv1, req->seq_t);
316 else
317 sv_setnv_mg (req->sv1, req->seq_t);
318
319 SvREFCNT_dec (req->sv1);
320 break;
321 }
322
323 errno = req->result;
324
325 PUTBACK;
326 call_sv (req->callback, G_VOID | G_EVAL);
327 SPAGAIN;
328
329 FREETMPS;
330 LEAVE;
331 }
332
333 return !SvTRUE (ERRSV);
334 }
335
336 static void req_free (aio_req req)
337 {
338 free (req->buf1);
339 free (req->buf2);
340 Safefree (req);
341 }
342
343 static void *aio_proc (void *arg);
344
345 static void start_thread (void)
346 {
347 worker *wrk = calloc (1, sizeof (worker));
348
349 if (!wrk)
350 croak ("unable to allocate worker thread data");
351
352 LOCK (wrklock);
353 if (thread_create (&wrk->tid, aio_proc, (void *)wrk))
354 {
355 wrk->prev = &wrk_first;
356 wrk->next = wrk_first.next;
357 wrk_first.next->prev = wrk;
358 wrk_first.next = wrk;
359 ++started;
360 }
361 else
362 free (wrk);
363
364 UNLOCK (wrklock);
365 }
366
367 static void maybe_start_thread ()
368 {
369 if (get_nthreads () >= wanted)
370 return;
371
372 /* todo: maybe use idle here, but might be less exact */
373 if (0 <= (int)get_nthreads () + (int)get_npending () - (int)nreqs)
374 return;
375
376 start_thread ();
377 }
378
379 static void req_send (aio_req req)
380 {
381 SV *wait_callback = 0;
382
383 // synthesize callback if none given
384 if (!SvOK (req->callback))
385 {
386 dSP;
387 PUSHMARK (SP);
388 PUTBACK;
389 int count = call_sv (prepare_cb, G_ARRAY);
390 SPAGAIN;
391
392 if (count != 2)
393 croak ("prepare callback must return exactly two values\n");
394
395 wait_callback = SvREFCNT_inc (POPs);
396 SvREFCNT_dec (req->callback);
397 req->callback = SvREFCNT_inc (POPs);
398 }
399
400 ++nreqs;
401
402 LOCK (reqlock);
403 ++nready;
404 reqq_push (&req_queue, req);
405 COND_SIGNAL (reqwait);
406 UNLOCK (reqlock);
407
408 maybe_start_thread ();
409
410 if (wait_callback)
411 {
412 dSP;
413 PUSHMARK (SP);
414 PUTBACK;
415 call_sv (wait_callback, G_DISCARD);
416 SvREFCNT_dec (wait_callback);
417 }
418 }
419
420 static void end_thread (void)
421 {
422 aio_req req;
423
424 Newz (0, req, 1, aio_cb);
425
426 req->type = REQ_QUIT;
427 req->pri = PRI_MAX + PRI_BIAS;
428
429 LOCK (reqlock);
430 reqq_push (&req_queue, req);
431 COND_SIGNAL (reqwait);
432 UNLOCK (reqlock);
433
434 LOCK (wrklock);
435 --started;
436 UNLOCK (wrklock);
437 }
438
439 static void set_max_idle (int nthreads)
440 {
441 if (WORDACCESS_UNSAFE) LOCK (reqlock);
442 max_idle = nthreads <= 0 ? 1 : nthreads;
443 if (WORDACCESS_UNSAFE) UNLOCK (reqlock);
444 }
445
446 static void min_parallel (int nthreads)
447 {
448 if (wanted < nthreads)
449 wanted = nthreads;
450 }
451
452 static void max_parallel (int nthreads)
453 {
454 if (wanted > nthreads)
455 wanted = nthreads;
456
457 while (started > wanted)
458 end_thread ();
459 }
460
461 static void poll_wait ()
462 {
463 fd_set rfd;
464
465 while (nreqs)
466 {
467 int size;
468 if (WORDACCESS_UNSAFE) LOCK (reslock);
469 size = res_queue.size;
470 if (WORDACCESS_UNSAFE) UNLOCK (reslock);
471
472 if (size)
473 return;
474
475 maybe_start_thread ();
476
477 FD_ZERO(&rfd);
478 FD_SET(respipe [0], &rfd);
479
480 select (respipe [0] + 1, &rfd, 0, 0, 0);
481 }
482 }
483
484 static int poll_cb ()
485 {
486 dSP;
487 int count = 0;
488 int maxreqs = max_poll_reqs;
489 int do_croak = 0;
490 struct timeval tv_start, tv_now;
491 aio_req req;
492
493 if (max_poll_time)
494 gettimeofday (&tv_start, 0);
495
496 for (;;)
497 {
498 for (;;)
499 {
500 maybe_start_thread ();
501
502 LOCK (reslock);
503 req = reqq_shift (&res_queue);
504
505 if (req)
506 {
507 --npending;
508
509 if (!res_queue.size)
510 {
511 /* read any signals sent by the worker threads */
512 char buf [4];
513 while (read (respipe [0], buf, 4) == 4)
514 ;
515 }
516 }
517
518 UNLOCK (reslock);
519
520 if (!req)
521 break;
522
523 --nreqs;
524
525 if (!req_invoke (req))
526 {
527 req_free (req);
528 croak (0);
529 }
530
531 count++;
532
533 req_free (req);
534
535 if (maxreqs && !--maxreqs)
536 break;
537
538 if (max_poll_time)
539 {
540 gettimeofday (&tv_now, 0);
541
542 if (tvdiff (&tv_start, &tv_now) >= max_poll_time)
543 break;
544 }
545 }
546
547 if (nreqs <= max_outstanding)
548 break;
549
550 poll_wait ();
551
552 ++maxreqs;
553 }
554
555 return count;
556 }
557
558 static void create_pipe ()
559 {
560 if (pipe (respipe))
561 croak ("unable to initialize result pipe");
562
563 if (fcntl (respipe [0], F_SETFL, O_NONBLOCK))
564 croak ("cannot set result pipe to nonblocking mode");
565
566 if (fcntl (respipe [1], F_SETFL, O_NONBLOCK))
567 croak ("cannot set result pipe to nonblocking mode");
568 }
569
570 /*****************************************************************************/
571
572 static void *aio_proc (void *thr_arg)
573 {
574 aio_req req;
575 struct timespec ts;
576 worker *self = (worker *)thr_arg;
577
578 /* try to distribute timeouts somewhat evenly */
579 ts.tv_nsec = (((unsigned long)self + (unsigned long)ts.tv_sec) & 1023UL)
580 * (1000000000UL / 1024UL);
581
582 for (;;)
583 {
584 ts.tv_sec = time (0) + IDLE_TIMEOUT;
585
586 LOCK (reqlock);
587
588 for (;;)
589 {
590 self->req = req = reqq_shift (&req_queue);
591
592 if (req)
593 break;
594
595 ++idle;
596
597 if (COND_TIMEDWAIT (reqwait, reqlock, ts)
598 == ETIMEDOUT)
599 {
600 if (idle > max_idle)
601 {
602 --idle;
603 UNLOCK (reqlock);
604 LOCK (wrklock);
605 --started;
606 UNLOCK (wrklock);
607 goto quit;
608 }
609
610 /* we are allowed to idle, so do so without any timeout */
611 COND_WAIT (reqwait, reqlock);
612 ts.tv_sec = time (0) + IDLE_TIMEOUT;
613 }
614
615 --idle;
616 }
617
618 --nready;
619
620 UNLOCK (reqlock);
621
622 switch (req->type)
623 {
624 case REQ_QUIT:
625 goto quit;
626
627 case REQ_ENV_OPEN:
628 req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1);
629 break;
630
631 case REQ_ENV_CLOSE:
632 req->result = req->env->close (req->env, req->uint1);
633 break;
634
635 case REQ_ENV_TXN_CHECKPOINT:
636 req->result = req->env->txn_checkpoint (req->env, req->uint1, req->int1, req->uint2);
637 break;
638
639 case REQ_ENV_LOCK_DETECT:
640 req->result = req->env->lock_detect (req->env, req->uint1, req->uint2, &req->int1);
641 break;
642
643 case REQ_ENV_MEMP_SYNC:
644 req->result = req->env->memp_sync (req->env, 0);
645 break;
646
647 case REQ_ENV_MEMP_TRICKLE:
648 req->result = req->env->memp_trickle (req->env, req->int1, &req->int2);
649 break;
650
651 case REQ_DB_OPEN:
652 req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2);
653 break;
654
655 case REQ_DB_CLOSE:
656 req->result = req->db->close (req->db, req->uint1);
657 break;
658
659 case REQ_DB_COMPACT:
660 req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0);
661 break;
662
663 case REQ_DB_SYNC:
664 req->result = req->db->sync (req->db, req->uint1);
665 break;
666
667 case REQ_DB_PUT:
668 req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1);
669 break;
670
671 case REQ_DB_GET:
672 req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1);
673 break;
674
675 case REQ_DB_PGET:
676 req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
677 break;
678
679 case REQ_DB_DEL:
680 req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1);
681 break;
682
683 case REQ_DB_KEY_RANGE:
684 req->result = req->db->key_range (req->db, req->txn, &req->dbt1, &req->key_range, req->uint1);
685 break;
686
687 case REQ_TXN_COMMIT:
688 req->result = req->txn->commit (req->txn, req->uint1);
689 break;
690
691 case REQ_TXN_ABORT:
692 req->result = req->txn->abort (req->txn);
693 break;
694
695 case REQ_C_CLOSE:
696 req->result = req->dbc->c_close (req->dbc);
697 break;
698
699 case REQ_C_COUNT:
700 {
701 db_recno_t recno;
702 req->result = req->dbc->c_count (req->dbc, &recno, req->uint1);
703 req->uv1 = recno;
704 }
705 break;
706
707 case REQ_C_PUT:
708 req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1);
709 break;
710
711 case REQ_C_GET:
712 req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1);
713 break;
714
715 case REQ_C_PGET:
716 req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
717 break;
718
719 case REQ_C_DEL:
720 req->result = req->dbc->c_del (req->dbc, req->uint1);
721 break;
722
723 case REQ_SEQ_OPEN:
724 req->result = req->seq->open (req->seq, req->txn, &req->dbt1, req->uint1);
725 break;
726
727 case REQ_SEQ_CLOSE:
728 req->result = req->seq->close (req->seq, req->uint1);
729 break;
730
731 case REQ_SEQ_GET:
732 req->result = req->seq->get (req->seq, req->txn, req->int1, &req->seq_t, req->uint1);
733 break;
734
735 case REQ_SEQ_REMOVE:
736 req->result = req->seq->remove (req->seq, req->txn, req->uint1);
737 break;
738
739 default:
740 req->result = ENOSYS;
741 break;
742 }
743
744 LOCK (reslock);
745
746 ++npending;
747
748 if (!reqq_push (&res_queue, req))
749 /* write a dummy byte to the pipe so fh becomes ready */
750 write (respipe [1], &respipe, 1);
751
752 self->req = 0;
753 worker_clear (self);
754
755 UNLOCK (reslock);
756 }
757
758 quit:
759 LOCK (wrklock);
760 worker_free (self);
761 UNLOCK (wrklock);
762
763 return 0;
764 }
765
766 /*****************************************************************************/
767
768 static void atfork_prepare (void)
769 {
770 LOCK (wrklock);
771 LOCK (reqlock);
772 LOCK (reslock);
773 }
774
775 static void atfork_parent (void)
776 {
777 UNLOCK (reslock);
778 UNLOCK (reqlock);
779 UNLOCK (wrklock);
780 }
781
782 static void atfork_child (void)
783 {
784 aio_req prv;
785
786 while (prv = reqq_shift (&req_queue))
787 req_free (prv);
788
789 while (prv = reqq_shift (&res_queue))
790 req_free (prv);
791
792 while (wrk_first.next != &wrk_first)
793 {
794 worker *wrk = wrk_first.next;
795
796 if (wrk->req)
797 req_free (wrk->req);
798
799 worker_clear (wrk);
800 worker_free (wrk);
801 }
802
803 started = 0;
804 idle = 0;
805 nreqs = 0;
806 nready = 0;
807 npending = 0;
808
809 close (respipe [0]);
810 close (respipe [1]);
811 create_pipe ();
812
813 atfork_parent ();
814 }
815
816 #define dREQ(reqtype) \
817 aio_req req; \
818 int req_pri = next_pri; \
819 next_pri = DEFAULT_PRI + PRI_BIAS; \
820 \
821 if (SvOK (callback) && !SvROK (callback)) \
822 croak ("callback must be undef or of reference type"); \
823 \
824 Newz (0, req, 1, aio_cb); \
825 if (!req) \
826 croak ("out of memory during aio_req allocation"); \
827 \
828 req->callback = newSVsv (callback); \
829 req->type = (reqtype); \
830 req->pri = req_pri
831
832 #define REQ_SEND \
833 req_send (req)
834
835 #define SvPTR(var, arg, type, class, nullok) \
836 if (!SvOK (arg)) \
837 { \
838 if (!nullok) \
839 croak (# var " must be a " # class " object, not undef"); \
840 \
841 (var) = 0; \
842 } \
843 else if (sv_derived_from ((arg), # class)) \
844 { \
845 IV tmp = SvIV ((SV*) SvRV (arg)); \
846 (var) = INT2PTR (type, tmp); \
847 if (!var) \
848 croak (# var " is not a valid " # class " object anymore"); \
849 } \
850 else \
851 croak (# var " is not of type " # class); \
852 \
853
854 static void
855 ptr_nuke (SV *sv)
856 {
857 assert (SvROK (sv));
858 sv_setiv (SvRV (sv), 0);
859 }
860
861 MODULE = BDB PACKAGE = BDB
862
863 PROTOTYPES: ENABLE
864
865 BOOT:
866 {
867 HV *stash = gv_stashpv ("BDB", 1);
868
869 static const struct {
870 const char *name;
871 IV iv;
872 } *civ, const_iv[] = {
873 #define const_iv(name) { # name, (IV)DB_ ## name },
874 const_iv (RPCCLIENT)
875 const_iv (INIT_CDB)
876 const_iv (INIT_LOCK)
877 const_iv (INIT_LOG)
878 const_iv (INIT_MPOOL)
879 const_iv (INIT_REP)
880 const_iv (INIT_TXN)
881 const_iv (RECOVER)
882 const_iv (INIT_TXN)
883 const_iv (RECOVER_FATAL)
884 const_iv (CREATE)
885 const_iv (USE_ENVIRON)
886 const_iv (USE_ENVIRON_ROOT)
887 const_iv (LOCKDOWN)
888 const_iv (PRIVATE)
889 const_iv (REGISTER)
890 const_iv (SYSTEM_MEM)
891 const_iv (AUTO_COMMIT)
892 const_iv (CDB_ALLDB)
893 const_iv (DIRECT_DB)
894 const_iv (DIRECT_LOG)
895 const_iv (DSYNC_DB)
896 const_iv (DSYNC_LOG)
897 const_iv (LOG_AUTOREMOVE)
898 const_iv (LOG_INMEMORY)
899 const_iv (NOLOCKING)
900 const_iv (MULTIVERSION)
901 const_iv (NOMMAP)
902 const_iv (NOPANIC)
903 const_iv (OVERWRITE)
904 const_iv (PANIC_ENVIRONMENT)
905 const_iv (REGION_INIT)
906 const_iv (TIME_NOTGRANTED)
907 const_iv (TXN_NOSYNC)
908 const_iv (TXN_SNAPSHOT)
909 const_iv (TXN_WRITE_NOSYNC)
910 const_iv (WRITECURSOR)
911 const_iv (YIELDCPU)
912 const_iv (ENCRYPT_AES)
913 const_iv (XA_CREATE)
914 const_iv (BTREE)
915 const_iv (HASH)
916 const_iv (QUEUE)
917 const_iv (RECNO)
918 const_iv (UNKNOWN)
919 const_iv (EXCL)
920 const_iv (READ_COMMITTED)
921 const_iv (READ_UNCOMMITTED)
922 const_iv (TRUNCATE)
923 const_iv (NOSYNC)
924 const_iv (CHKSUM)
925 const_iv (ENCRYPT)
926 const_iv (TXN_NOT_DURABLE)
927 const_iv (DUP)
928 const_iv (DUPSORT)
929 const_iv (RECNUM)
930 const_iv (RENUMBER)
931 const_iv (REVSPLITOFF)
932 const_iv (INORDER)
933 const_iv (CONSUME)
934 const_iv (CONSUME_WAIT)
935 const_iv (GET_BOTH)
936 const_iv (GET_BOTH_RANGE)
937 //const_iv (SET_RECNO)
938 //const_iv (MULTIPLE)
939 const_iv (SNAPSHOT)
940 const_iv (JOIN_ITEM)
941 const_iv (RMW)
942
943 const_iv (NOTFOUND)
944 const_iv (KEYEMPTY)
945 const_iv (LOCK_DEADLOCK)
946 const_iv (LOCK_NOTGRANTED)
947 const_iv (RUNRECOVERY)
948 const_iv (OLD_VERSION)
949 const_iv (REP_HANDLE_DEAD)
950 const_iv (REP_LOCKOUT)
951 const_iv (SECONDARY_BAD)
952
953 const_iv (FREE_SPACE)
954 const_iv (FREELIST_ONLY)
955
956 const_iv (APPEND)
957 const_iv (NODUPDATA)
958 const_iv (NOOVERWRITE)
959
960 const_iv (TXN_NOWAIT)
961 const_iv (TXN_SNAPSHOT)
962 const_iv (TXN_SYNC)
963
964 const_iv (SET_LOCK_TIMEOUT)
965 const_iv (SET_TXN_TIMEOUT)
966
967 const_iv (JOIN_ITEM)
968 const_iv (FIRST)
969 const_iv (NEXT)
970 const_iv (NEXT_DUP)
971 const_iv (NEXT_NODUP)
972 const_iv (PREV)
973 const_iv (PREV_NODUP)
974 const_iv (SET)
975 const_iv (SET_RANGE)
976 const_iv (LAST)
977 const_iv (BEFORE)
978 const_iv (AFTER)
979 const_iv (CURRENT)
980 const_iv (KEYFIRST)
981 const_iv (KEYLAST)
982 const_iv (NODUPDATA)
983
984 const_iv (FORCE)
985
986 const_iv (LOCK_DEFAULT)
987 const_iv (LOCK_EXPIRE)
988 const_iv (LOCK_MAXLOCKS)
989 const_iv (LOCK_MAXWRITE)
990 const_iv (LOCK_MINLOCKS)
991 const_iv (LOCK_MINWRITE)
992 const_iv (LOCK_OLDEST)
993 const_iv (LOCK_RANDOM)
994 const_iv (LOCK_YOUNGEST)
995
996 const_iv (SEQ_DEC)
997 const_iv (SEQ_INC)
998 const_iv (SEQ_WRAP)
999 };
1000
1001 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1002 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1003
1004 create_pipe ();
1005 ATFORK (atfork_prepare, atfork_parent, atfork_child);
1006 }
1007
1008 void
1009 max_poll_reqs (int nreqs)
1010 PROTOTYPE: $
1011 CODE:
1012 max_poll_reqs = nreqs;
1013
1014 void
1015 max_poll_time (double nseconds)
1016 PROTOTYPE: $
1017 CODE:
1018 max_poll_time = nseconds * AIO_TICKS;
1019
1020 void
1021 min_parallel (int nthreads)
1022 PROTOTYPE: $
1023
1024 void
1025 max_parallel (int nthreads)
1026 PROTOTYPE: $
1027
1028 void
1029 max_idle (int nthreads)
1030 PROTOTYPE: $
1031 CODE:
1032 set_max_idle (nthreads);
1033
1034 int
1035 max_outstanding (int maxreqs)
1036 PROTOTYPE: $
1037 CODE:
1038 RETVAL = max_outstanding;
1039 max_outstanding = maxreqs;
1040 OUTPUT:
1041 RETVAL
1042
1043 int
1044 dbreq_pri (int pri = 0)
1045 PROTOTYPE: ;$
1046 CODE:
1047 RETVAL = next_pri - PRI_BIAS;
1048 if (items > 0)
1049 {
1050 if (pri < PRI_MIN) pri = PRI_MIN;
1051 if (pri > PRI_MAX) pri = PRI_MAX;
1052 next_pri = pri + PRI_BIAS;
1053 }
1054 OUTPUT:
1055 RETVAL
1056
1057 void
1058 dbreq_nice (int nice = 0)
1059 CODE:
1060 nice = next_pri - nice;
1061 if (nice < PRI_MIN) nice = PRI_MIN;
1062 if (nice > PRI_MAX) nice = PRI_MAX;
1063 next_pri = nice + PRI_BIAS;
1064
1065 void
1066 flush ()
1067 PROTOTYPE:
1068 CODE:
1069 while (nreqs)
1070 {
1071 poll_wait ();
1072 poll_cb ();
1073 }
1074
1075 int
1076 poll ()
1077 PROTOTYPE:
1078 CODE:
1079 poll_wait ();
1080 RETVAL = poll_cb ();
1081 OUTPUT:
1082 RETVAL
1083
1084 int
1085 poll_fileno ()
1086 PROTOTYPE:
1087 CODE:
1088 RETVAL = respipe [0];
1089 OUTPUT:
1090 RETVAL
1091
1092 int
1093 poll_cb (...)
1094 PROTOTYPE:
1095 CODE:
1096 RETVAL = poll_cb ();
1097 OUTPUT:
1098 RETVAL
1099
1100 void
1101 poll_wait ()
1102 PROTOTYPE:
1103 CODE:
1104 poll_wait ();
1105
1106 int
1107 nreqs ()
1108 PROTOTYPE:
1109 CODE:
1110 RETVAL = nreqs;
1111 OUTPUT:
1112 RETVAL
1113
1114 int
1115 nready ()
1116 PROTOTYPE:
1117 CODE:
1118 RETVAL = get_nready ();
1119 OUTPUT:
1120 RETVAL
1121
1122 int
1123 npending ()
1124 PROTOTYPE:
1125 CODE:
1126 RETVAL = get_npending ();
1127 OUTPUT:
1128 RETVAL
1129
1130 int
1131 nthreads ()
1132 PROTOTYPE:
1133 CODE:
1134 if (WORDACCESS_UNSAFE) LOCK (wrklock);
1135 RETVAL = started;
1136 if (WORDACCESS_UNSAFE) UNLOCK (wrklock);
1137 OUTPUT:
1138 RETVAL
1139
1140 void
1141 set_sync_prepare (SV *cb)
1142 PROTOTYPE: &
1143 CODE:
1144 SvREFCNT_dec (prepare_cb);
1145 prepare_cb = newSVsv (cb);
1146
1147
1148 DB_ENV *
1149 db_env_create (U32 env_flags = 0)
1150 CODE:
1151 {
1152 errno = db_env_create (&RETVAL, env_flags);
1153 if (errno)
1154 croak ("db_env_create: %s", db_strerror (errno));
1155 }
1156 OUTPUT:
1157 RETVAL
1158
1159 void
1160 db_env_open (DB_ENV *env, octetstring db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
1161 CODE:
1162 {
1163 env->set_thread_count (env, get_nthreads ());
1164
1165 dREQ (REQ_ENV_OPEN);
1166 req->env = env;
1167 req->uint1 = open_flags | DB_THREAD;
1168 req->int1 = mode;
1169 req->buf1 = strdup_ornull (db_home);
1170 REQ_SEND;
1171 }
1172
1173 void
1174 db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef)
1175 CODE:
1176 {
1177 dREQ (REQ_ENV_CLOSE);
1178 req->env = env;
1179 req->uint1 = flags;
1180 REQ_SEND;
1181 ptr_nuke (ST (0));
1182 }
1183
1184 void
1185 db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1186 CODE:
1187 {
1188 dREQ (REQ_ENV_TXN_CHECKPOINT);
1189 req->env = env;
1190 req->uint1 = kbyte;
1191 req->int1 = min;
1192 req->uint2 = flags;
1193 REQ_SEND;
1194 }
1195
1196 void
1197 db_env_lock_detect (DB_ENV *env, U32 flags = 0, U32 atype = DB_LOCK_DEFAULT, SV *dummy = 0, SV *callback = &PL_sv_undef)
1198 CODE:
1199 {
1200 dREQ (REQ_ENV_LOCK_DETECT);
1201 req->env = env;
1202 req->uint1 = flags;
1203 req->uint2 = atype;
1204 REQ_SEND;
1205 }
1206
1207 void
1208 db_env_memp_sync (DB_ENV *env, SV *dummy = 0, SV *callback = &PL_sv_undef)
1209 CODE:
1210 {
1211 dREQ (REQ_ENV_MEMP_SYNC);
1212 req->env = env;
1213 REQ_SEND;
1214 }
1215
1216 void
1217 db_env_memp_trickle (DB_ENV *env, int percent, SV *dummy = 0, SV *callback = &PL_sv_undef)
1218 CODE:
1219 {
1220 dREQ (REQ_ENV_MEMP_TRICKLE);
1221 req->env = env;
1222 req->int1 = percent;
1223 REQ_SEND;
1224 }
1225
1226
1227 DB *
1228 db_create (DB_ENV *env = 0, U32 flags = 0)
1229 CODE:
1230 {
1231 errno = db_create (&RETVAL, env, flags);
1232 if (errno)
1233 croak ("db_create: %s", db_strerror (errno));
1234
1235 if (RETVAL)
1236 RETVAL->app_private = (void *)newSVsv (ST (0));
1237 }
1238 OUTPUT:
1239 RETVAL
1240
1241 void
1242 db_open (DB *db, DB_TXN_ornull *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
1243 CODE:
1244 {
1245 dREQ (REQ_DB_OPEN);
1246 req->db = db;
1247 req->txn = txnid;
1248 req->buf1 = strdup_ornull (file);
1249 req->buf2 = strdup_ornull (database);
1250 req->int1 = type;
1251 req->uint1 = flags | DB_THREAD;
1252 req->int2 = mode;
1253 REQ_SEND;
1254 }
1255
1256 void
1257 db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1258 CODE:
1259 {
1260 dREQ (REQ_DB_CLOSE);
1261 req->db = db;
1262 req->uint1 = flags;
1263 req->sv1 = (SV *)db->app_private;
1264 REQ_SEND;
1265 ptr_nuke (ST (0));
1266 }
1267
1268 void
1269 db_compact (DB *db, DB_TXN_ornull *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef)
1270 CODE:
1271 {
1272 dREQ (REQ_DB_COMPACT);
1273 req->db = db;
1274 req->txn = txn;
1275 sv_to_dbt (&req->dbt1, start);
1276 sv_to_dbt (&req->dbt2, stop);
1277 req->uint1 = flags;
1278 REQ_SEND;
1279 }
1280
1281 void
1282 db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1283 CODE:
1284 {
1285 dREQ (REQ_DB_SYNC);
1286 req->db = db;
1287 req->uint1 = flags;
1288 REQ_SEND;
1289 }
1290
1291 void
1292 db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = &PL_sv_undef)
1293 CODE:
1294 {
1295 dREQ (REQ_DB_KEY_RANGE);
1296 req->db = db;
1297 req->txn = txn;
1298 sv_to_dbt (&req->dbt1, key);
1299 req->uint1 = flags;
1300 req->sv1 = SvREFCNT_inc (key_range); SvREADONLY_on (key_range);
1301 REQ_SEND;
1302 }
1303
1304 void
1305 db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1306 CODE:
1307 {
1308 dREQ (REQ_DB_PUT);
1309 req->db = db;
1310 req->txn = txn;
1311 sv_to_dbt (&req->dbt1, key);
1312 sv_to_dbt (&req->dbt2, data);
1313 req->uint1 = flags;
1314 REQ_SEND;
1315 }
1316
1317 void
1318 db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1319 CODE:
1320 {
1321 dREQ (REQ_DB_GET);
1322 req->db = db;
1323 req->txn = txn;
1324 req->uint1 = flags;
1325 sv_to_dbt (&req->dbt1, key);
1326 req->dbt3.flags = DB_DBT_MALLOC;
1327 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1328 REQ_SEND;
1329 }
1330
1331 void
1332 db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1333 CODE:
1334 {
1335 dREQ (REQ_DB_PGET);
1336 req->db = db;
1337 req->txn = txn;
1338 req->uint1 = flags;
1339 sv_to_dbt (&req->dbt1, key);
1340 sv_to_dbt (&req->dbt2, pkey);
1341 req->dbt3.flags = DB_DBT_MALLOC;
1342 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1343 REQ_SEND;
1344 }
1345
1346 void
1347 db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1348 CODE:
1349 {
1350 dREQ (REQ_DB_DEL);
1351 req->db = db;
1352 req->txn = txn;
1353 req->uint1 = flags;
1354 sv_to_dbt (&req->dbt1, key);
1355 REQ_SEND;
1356 }
1357
1358 void
1359 db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef)
1360 CODE:
1361 {
1362 dREQ (REQ_TXN_COMMIT);
1363 req->txn = txn;
1364 req->uint1 = flags;
1365 REQ_SEND;
1366 ptr_nuke (ST (0));
1367 }
1368
1369 void
1370 db_txn_abort (DB_TXN *txn, SV *callback = &PL_sv_undef)
1371 CODE:
1372 {
1373 dREQ (REQ_TXN_ABORT);
1374 req->txn = txn;
1375 REQ_SEND;
1376 ptr_nuke (ST (0));
1377 }
1378
1379 void
1380 db_c_close (DBC *dbc, SV *callback = &PL_sv_undef)
1381 CODE:
1382 {
1383 dREQ (REQ_C_CLOSE);
1384 req->dbc = dbc;
1385 REQ_SEND;
1386 ptr_nuke (ST (0));
1387 }
1388
1389 void
1390 db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = &PL_sv_undef)
1391 CODE:
1392 {
1393 dREQ (REQ_C_COUNT);
1394 req->dbc = dbc;
1395 req->sv1 = SvREFCNT_inc (count);
1396 REQ_SEND;
1397 }
1398
1399 void
1400 db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1401 CODE:
1402 {
1403 dREQ (REQ_C_PUT);
1404 req->dbc = dbc;
1405 sv_to_dbt (&req->dbt1, key);
1406 sv_to_dbt (&req->dbt2, data);
1407 req->uint1 = flags;
1408 REQ_SEND;
1409 }
1410
1411 void
1412 db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1413 CODE:
1414 {
1415 dREQ (REQ_C_GET);
1416 req->dbc = dbc;
1417 req->uint1 = flags;
1418 if ((flags & DB_SET) == DB_SET
1419 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1420 sv_to_dbt (&req->dbt1, key);
1421 else
1422 req->dbt1.flags = DB_DBT_MALLOC;
1423
1424 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1425
1426 if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1427 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1428 sv_to_dbt (&req->dbt3, data);
1429 else
1430 req->dbt3.flags = DB_DBT_MALLOC;
1431
1432 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1433 REQ_SEND;
1434 }
1435
1436 void
1437 db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1438 CODE:
1439 {
1440 dREQ (REQ_C_PGET);
1441 req->dbc = dbc;
1442 req->uint1 = flags;
1443 if ((flags & DB_SET) == DB_SET
1444 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1445 sv_to_dbt (&req->dbt1, key);
1446 else
1447 req->dbt1.flags = DB_DBT_MALLOC;
1448
1449 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1450
1451 req->dbt2.flags = DB_DBT_MALLOC;
1452 req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey);
1453
1454 if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1455 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1456 sv_to_dbt (&req->dbt3, data);
1457 else
1458 req->dbt3.flags = DB_DBT_MALLOC;
1459
1460 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1461 REQ_SEND;
1462 }
1463
1464 void
1465 db_c_del (DBC *dbc, U32 flags = 0, SV *callback = &PL_sv_undef)
1466 CODE:
1467 {
1468 dREQ (REQ_C_DEL);
1469 req->dbc = dbc;
1470 req->uint1 = flags;
1471 REQ_SEND;
1472 }
1473
1474
1475 void
1476 db_sequence_open (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1477 CODE:
1478 {
1479 dREQ (REQ_SEQ_OPEN);
1480 req->seq = seq;
1481 req->txn = txnid;
1482 req->uint1 = flags | DB_THREAD;
1483 sv_to_dbt (&req->dbt1, key);
1484 REQ_SEND;
1485 }
1486
1487 void
1488 db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = &PL_sv_undef)
1489 CODE:
1490 {
1491 dREQ (REQ_SEQ_CLOSE);
1492 req->seq = seq;
1493 req->uint1 = flags;
1494 REQ_SEND;
1495 ptr_nuke (ST (0));
1496 }
1497
1498 void
1499 db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = &PL_sv_undef)
1500 CODE:
1501 {
1502 dREQ (REQ_SEQ_GET);
1503 req->seq = seq;
1504 req->txn = txnid;
1505 req->int1 = delta;
1506 req->uint1 = flags;
1507 req->sv1 = SvREFCNT_inc (seq_value); SvREADONLY_on (seq_value);
1508 REQ_SEND;
1509 }
1510
1511 void
1512 db_sequence_remove (DB_SEQUENCE *seq, DB_TXN_ornull *txnid = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1513 CODE:
1514 {
1515 dREQ (REQ_SEQ_REMOVE);
1516 req->seq = seq;
1517 req->txn = txnid;
1518 req->uint1 = flags;
1519 REQ_SEND;
1520 }
1521
1522
1523 MODULE = BDB PACKAGE = BDB::Env
1524
1525 void
1526 DESTROY (DB_ENV_ornull *env)
1527 CODE:
1528 if (env)
1529 env->close (env, 0);
1530
1531 int set_data_dir (DB_ENV *env, const char *dir)
1532 CODE:
1533 RETVAL = env->set_data_dir (env, dir);
1534 OUTPUT:
1535 RETVAL
1536
1537 int set_tmp_dir (DB_ENV *env, const char *dir)
1538 CODE:
1539 RETVAL = env->set_tmp_dir (env, dir);
1540 OUTPUT:
1541 RETVAL
1542
1543 int set_lg_dir (DB_ENV *env, const char *dir)
1544 CODE:
1545 RETVAL = env->set_lg_dir (env, dir);
1546 OUTPUT:
1547 RETVAL
1548
1549 int set_shm_key (DB_ENV *env, long shm_key)
1550 CODE:
1551 RETVAL = env->set_shm_key (env, shm_key);
1552 OUTPUT:
1553 RETVAL
1554
1555 int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0)
1556 CODE:
1557 RETVAL = env->set_cachesize (env, gbytes, bytes, ncache);
1558 OUTPUT:
1559 RETVAL
1560
1561 int set_flags (DB_ENV *env, U32 flags, int onoff)
1562 CODE:
1563 RETVAL = env->set_flags (env, flags, onoff);
1564 OUTPUT:
1565 RETVAL
1566
1567 int set_encrypt (DB_ENV *env, const char *password, U32 flags = 0)
1568 CODE:
1569 RETVAL = env->set_encrypt (env, password, flags);
1570 OUTPUT:
1571 RETVAL
1572
1573 int set_timeout (DB_ENV *env, NV timeout, U32 flags)
1574 CODE:
1575 RETVAL = env->set_timeout (env, timeout * 1000000, flags);
1576 OUTPUT:
1577 RETVAL
1578
1579 int set_mp_max_openfd (DB_ENV *env, int maxopenfd);
1580 CODE:
1581 RETVAL = env->set_mp_max_openfd (env, maxopenfd);
1582 OUTPUT:
1583 RETVAL
1584
1585 int set_mp_max_write (DB_ENV *env, int maxwrite, int maxwrite_sleep);
1586 CODE:
1587 RETVAL = env->set_mp_max_write (env, maxwrite, maxwrite_sleep);
1588 OUTPUT:
1589 RETVAL
1590
1591 int set_mp_mmapsize (DB_ENV *env, int mmapsize_mb)
1592 CODE:
1593 RETVAL = env->set_mp_mmapsize (env, ((size_t)mmapsize_mb) << 20);
1594 OUTPUT:
1595 RETVAL
1596
1597 int set_lk_detect (DB_ENV *env, U32 detect = DB_LOCK_DEFAULT)
1598 CODE:
1599 RETVAL = env->set_lk_detect (env, detect);
1600 OUTPUT:
1601 RETVAL
1602
1603 int set_lk_max_lockers (DB_ENV *env, U32 max)
1604 CODE:
1605 RETVAL = env->set_lk_max_lockers (env, max);
1606 OUTPUT:
1607 RETVAL
1608
1609 int set_lk_max_locks (DB_ENV *env, U32 max)
1610 CODE:
1611 RETVAL = env->set_lk_max_locks (env, max);
1612 OUTPUT:
1613 RETVAL
1614
1615 int set_lk_max_objects (DB_ENV *env, U32 max)
1616 CODE:
1617 RETVAL = env->set_lk_max_objects (env, max);
1618 OUTPUT:
1619 RETVAL
1620
1621 int set_lg_bsize (DB_ENV *env, U32 max)
1622 CODE:
1623 RETVAL = env->set_lg_bsize (env, max);
1624 OUTPUT:
1625 RETVAL
1626
1627 int set_lg_max (DB_ENV *env, U32 max)
1628 CODE:
1629 RETVAL = env->set_lg_max (env, max);
1630 OUTPUT:
1631 RETVAL
1632
1633 DB_TXN *
1634 txn_begin (DB_ENV *env, DB_TXN_ornull *parent = 0, U32 flags = 0)
1635 CODE:
1636 errno = env->txn_begin (env, parent, &RETVAL, flags);
1637 if (errno)
1638 croak ("DB_ENV->txn_begin: %s", db_strerror (errno));
1639 OUTPUT:
1640 RETVAL
1641
1642 MODULE = BDB PACKAGE = BDB::Db
1643
1644 void
1645 DESTROY (DB_ornull *db)
1646 CODE:
1647 if (db)
1648 {
1649 SV *env = (SV *)db->app_private;
1650 db->close (db, 0);
1651 SvREFCNT_dec (env);
1652 }
1653
1654 int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0)
1655 CODE:
1656 RETVAL = db->set_cachesize (db, gbytes, bytes, ncache);
1657 OUTPUT:
1658 RETVAL
1659
1660 int set_flags (DB *db, U32 flags);
1661 CODE:
1662 RETVAL = db->set_flags (db, flags);
1663 OUTPUT:
1664 RETVAL
1665
1666 int set_encrypt (DB *db, const char *password, U32 flags)
1667 CODE:
1668 RETVAL = db->set_encrypt (db, password, flags);
1669 OUTPUT:
1670 RETVAL
1671
1672 int set_lorder (DB *db, int lorder)
1673 CODE:
1674 RETVAL = db->set_lorder (db, lorder);
1675 OUTPUT:
1676 RETVAL
1677
1678 int set_bt_minkey (DB *db, U32 minkey)
1679 CODE:
1680 RETVAL = db->set_bt_minkey (db, minkey);
1681 OUTPUT:
1682 RETVAL
1683
1684 int set_re_delim(DB *db, int delim);
1685 CODE:
1686 RETVAL = db->set_re_delim (db, delim);
1687 OUTPUT:
1688 RETVAL
1689
1690 int set_re_pad (DB *db, int re_pad)
1691 CODE:
1692 RETVAL = db->set_re_pad (db, re_pad);
1693 OUTPUT:
1694 RETVAL
1695
1696 int set_re_source (DB *db, char *source)
1697 CODE:
1698 RETVAL = db->set_re_source (db, source);
1699 OUTPUT:
1700 RETVAL
1701
1702 int set_re_len (DB *db, U32 re_len)
1703 CODE:
1704 RETVAL = db->set_re_len (db, re_len);
1705 OUTPUT:
1706 RETVAL
1707
1708 int set_h_ffactor (DB *db, U32 h_ffactor)
1709 CODE:
1710 RETVAL = db->set_h_ffactor (db, h_ffactor);
1711 OUTPUT:
1712 RETVAL
1713
1714 int set_h_nelem (DB *db, U32 h_nelem)
1715 CODE:
1716 RETVAL = db->set_h_nelem (db, h_nelem);
1717 OUTPUT:
1718 RETVAL
1719
1720 int set_q_extentsize (DB *db, U32 extentsize)
1721 CODE:
1722 RETVAL = db->set_q_extentsize (db, extentsize);
1723 OUTPUT:
1724 RETVAL
1725
1726 DBC *
1727 cursor (DB *db, DB_TXN_ornull *txn = 0, U32 flags = 0)
1728 CODE:
1729 errno = db->cursor (db, txn, &RETVAL, flags);
1730 if (errno)
1731 croak ("DB->cursor: %s", db_strerror (errno));
1732 OUTPUT:
1733 RETVAL
1734
1735 DB_SEQUENCE *
1736 sequence (DB *db, U32 flags = 0)
1737 CODE:
1738 {
1739 errno = db_sequence_create (&RETVAL, db, flags);
1740 if (errno)
1741 croak ("db_sequence_create: %s", db_strerror (errno));
1742 }
1743 OUTPUT:
1744 RETVAL
1745
1746
1747 MODULE = BDB PACKAGE = BDB::Txn
1748
1749 void
1750 DESTROY (DB_TXN_ornull *txn)
1751 CODE:
1752 if (txn)
1753 txn->abort (txn);
1754
1755 int set_timeout (DB_TXN *txn, NV timeout, U32 flags)
1756 CODE:
1757 RETVAL = txn->set_timeout (txn, timeout * 1000000, flags);
1758 OUTPUT:
1759 RETVAL
1760
1761
1762 MODULE = BDB PACKAGE = BDB::Cursor
1763
1764 void
1765 DESTROY (DBC_ornull *dbc)
1766 CODE:
1767 if (dbc)
1768 dbc->c_close (dbc);
1769
1770 MODULE = BDB PACKAGE = BDB::Sequence
1771
1772 void
1773 DESTROY (DB_SEQUENCE_ornull *seq)
1774 CODE:
1775 if (seq)
1776 seq->close (seq, 0);
1777
1778 int initial_value (DB_SEQUENCE *seq, db_seq_t value)
1779 CODE:
1780 RETVAL = seq->initial_value (seq, value);
1781 OUTPUT:
1782 RETVAL
1783
1784 int set_cachesize (DB_SEQUENCE *seq, U32 size)
1785 CODE:
1786 RETVAL = seq->set_cachesize (seq, size);
1787 OUTPUT:
1788 RETVAL
1789
1790 int set_flags (DB_SEQUENCE *seq, U32 flags)
1791 CODE:
1792 RETVAL = seq->set_flags (seq, flags);
1793 OUTPUT:
1794 RETVAL
1795
1796 int set_range (DB_SEQUENCE *seq, db_seq_t min, db_seq_t max)
1797 CODE:
1798 RETVAL = seq->set_range (seq, min, max);
1799 OUTPUT:
1800 RETVAL
1801