ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/BDB/BDB.xs
Revision: 1.12
Committed: Sun Jul 8 09:16:19 2007 UTC (16 years, 10 months ago) by root
Branch: MAIN
Changes since 1.11: +59 -60 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 = X_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 = X_MUTEX_INIT;
165 static mutex_t reqlock = X_MUTEX_INIT;
166 static cond_t reqwait = X_COND_INIT;
167
168 #if WORDACCESS_UNSAFE
169
170 static unsigned int get_nready ()
171 {
172 unsigned int retval;
173
174 X_LOCK (reqlock);
175 retval = nready;
176 X_UNLOCK (reqlock);
177
178 return retval;
179 }
180
181 static unsigned int get_npending ()
182 {
183 unsigned int retval;
184
185 X_LOCK (reslock);
186 retval = npending;
187 X_UNLOCK (reslock);
188
189 return retval;
190 }
191
192 static unsigned int get_nthreads ()
193 {
194 unsigned int retval;
195
196 X_LOCK (wrklock);
197 retval = started;
198 X_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 X_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 X_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 X_LOCK (reqlock);
403 ++nready;
404 reqq_push (&req_queue, req);
405 X_COND_SIGNAL (reqwait);
406 X_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 X_LOCK (reqlock);
430 reqq_push (&req_queue, req);
431 X_COND_SIGNAL (reqwait);
432 X_UNLOCK (reqlock);
433
434 X_LOCK (wrklock);
435 --started;
436 X_UNLOCK (wrklock);
437 }
438
439 static void set_max_idle (int nthreads)
440 {
441 if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
442 max_idle = nthreads <= 0 ? 1 : nthreads;
443 if (WORDACCESS_UNSAFE) X_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) X_LOCK (reslock);
469 size = res_queue.size;
470 if (WORDACCESS_UNSAFE) X_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 X_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 X_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 /*****************************************************************************/
559
560 static void *aio_proc (void *thr_arg)
561 {
562 aio_req req;
563 struct timespec ts;
564 worker *self = (worker *)thr_arg;
565
566 /* try to distribute timeouts somewhat evenly */
567 ts.tv_nsec = (((unsigned long)self + (unsigned long)ts.tv_sec) & 1023UL)
568 * (1000000000UL / 1024UL);
569
570 for (;;)
571 {
572 ts.tv_sec = time (0) + IDLE_TIMEOUT;
573
574 X_LOCK (reqlock);
575
576 for (;;)
577 {
578 self->req = req = reqq_shift (&req_queue);
579
580 if (req)
581 break;
582
583 ++idle;
584
585 if (X_COND_TIMEDWAIT (reqwait, reqlock, ts)
586 == ETIMEDOUT)
587 {
588 if (idle > max_idle)
589 {
590 --idle;
591 X_UNLOCK (reqlock);
592 X_LOCK (wrklock);
593 --started;
594 X_UNLOCK (wrklock);
595 goto quit;
596 }
597
598 /* we are allowed to idle, so do so without any timeout */
599 X_COND_WAIT (reqwait, reqlock);
600 ts.tv_sec = time (0) + IDLE_TIMEOUT;
601 }
602
603 --idle;
604 }
605
606 --nready;
607
608 X_UNLOCK (reqlock);
609
610 switch (req->type)
611 {
612 case REQ_QUIT:
613 goto quit;
614
615 case REQ_ENV_OPEN:
616 req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1);
617 break;
618
619 case REQ_ENV_CLOSE:
620 req->result = req->env->close (req->env, req->uint1);
621 break;
622
623 case REQ_ENV_TXN_CHECKPOINT:
624 req->result = req->env->txn_checkpoint (req->env, req->uint1, req->int1, req->uint2);
625 break;
626
627 case REQ_ENV_LOCK_DETECT:
628 req->result = req->env->lock_detect (req->env, req->uint1, req->uint2, &req->int1);
629 break;
630
631 case REQ_ENV_MEMP_SYNC:
632 req->result = req->env->memp_sync (req->env, 0);
633 break;
634
635 case REQ_ENV_MEMP_TRICKLE:
636 req->result = req->env->memp_trickle (req->env, req->int1, &req->int2);
637 break;
638
639 case REQ_DB_OPEN:
640 req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2);
641 break;
642
643 case REQ_DB_CLOSE:
644 req->result = req->db->close (req->db, req->uint1);
645 break;
646
647 case REQ_DB_COMPACT:
648 req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0);
649 break;
650
651 case REQ_DB_SYNC:
652 req->result = req->db->sync (req->db, req->uint1);
653 break;
654
655 case REQ_DB_PUT:
656 req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1);
657 break;
658
659 case REQ_DB_GET:
660 req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1);
661 break;
662
663 case REQ_DB_PGET:
664 req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
665 break;
666
667 case REQ_DB_DEL:
668 req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1);
669 break;
670
671 case REQ_DB_KEY_RANGE:
672 req->result = req->db->key_range (req->db, req->txn, &req->dbt1, &req->key_range, req->uint1);
673 break;
674
675 case REQ_TXN_COMMIT:
676 req->result = req->txn->commit (req->txn, req->uint1);
677 break;
678
679 case REQ_TXN_ABORT:
680 req->result = req->txn->abort (req->txn);
681 break;
682
683 case REQ_C_CLOSE:
684 req->result = req->dbc->c_close (req->dbc);
685 break;
686
687 case REQ_C_COUNT:
688 {
689 db_recno_t recno;
690 req->result = req->dbc->c_count (req->dbc, &recno, req->uint1);
691 req->uv1 = recno;
692 }
693 break;
694
695 case REQ_C_PUT:
696 req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1);
697 break;
698
699 case REQ_C_GET:
700 req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1);
701 break;
702
703 case REQ_C_PGET:
704 req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
705 break;
706
707 case REQ_C_DEL:
708 req->result = req->dbc->c_del (req->dbc, req->uint1);
709 break;
710
711 case REQ_SEQ_OPEN:
712 req->result = req->seq->open (req->seq, req->txn, &req->dbt1, req->uint1);
713 break;
714
715 case REQ_SEQ_CLOSE:
716 req->result = req->seq->close (req->seq, req->uint1);
717 break;
718
719 case REQ_SEQ_GET:
720 req->result = req->seq->get (req->seq, req->txn, req->int1, &req->seq_t, req->uint1);
721 break;
722
723 case REQ_SEQ_REMOVE:
724 req->result = req->seq->remove (req->seq, req->txn, req->uint1);
725 break;
726
727 default:
728 req->result = ENOSYS;
729 break;
730 }
731
732 X_LOCK (reslock);
733
734 ++npending;
735
736 if (!reqq_push (&res_queue, req))
737 /* write a dummy byte to the pipe so fh becomes ready */
738 write (respipe [1], &respipe, 1);
739
740 self->req = 0;
741 worker_clear (self);
742
743 X_UNLOCK (reslock);
744 }
745
746 quit:
747 X_LOCK (wrklock);
748 worker_free (self);
749 X_UNLOCK (wrklock);
750
751 return 0;
752 }
753
754 /*****************************************************************************/
755
756 static void atfork_prepare (void)
757 {
758 X_LOCK (wrklock);
759 X_LOCK (reqlock);
760 X_LOCK (reslock);
761 }
762
763 static void atfork_parent (void)
764 {
765 X_UNLOCK (reslock);
766 X_UNLOCK (reqlock);
767 X_UNLOCK (wrklock);
768 }
769
770 static void atfork_child (void)
771 {
772 aio_req prv;
773
774 while (prv = reqq_shift (&req_queue))
775 req_free (prv);
776
777 while (prv = reqq_shift (&res_queue))
778 req_free (prv);
779
780 while (wrk_first.next != &wrk_first)
781 {
782 worker *wrk = wrk_first.next;
783
784 if (wrk->req)
785 req_free (wrk->req);
786
787 worker_clear (wrk);
788 worker_free (wrk);
789 }
790
791 started = 0;
792 idle = 0;
793 nreqs = 0;
794 nready = 0;
795 npending = 0;
796
797 close (respipe [0]);
798 close (respipe [1]);
799
800 if (!create_pipe (respipe))
801 croak ("unable to initialize result pipe");
802
803 atfork_parent ();
804 }
805
806 #define dREQ(reqtype) \
807 aio_req req; \
808 int req_pri = next_pri; \
809 next_pri = DEFAULT_PRI + PRI_BIAS; \
810 \
811 if (SvOK (callback) && !SvROK (callback)) \
812 croak ("callback must be undef or of reference type"); \
813 \
814 Newz (0, req, 1, aio_cb); \
815 if (!req) \
816 croak ("out of memory during aio_req allocation"); \
817 \
818 req->callback = newSVsv (callback); \
819 req->type = (reqtype); \
820 req->pri = req_pri
821
822 #define REQ_SEND \
823 req_send (req)
824
825 #define SvPTR(var, arg, type, class, nullok) \
826 if (!SvOK (arg)) \
827 { \
828 if (!nullok) \
829 croak (# var " must be a " # class " object, not undef"); \
830 \
831 (var) = 0; \
832 } \
833 else if (sv_derived_from ((arg), # class)) \
834 { \
835 IV tmp = SvIV ((SV*) SvRV (arg)); \
836 (var) = INT2PTR (type, tmp); \
837 if (!var) \
838 croak (# var " is not a valid " # class " object anymore"); \
839 } \
840 else \
841 croak (# var " is not of type " # class); \
842 \
843
844 static void
845 ptr_nuke (SV *sv)
846 {
847 assert (SvROK (sv));
848 sv_setiv (SvRV (sv), 0);
849 }
850
851 MODULE = BDB PACKAGE = BDB
852
853 PROTOTYPES: ENABLE
854
855 BOOT:
856 {
857 HV *stash = gv_stashpv ("BDB", 1);
858
859 static const struct {
860 const char *name;
861 IV iv;
862 } *civ, const_iv[] = {
863 #define const_iv(name) { # name, (IV)DB_ ## name },
864 const_iv (RPCCLIENT)
865 const_iv (INIT_CDB)
866 const_iv (INIT_LOCK)
867 const_iv (INIT_LOG)
868 const_iv (INIT_MPOOL)
869 const_iv (INIT_REP)
870 const_iv (INIT_TXN)
871 const_iv (RECOVER)
872 const_iv (INIT_TXN)
873 const_iv (RECOVER_FATAL)
874 const_iv (CREATE)
875 const_iv (USE_ENVIRON)
876 const_iv (USE_ENVIRON_ROOT)
877 const_iv (LOCKDOWN)
878 const_iv (PRIVATE)
879 const_iv (REGISTER)
880 const_iv (SYSTEM_MEM)
881 const_iv (AUTO_COMMIT)
882 const_iv (CDB_ALLDB)
883 const_iv (DIRECT_DB)
884 const_iv (DIRECT_LOG)
885 const_iv (DSYNC_DB)
886 const_iv (DSYNC_LOG)
887 const_iv (LOG_AUTOREMOVE)
888 const_iv (LOG_INMEMORY)
889 const_iv (NOLOCKING)
890 const_iv (MULTIVERSION)
891 const_iv (NOMMAP)
892 const_iv (NOPANIC)
893 const_iv (OVERWRITE)
894 const_iv (PANIC_ENVIRONMENT)
895 const_iv (REGION_INIT)
896 const_iv (TIME_NOTGRANTED)
897 const_iv (TXN_NOSYNC)
898 const_iv (TXN_SNAPSHOT)
899 const_iv (TXN_WRITE_NOSYNC)
900 const_iv (WRITECURSOR)
901 const_iv (YIELDCPU)
902 const_iv (ENCRYPT_AES)
903 const_iv (XA_CREATE)
904 const_iv (BTREE)
905 const_iv (HASH)
906 const_iv (QUEUE)
907 const_iv (RECNO)
908 const_iv (UNKNOWN)
909 const_iv (EXCL)
910 const_iv (READ_COMMITTED)
911 const_iv (READ_UNCOMMITTED)
912 const_iv (TRUNCATE)
913 const_iv (NOSYNC)
914 const_iv (CHKSUM)
915 const_iv (ENCRYPT)
916 const_iv (TXN_NOT_DURABLE)
917 const_iv (DUP)
918 const_iv (DUPSORT)
919 const_iv (RECNUM)
920 const_iv (RENUMBER)
921 const_iv (REVSPLITOFF)
922 const_iv (INORDER)
923 const_iv (CONSUME)
924 const_iv (CONSUME_WAIT)
925 const_iv (GET_BOTH)
926 const_iv (GET_BOTH_RANGE)
927 //const_iv (SET_RECNO)
928 //const_iv (MULTIPLE)
929 const_iv (SNAPSHOT)
930 const_iv (JOIN_ITEM)
931 const_iv (RMW)
932
933 const_iv (NOTFOUND)
934 const_iv (KEYEMPTY)
935 const_iv (LOCK_DEADLOCK)
936 const_iv (LOCK_NOTGRANTED)
937 const_iv (RUNRECOVERY)
938 const_iv (OLD_VERSION)
939 const_iv (REP_HANDLE_DEAD)
940 const_iv (REP_LOCKOUT)
941 const_iv (SECONDARY_BAD)
942
943 const_iv (FREE_SPACE)
944 const_iv (FREELIST_ONLY)
945
946 const_iv (APPEND)
947 const_iv (NODUPDATA)
948 const_iv (NOOVERWRITE)
949
950 const_iv (TXN_NOWAIT)
951 const_iv (TXN_SNAPSHOT)
952 const_iv (TXN_SYNC)
953
954 const_iv (SET_LOCK_TIMEOUT)
955 const_iv (SET_TXN_TIMEOUT)
956
957 const_iv (JOIN_ITEM)
958 const_iv (FIRST)
959 const_iv (NEXT)
960 const_iv (NEXT_DUP)
961 const_iv (NEXT_NODUP)
962 const_iv (PREV)
963 const_iv (PREV_NODUP)
964 const_iv (SET)
965 const_iv (SET_RANGE)
966 const_iv (LAST)
967 const_iv (BEFORE)
968 const_iv (AFTER)
969 const_iv (CURRENT)
970 const_iv (KEYFIRST)
971 const_iv (KEYLAST)
972 const_iv (NODUPDATA)
973
974 const_iv (FORCE)
975
976 const_iv (LOCK_DEFAULT)
977 const_iv (LOCK_EXPIRE)
978 const_iv (LOCK_MAXLOCKS)
979 const_iv (LOCK_MAXWRITE)
980 const_iv (LOCK_MINLOCKS)
981 const_iv (LOCK_MINWRITE)
982 const_iv (LOCK_OLDEST)
983 const_iv (LOCK_RANDOM)
984 const_iv (LOCK_YOUNGEST)
985
986 const_iv (SEQ_DEC)
987 const_iv (SEQ_INC)
988 const_iv (SEQ_WRAP)
989 };
990
991 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
992 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
993
994 if (!create_pipe (respipe))
995 croak ("unable to initialize result pipe");
996
997 X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child);
998 #ifdef _WIN32
999 X_MUTEX_CHECK (wrklock);
1000 X_MUTEX_CHECK (reslock);
1001 X_MUTEX_CHECK (reqlock);
1002
1003 X_COND_CHECK (reqwait);
1004 #endif
1005 }
1006
1007 void
1008 max_poll_reqs (int nreqs)
1009 PROTOTYPE: $
1010 CODE:
1011 max_poll_reqs = nreqs;
1012
1013 void
1014 max_poll_time (double nseconds)
1015 PROTOTYPE: $
1016 CODE:
1017 max_poll_time = nseconds * AIO_TICKS;
1018
1019 void
1020 min_parallel (int nthreads)
1021 PROTOTYPE: $
1022
1023 void
1024 max_parallel (int nthreads)
1025 PROTOTYPE: $
1026
1027 void
1028 max_idle (int nthreads)
1029 PROTOTYPE: $
1030 CODE:
1031 set_max_idle (nthreads);
1032
1033 int
1034 max_outstanding (int maxreqs)
1035 PROTOTYPE: $
1036 CODE:
1037 RETVAL = max_outstanding;
1038 max_outstanding = maxreqs;
1039 OUTPUT:
1040 RETVAL
1041
1042 int
1043 dbreq_pri (int pri = 0)
1044 PROTOTYPE: ;$
1045 CODE:
1046 RETVAL = next_pri - PRI_BIAS;
1047 if (items > 0)
1048 {
1049 if (pri < PRI_MIN) pri = PRI_MIN;
1050 if (pri > PRI_MAX) pri = PRI_MAX;
1051 next_pri = pri + PRI_BIAS;
1052 }
1053 OUTPUT:
1054 RETVAL
1055
1056 void
1057 dbreq_nice (int nice = 0)
1058 CODE:
1059 nice = next_pri - nice;
1060 if (nice < PRI_MIN) nice = PRI_MIN;
1061 if (nice > PRI_MAX) nice = PRI_MAX;
1062 next_pri = nice + PRI_BIAS;
1063
1064 void
1065 flush ()
1066 PROTOTYPE:
1067 CODE:
1068 while (nreqs)
1069 {
1070 poll_wait ();
1071 poll_cb ();
1072 }
1073
1074 int
1075 poll ()
1076 PROTOTYPE:
1077 CODE:
1078 poll_wait ();
1079 RETVAL = poll_cb ();
1080 OUTPUT:
1081 RETVAL
1082
1083 int
1084 poll_fileno ()
1085 PROTOTYPE:
1086 CODE:
1087 RETVAL = respipe [0];
1088 OUTPUT:
1089 RETVAL
1090
1091 int
1092 poll_cb (...)
1093 PROTOTYPE:
1094 CODE:
1095 RETVAL = poll_cb ();
1096 OUTPUT:
1097 RETVAL
1098
1099 void
1100 poll_wait ()
1101 PROTOTYPE:
1102 CODE:
1103 poll_wait ();
1104
1105 int
1106 nreqs ()
1107 PROTOTYPE:
1108 CODE:
1109 RETVAL = nreqs;
1110 OUTPUT:
1111 RETVAL
1112
1113 int
1114 nready ()
1115 PROTOTYPE:
1116 CODE:
1117 RETVAL = get_nready ();
1118 OUTPUT:
1119 RETVAL
1120
1121 int
1122 npending ()
1123 PROTOTYPE:
1124 CODE:
1125 RETVAL = get_npending ();
1126 OUTPUT:
1127 RETVAL
1128
1129 int
1130 nthreads ()
1131 PROTOTYPE:
1132 CODE:
1133 if (WORDACCESS_UNSAFE) X_LOCK (wrklock);
1134 RETVAL = started;
1135 if (WORDACCESS_UNSAFE) X_UNLOCK (wrklock);
1136 OUTPUT:
1137 RETVAL
1138
1139 void
1140 set_sync_prepare (SV *cb)
1141 PROTOTYPE: &
1142 CODE:
1143 SvREFCNT_dec (prepare_cb);
1144 prepare_cb = newSVsv (cb);
1145
1146
1147 DB_ENV *
1148 db_env_create (U32 env_flags = 0)
1149 CODE:
1150 {
1151 errno = db_env_create (&RETVAL, env_flags);
1152 if (errno)
1153 croak ("db_env_create: %s", db_strerror (errno));
1154 }
1155 OUTPUT:
1156 RETVAL
1157
1158 void
1159 db_env_open (DB_ENV *env, octetstring db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
1160 CODE:
1161 {
1162 env->set_thread_count (env, get_nthreads ());
1163
1164 dREQ (REQ_ENV_OPEN);
1165 req->env = env;
1166 req->uint1 = open_flags | DB_THREAD;
1167 req->int1 = mode;
1168 req->buf1 = strdup_ornull (db_home);
1169 REQ_SEND;
1170 }
1171
1172 void
1173 db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef)
1174 CODE:
1175 {
1176 dREQ (REQ_ENV_CLOSE);
1177 req->env = env;
1178 req->uint1 = flags;
1179 REQ_SEND;
1180 ptr_nuke (ST (0));
1181 }
1182
1183 void
1184 db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1185 CODE:
1186 {
1187 dREQ (REQ_ENV_TXN_CHECKPOINT);
1188 req->env = env;
1189 req->uint1 = kbyte;
1190 req->int1 = min;
1191 req->uint2 = flags;
1192 REQ_SEND;
1193 }
1194
1195 void
1196 db_env_lock_detect (DB_ENV *env, U32 flags = 0, U32 atype = DB_LOCK_DEFAULT, SV *dummy = 0, SV *callback = &PL_sv_undef)
1197 CODE:
1198 {
1199 dREQ (REQ_ENV_LOCK_DETECT);
1200 req->env = env;
1201 req->uint1 = flags;
1202 req->uint2 = atype;
1203 REQ_SEND;
1204 }
1205
1206 void
1207 db_env_memp_sync (DB_ENV *env, SV *dummy = 0, SV *callback = &PL_sv_undef)
1208 CODE:
1209 {
1210 dREQ (REQ_ENV_MEMP_SYNC);
1211 req->env = env;
1212 REQ_SEND;
1213 }
1214
1215 void
1216 db_env_memp_trickle (DB_ENV *env, int percent, SV *dummy = 0, SV *callback = &PL_sv_undef)
1217 CODE:
1218 {
1219 dREQ (REQ_ENV_MEMP_TRICKLE);
1220 req->env = env;
1221 req->int1 = percent;
1222 REQ_SEND;
1223 }
1224
1225
1226 DB *
1227 db_create (DB_ENV *env = 0, U32 flags = 0)
1228 CODE:
1229 {
1230 errno = db_create (&RETVAL, env, flags);
1231 if (errno)
1232 croak ("db_create: %s", db_strerror (errno));
1233
1234 if (RETVAL)
1235 RETVAL->app_private = (void *)newSVsv (ST (0));
1236 }
1237 OUTPUT:
1238 RETVAL
1239
1240 void
1241 db_open (DB *db, DB_TXN_ornull *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
1242 CODE:
1243 {
1244 dREQ (REQ_DB_OPEN);
1245 req->db = db;
1246 req->txn = txnid;
1247 req->buf1 = strdup_ornull (file);
1248 req->buf2 = strdup_ornull (database);
1249 req->int1 = type;
1250 req->uint1 = flags | DB_THREAD;
1251 req->int2 = mode;
1252 REQ_SEND;
1253 }
1254
1255 void
1256 db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1257 CODE:
1258 {
1259 dREQ (REQ_DB_CLOSE);
1260 req->db = db;
1261 req->uint1 = flags;
1262 req->sv1 = (SV *)db->app_private;
1263 REQ_SEND;
1264 ptr_nuke (ST (0));
1265 }
1266
1267 void
1268 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)
1269 CODE:
1270 {
1271 dREQ (REQ_DB_COMPACT);
1272 req->db = db;
1273 req->txn = txn;
1274 sv_to_dbt (&req->dbt1, start);
1275 sv_to_dbt (&req->dbt2, stop);
1276 req->uint1 = flags;
1277 REQ_SEND;
1278 }
1279
1280 void
1281 db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1282 CODE:
1283 {
1284 dREQ (REQ_DB_SYNC);
1285 req->db = db;
1286 req->uint1 = flags;
1287 REQ_SEND;
1288 }
1289
1290 void
1291 db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = &PL_sv_undef)
1292 CODE:
1293 {
1294 dREQ (REQ_DB_KEY_RANGE);
1295 req->db = db;
1296 req->txn = txn;
1297 sv_to_dbt (&req->dbt1, key);
1298 req->uint1 = flags;
1299 req->sv1 = SvREFCNT_inc (key_range); SvREADONLY_on (key_range);
1300 REQ_SEND;
1301 }
1302
1303 void
1304 db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1305 CODE:
1306 {
1307 dREQ (REQ_DB_PUT);
1308 req->db = db;
1309 req->txn = txn;
1310 sv_to_dbt (&req->dbt1, key);
1311 sv_to_dbt (&req->dbt2, data);
1312 req->uint1 = flags;
1313 REQ_SEND;
1314 }
1315
1316 void
1317 db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1318 CODE:
1319 {
1320 dREQ (REQ_DB_GET);
1321 req->db = db;
1322 req->txn = txn;
1323 req->uint1 = flags;
1324 sv_to_dbt (&req->dbt1, key);
1325 req->dbt3.flags = DB_DBT_MALLOC;
1326 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1327 REQ_SEND;
1328 }
1329
1330 void
1331 db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1332 CODE:
1333 {
1334 dREQ (REQ_DB_PGET);
1335 req->db = db;
1336 req->txn = txn;
1337 req->uint1 = flags;
1338 sv_to_dbt (&req->dbt1, key);
1339 sv_to_dbt (&req->dbt2, pkey);
1340 req->dbt3.flags = DB_DBT_MALLOC;
1341 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1342 REQ_SEND;
1343 }
1344
1345 void
1346 db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1347 CODE:
1348 {
1349 dREQ (REQ_DB_DEL);
1350 req->db = db;
1351 req->txn = txn;
1352 req->uint1 = flags;
1353 sv_to_dbt (&req->dbt1, key);
1354 REQ_SEND;
1355 }
1356
1357 void
1358 db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef)
1359 CODE:
1360 {
1361 dREQ (REQ_TXN_COMMIT);
1362 req->txn = txn;
1363 req->uint1 = flags;
1364 REQ_SEND;
1365 ptr_nuke (ST (0));
1366 }
1367
1368 void
1369 db_txn_abort (DB_TXN *txn, SV *callback = &PL_sv_undef)
1370 CODE:
1371 {
1372 dREQ (REQ_TXN_ABORT);
1373 req->txn = txn;
1374 REQ_SEND;
1375 ptr_nuke (ST (0));
1376 }
1377
1378 void
1379 db_c_close (DBC *dbc, SV *callback = &PL_sv_undef)
1380 CODE:
1381 {
1382 dREQ (REQ_C_CLOSE);
1383 req->dbc = dbc;
1384 REQ_SEND;
1385 ptr_nuke (ST (0));
1386 }
1387
1388 void
1389 db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = &PL_sv_undef)
1390 CODE:
1391 {
1392 dREQ (REQ_C_COUNT);
1393 req->dbc = dbc;
1394 req->sv1 = SvREFCNT_inc (count);
1395 REQ_SEND;
1396 }
1397
1398 void
1399 db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1400 CODE:
1401 {
1402 dREQ (REQ_C_PUT);
1403 req->dbc = dbc;
1404 sv_to_dbt (&req->dbt1, key);
1405 sv_to_dbt (&req->dbt2, data);
1406 req->uint1 = flags;
1407 REQ_SEND;
1408 }
1409
1410 void
1411 db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1412 CODE:
1413 {
1414 dREQ (REQ_C_GET);
1415 req->dbc = dbc;
1416 req->uint1 = flags;
1417 if ((flags & DB_SET) == DB_SET
1418 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1419 sv_to_dbt (&req->dbt1, key);
1420 else
1421 req->dbt1.flags = DB_DBT_MALLOC;
1422
1423 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1424
1425 if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1426 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1427 sv_to_dbt (&req->dbt3, data);
1428 else
1429 req->dbt3.flags = DB_DBT_MALLOC;
1430
1431 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1432 REQ_SEND;
1433 }
1434
1435 void
1436 db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1437 CODE:
1438 {
1439 dREQ (REQ_C_PGET);
1440 req->dbc = dbc;
1441 req->uint1 = flags;
1442 if ((flags & DB_SET) == DB_SET
1443 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1444 sv_to_dbt (&req->dbt1, key);
1445 else
1446 req->dbt1.flags = DB_DBT_MALLOC;
1447
1448 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1449
1450 req->dbt2.flags = DB_DBT_MALLOC;
1451 req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey);
1452
1453 if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1454 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1455 sv_to_dbt (&req->dbt3, data);
1456 else
1457 req->dbt3.flags = DB_DBT_MALLOC;
1458
1459 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1460 REQ_SEND;
1461 }
1462
1463 void
1464 db_c_del (DBC *dbc, U32 flags = 0, SV *callback = &PL_sv_undef)
1465 CODE:
1466 {
1467 dREQ (REQ_C_DEL);
1468 req->dbc = dbc;
1469 req->uint1 = flags;
1470 REQ_SEND;
1471 }
1472
1473
1474 void
1475 db_sequence_open (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1476 CODE:
1477 {
1478 dREQ (REQ_SEQ_OPEN);
1479 req->seq = seq;
1480 req->txn = txnid;
1481 req->uint1 = flags | DB_THREAD;
1482 sv_to_dbt (&req->dbt1, key);
1483 REQ_SEND;
1484 }
1485
1486 void
1487 db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = &PL_sv_undef)
1488 CODE:
1489 {
1490 dREQ (REQ_SEQ_CLOSE);
1491 req->seq = seq;
1492 req->uint1 = flags;
1493 REQ_SEND;
1494 ptr_nuke (ST (0));
1495 }
1496
1497 void
1498 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)
1499 CODE:
1500 {
1501 dREQ (REQ_SEQ_GET);
1502 req->seq = seq;
1503 req->txn = txnid;
1504 req->int1 = delta;
1505 req->uint1 = flags;
1506 req->sv1 = SvREFCNT_inc (seq_value); SvREADONLY_on (seq_value);
1507 REQ_SEND;
1508 }
1509
1510 void
1511 db_sequence_remove (DB_SEQUENCE *seq, DB_TXN_ornull *txnid = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1512 CODE:
1513 {
1514 dREQ (REQ_SEQ_REMOVE);
1515 req->seq = seq;
1516 req->txn = txnid;
1517 req->uint1 = flags;
1518 REQ_SEND;
1519 }
1520
1521
1522 MODULE = BDB PACKAGE = BDB::Env
1523
1524 void
1525 DESTROY (DB_ENV_ornull *env)
1526 CODE:
1527 if (env)
1528 env->close (env, 0);
1529
1530 int set_data_dir (DB_ENV *env, const char *dir)
1531 CODE:
1532 RETVAL = env->set_data_dir (env, dir);
1533 OUTPUT:
1534 RETVAL
1535
1536 int set_tmp_dir (DB_ENV *env, const char *dir)
1537 CODE:
1538 RETVAL = env->set_tmp_dir (env, dir);
1539 OUTPUT:
1540 RETVAL
1541
1542 int set_lg_dir (DB_ENV *env, const char *dir)
1543 CODE:
1544 RETVAL = env->set_lg_dir (env, dir);
1545 OUTPUT:
1546 RETVAL
1547
1548 int set_shm_key (DB_ENV *env, long shm_key)
1549 CODE:
1550 RETVAL = env->set_shm_key (env, shm_key);
1551 OUTPUT:
1552 RETVAL
1553
1554 int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0)
1555 CODE:
1556 RETVAL = env->set_cachesize (env, gbytes, bytes, ncache);
1557 OUTPUT:
1558 RETVAL
1559
1560 int set_flags (DB_ENV *env, U32 flags, int onoff)
1561 CODE:
1562 RETVAL = env->set_flags (env, flags, onoff);
1563 OUTPUT:
1564 RETVAL
1565
1566 int set_encrypt (DB_ENV *env, const char *password, U32 flags = 0)
1567 CODE:
1568 RETVAL = env->set_encrypt (env, password, flags);
1569 OUTPUT:
1570 RETVAL
1571
1572 int set_timeout (DB_ENV *env, NV timeout, U32 flags)
1573 CODE:
1574 RETVAL = env->set_timeout (env, timeout * 1000000, flags);
1575 OUTPUT:
1576 RETVAL
1577
1578 int set_mp_max_openfd (DB_ENV *env, int maxopenfd);
1579 CODE:
1580 RETVAL = env->set_mp_max_openfd (env, maxopenfd);
1581 OUTPUT:
1582 RETVAL
1583
1584 int set_mp_max_write (DB_ENV *env, int maxwrite, int maxwrite_sleep);
1585 CODE:
1586 RETVAL = env->set_mp_max_write (env, maxwrite, maxwrite_sleep);
1587 OUTPUT:
1588 RETVAL
1589
1590 int set_mp_mmapsize (DB_ENV *env, int mmapsize_mb)
1591 CODE:
1592 RETVAL = env->set_mp_mmapsize (env, ((size_t)mmapsize_mb) << 20);
1593 OUTPUT:
1594 RETVAL
1595
1596 int set_lk_detect (DB_ENV *env, U32 detect = DB_LOCK_DEFAULT)
1597 CODE:
1598 RETVAL = env->set_lk_detect (env, detect);
1599 OUTPUT:
1600 RETVAL
1601
1602 int set_lk_max_lockers (DB_ENV *env, U32 max)
1603 CODE:
1604 RETVAL = env->set_lk_max_lockers (env, max);
1605 OUTPUT:
1606 RETVAL
1607
1608 int set_lk_max_locks (DB_ENV *env, U32 max)
1609 CODE:
1610 RETVAL = env->set_lk_max_locks (env, max);
1611 OUTPUT:
1612 RETVAL
1613
1614 int set_lk_max_objects (DB_ENV *env, U32 max)
1615 CODE:
1616 RETVAL = env->set_lk_max_objects (env, max);
1617 OUTPUT:
1618 RETVAL
1619
1620 int set_lg_bsize (DB_ENV *env, U32 max)
1621 CODE:
1622 RETVAL = env->set_lg_bsize (env, max);
1623 OUTPUT:
1624 RETVAL
1625
1626 int set_lg_max (DB_ENV *env, U32 max)
1627 CODE:
1628 RETVAL = env->set_lg_max (env, max);
1629 OUTPUT:
1630 RETVAL
1631
1632 DB_TXN *
1633 txn_begin (DB_ENV *env, DB_TXN_ornull *parent = 0, U32 flags = 0)
1634 CODE:
1635 errno = env->txn_begin (env, parent, &RETVAL, flags);
1636 if (errno)
1637 croak ("DB_ENV->txn_begin: %s", db_strerror (errno));
1638 OUTPUT:
1639 RETVAL
1640
1641 MODULE = BDB PACKAGE = BDB::Db
1642
1643 void
1644 DESTROY (DB_ornull *db)
1645 CODE:
1646 if (db)
1647 {
1648 SV *env = (SV *)db->app_private;
1649 db->close (db, 0);
1650 SvREFCNT_dec (env);
1651 }
1652
1653 int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0)
1654 CODE:
1655 RETVAL = db->set_cachesize (db, gbytes, bytes, ncache);
1656 OUTPUT:
1657 RETVAL
1658
1659 int set_flags (DB *db, U32 flags);
1660 CODE:
1661 RETVAL = db->set_flags (db, flags);
1662 OUTPUT:
1663 RETVAL
1664
1665 int set_encrypt (DB *db, const char *password, U32 flags)
1666 CODE:
1667 RETVAL = db->set_encrypt (db, password, flags);
1668 OUTPUT:
1669 RETVAL
1670
1671 int set_lorder (DB *db, int lorder)
1672 CODE:
1673 RETVAL = db->set_lorder (db, lorder);
1674 OUTPUT:
1675 RETVAL
1676
1677 int set_bt_minkey (DB *db, U32 minkey)
1678 CODE:
1679 RETVAL = db->set_bt_minkey (db, minkey);
1680 OUTPUT:
1681 RETVAL
1682
1683 int set_re_delim(DB *db, int delim);
1684 CODE:
1685 RETVAL = db->set_re_delim (db, delim);
1686 OUTPUT:
1687 RETVAL
1688
1689 int set_re_pad (DB *db, int re_pad)
1690 CODE:
1691 RETVAL = db->set_re_pad (db, re_pad);
1692 OUTPUT:
1693 RETVAL
1694
1695 int set_re_source (DB *db, char *source)
1696 CODE:
1697 RETVAL = db->set_re_source (db, source);
1698 OUTPUT:
1699 RETVAL
1700
1701 int set_re_len (DB *db, U32 re_len)
1702 CODE:
1703 RETVAL = db->set_re_len (db, re_len);
1704 OUTPUT:
1705 RETVAL
1706
1707 int set_h_ffactor (DB *db, U32 h_ffactor)
1708 CODE:
1709 RETVAL = db->set_h_ffactor (db, h_ffactor);
1710 OUTPUT:
1711 RETVAL
1712
1713 int set_h_nelem (DB *db, U32 h_nelem)
1714 CODE:
1715 RETVAL = db->set_h_nelem (db, h_nelem);
1716 OUTPUT:
1717 RETVAL
1718
1719 int set_q_extentsize (DB *db, U32 extentsize)
1720 CODE:
1721 RETVAL = db->set_q_extentsize (db, extentsize);
1722 OUTPUT:
1723 RETVAL
1724
1725 DBC *
1726 cursor (DB *db, DB_TXN_ornull *txn = 0, U32 flags = 0)
1727 CODE:
1728 errno = db->cursor (db, txn, &RETVAL, flags);
1729 if (errno)
1730 croak ("DB->cursor: %s", db_strerror (errno));
1731 OUTPUT:
1732 RETVAL
1733
1734 DB_SEQUENCE *
1735 sequence (DB *db, U32 flags = 0)
1736 CODE:
1737 {
1738 errno = db_sequence_create (&RETVAL, db, flags);
1739 if (errno)
1740 croak ("db_sequence_create: %s", db_strerror (errno));
1741 }
1742 OUTPUT:
1743 RETVAL
1744
1745
1746 MODULE = BDB PACKAGE = BDB::Txn
1747
1748 void
1749 DESTROY (DB_TXN_ornull *txn)
1750 CODE:
1751 if (txn)
1752 txn->abort (txn);
1753
1754 int set_timeout (DB_TXN *txn, NV timeout, U32 flags)
1755 CODE:
1756 RETVAL = txn->set_timeout (txn, timeout * 1000000, flags);
1757 OUTPUT:
1758 RETVAL
1759
1760
1761 MODULE = BDB PACKAGE = BDB::Cursor
1762
1763 void
1764 DESTROY (DBC_ornull *dbc)
1765 CODE:
1766 if (dbc)
1767 dbc->c_close (dbc);
1768
1769 MODULE = BDB PACKAGE = BDB::Sequence
1770
1771 void
1772 DESTROY (DB_SEQUENCE_ornull *seq)
1773 CODE:
1774 if (seq)
1775 seq->close (seq, 0);
1776
1777 int initial_value (DB_SEQUENCE *seq, db_seq_t value)
1778 CODE:
1779 RETVAL = seq->initial_value (seq, value);
1780 OUTPUT:
1781 RETVAL
1782
1783 int set_cachesize (DB_SEQUENCE *seq, U32 size)
1784 CODE:
1785 RETVAL = seq->set_cachesize (seq, size);
1786 OUTPUT:
1787 RETVAL
1788
1789 int set_flags (DB_SEQUENCE *seq, U32 flags)
1790 CODE:
1791 RETVAL = seq->set_flags (seq, flags);
1792 OUTPUT:
1793 RETVAL
1794
1795 int set_range (DB_SEQUENCE *seq, db_seq_t min, db_seq_t max)
1796 CODE:
1797 RETVAL = seq->set_range (seq, min, max);
1798 OUTPUT:
1799 RETVAL
1800