ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/BDB/BDB.xs
(Generate patch)

Comparing BDB/BDB.xs (file contents):
Revision 1.2 by root, Mon Feb 5 20:21:38 2007 UTC vs.
Revision 1.4 by root, Mon Feb 5 22:31:05 2007 UTC

41# define WORDACCESS_UNSAFE 1 41# define WORDACCESS_UNSAFE 1
42# endif 42# endif
43#endif 43#endif
44 44
45typedef SV SV8; /* byte-sv, used for argument-checking */ 45typedef SV SV8; /* byte-sv, used for argument-checking */
46typedef char *octetstring;
46 47
48static SV *prepare_cb;
49
50static inline char *
51strdup_ornull (const char *s)
52{
53 return s ? strdup (s) : 0;
54}
55
47enum 56enum {
48{
49 REQ_QUIT, 57 REQ_QUIT,
50 REQ_ENV_OPEN, REQ_ENV_CLOSE, 58 REQ_ENV_OPEN, REQ_ENV_CLOSE,
51 REQ_DB_OPEN, REQ_DB_CLOSE, 59 REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT,
52}; 60};
53 61
54typedef struct aio_cb 62typedef struct aio_cb
55{ 63{
56 struct aio_cb *volatile next; 64 struct aio_cb *volatile next;
57 SV *callback; 65 SV *callback;
58 int type, pri, errorno; 66 int type, pri, result;
59 67
60 DB_ENV *env; 68 DB_ENV *env;
61 DB *db; 69 DB *db;
62 DB_TXN *txn; 70 DB_TXN *txn;
63 DBC *cursor; 71 DBC *cursor;
64 int int1, int2; 72 int int1, int2;
65 U32 uint1, uint2; 73 U32 uint1, uint2;
66 char *buf1, *buf2; 74 char *buf1, *buf2;
75
76 DBT dbt1, dbt2, dbt3;
67} aio_cb; 77} aio_cb;
68 78
69typedef aio_cb *aio_req; 79typedef aio_cb *aio_req;
70 80
71enum { 81enum {
254 264
255 switch (req->type) 265 switch (req->type)
256 { 266 {
257 } 267 }
258 268
269 errno = req->result;
270
259 PUTBACK; 271 PUTBACK;
260 call_sv (req->callback, G_VOID | G_EVAL); 272 call_sv (req->callback, G_VOID | G_EVAL);
261 SPAGAIN; 273 SPAGAIN;
262 274
263 FREETMPS; 275 FREETMPS;
272 free (req->buf1); 284 free (req->buf1);
273 free (req->buf2); 285 free (req->buf2);
274 Safefree (req); 286 Safefree (req);
275} 287}
276 288
277static void *aio_proc(void *arg); 289static void *aio_proc (void *arg);
278 290
279static void start_thread (void) 291static void start_thread (void)
280{ 292{
281 sigset_t fullsigset, oldsigset; 293 sigset_t fullsigset, oldsigset;
282 pthread_attr_t attr; 294 pthread_attr_t attr;
324 start_thread (); 336 start_thread ();
325} 337}
326 338
327static void req_send (aio_req req) 339static void req_send (aio_req req)
328{ 340{
341 SV *wait_callback = 0;
342
343 // synthesize callback if none given
344 if (!SvOK (req->callback))
345 {
346 dSP;
347 PUSHMARK (SP);
348 PUTBACK;
349 int count = call_sv (prepare_cb, G_ARRAY);
350 SPAGAIN;
351
352 if (count != 2)
353 croak ("prepare callback must return exactly two values\n");
354
355 wait_callback = SvREFCNT_inc (POPs);
356 SvREFCNT_dec (req->callback);
357 req->callback = SvREFCNT_inc (POPs);
358 }
359
329 ++nreqs; 360 ++nreqs;
330 361
331 LOCK (reqlock); 362 LOCK (reqlock);
332 ++nready; 363 ++nready;
333 reqq_push (&req_queue, req); 364 reqq_push (&req_queue, req);
334 pthread_cond_signal (&reqwait); 365 pthread_cond_signal (&reqwait);
335 UNLOCK (reqlock); 366 UNLOCK (reqlock);
336 367
337 maybe_start_thread (); 368 maybe_start_thread ();
369
370 if (wait_callback)
371 {
372 dSP;
373 PUSHMARK (SP);
374 PUTBACK;
375 call_sv (wait_callback, G_DISCARD);
376 SvREFCNT_dec (wait_callback);
377 }
338} 378}
339 379
340static void end_thread (void) 380static void end_thread (void)
341{ 381{
342 aio_req req; 382 aio_req req;
537 577
538 --nready; 578 --nready;
539 579
540 UNLOCK (reqlock); 580 UNLOCK (reqlock);
541 581
542 errno = 0; /* strictly unnecessary */
543
544 switch (req->type) 582 switch (req->type)
545 { 583 {
546 case REQ_QUIT: 584 case REQ_QUIT:
547 goto quit; 585 goto quit;
548 586
587 case REQ_ENV_OPEN:
588 req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1);
589 break;
590
591 case REQ_ENV_CLOSE:
592 req->result = req->env->close (req->env, req->uint1);
593 break;
594
595 case REQ_DB_OPEN:
596 req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2);
597 break;
598
599 case REQ_DB_CLOSE:
600 req->result = req->db->close (req->db, req->uint1);
601 break;
602
603 case REQ_DB_COMPACT:
604 req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0);
605 break;
606
607 case REQ_DB_SYNC:
608 req->result = req->db->sync (req->db, req->uint1);
609 break;
610
611 case REQ_DB_PUT:
612 req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1);
613 break;
614
549 default: 615 default:
550 //req->result = ENOSYS; 616 req->result = ENOSYS;
551 break; 617 break;
552 } 618 }
553
554 //req->errorno = errno;
555 619
556 LOCK (reslock); 620 LOCK (reslock);
557 621
558 ++npending; 622 ++npending;
559 623
651 { \ 715 { \
652 IV tmp = SvIV ((SV*) SvRV (arg)); \ 716 IV tmp = SvIV ((SV*) SvRV (arg)); \
653 (var) = INT2PTR (type, tmp); \ 717 (var) = INT2PTR (type, tmp); \
654 } \ 718 } \
655 else \ 719 else \
656 Perl_croak (# var " is not of type " # type) 720 Perl_croak (# var " is not of type " # class)
721
722inline void
723set_dbt (DBT *dbt, SV *sv)
724{
725 STRLEN len;
726 char *data = SvPVbyte (sv, len);
727
728 dbt->data = malloc (len);
729 memcpy (dbt->data, data, len);
730 dbt->size = len;
731}
657 732
658MODULE = BDB PACKAGE = BDB 733MODULE = BDB PACKAGE = BDB
659 734
660PROTOTYPES: ENABLE 735PROTOTYPES: ENABLE
661 736
711 const_iv (HASH) 786 const_iv (HASH)
712 const_iv (QUEUE) 787 const_iv (QUEUE)
713 const_iv (RECNO) 788 const_iv (RECNO)
714 const_iv (UNKNOWN) 789 const_iv (UNKNOWN)
715 const_iv (EXCL) 790 const_iv (EXCL)
791 const_iv (READ_COMMITTED)
716 const_iv (READ_UNCOMMITTED) 792 const_iv (READ_UNCOMMITTED)
717 const_iv (TRUNCATE) 793 const_iv (TRUNCATE)
718 const_iv (NOSYNC) 794 const_iv (NOSYNC)
719 const_iv (CHKSUM) 795 const_iv (CHKSUM)
720 const_iv (ENCRYPT) 796 const_iv (ENCRYPT)
734 const_iv (NOTFOUND) 810 const_iv (NOTFOUND)
735 const_iv (KEYEMPTY) 811 const_iv (KEYEMPTY)
736 const_iv (LOCK_DEADLOCK) 812 const_iv (LOCK_DEADLOCK)
737 const_iv (LOCK_NOTGRANTED) 813 const_iv (LOCK_NOTGRANTED)
738 const_iv (RUNRECOVERY) 814 const_iv (RUNRECOVERY)
815 const_iv (OLD_VERSION)
816 const_iv (REP_HANDLE_DEAD)
817 const_iv (REP_LOCKOUT)
818
819 const_iv (FREE_SPACE)
820 const_iv (FREELIST_ONLY)
821
822 const_iv (APPEND)
823 const_iv (NODUPDATA)
824 const_iv (NOOVERWRITE)
825
826 const_iv (TXN_NOWAIT)
827 const_iv (TXN_SNAPSHOT)
828 const_iv (TXN_SYNC)
829
830 const_iv (SET_LOCK_TIMEOUT)
831 const_iv (SET_TXN_TIMEOUT)
739 }; 832 };
740 833
741 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 834 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
742 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 835 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
743 836
779 max_outstanding = maxreqs; 872 max_outstanding = maxreqs;
780 OUTPUT: 873 OUTPUT:
781 RETVAL 874 RETVAL
782 875
783int 876int
784bdbreq_pri (int pri = 0) 877dbreq_pri (int pri = 0)
785 PROTOTYPE: ;$ 878 PROTOTYPE: ;$
786 CODE: 879 CODE:
787 RETVAL = next_pri - PRI_BIAS; 880 RETVAL = next_pri - PRI_BIAS;
788 if (items > 0) 881 if (items > 0)
789 { 882 {
793 } 886 }
794 OUTPUT: 887 OUTPUT:
795 RETVAL 888 RETVAL
796 889
797void 890void
798bdbreq_nice (int nice = 0) 891dbreq_nice (int nice = 0)
799 CODE: 892 CODE:
800 nice = next_pri - nice; 893 nice = next_pri - nice;
801 if (nice < PRI_MIN) nice = PRI_MIN; 894 if (nice < PRI_MIN) nice = PRI_MIN;
802 if (nice > PRI_MAX) nice = PRI_MAX; 895 if (nice > PRI_MAX) nice = PRI_MAX;
803 next_pri = nice + PRI_BIAS; 896 next_pri = nice + PRI_BIAS;
811 poll_wait (); 904 poll_wait ();
812 poll_cb (); 905 poll_cb ();
813 } 906 }
814 907
815int 908int
816poll() 909poll ()
817 PROTOTYPE: 910 PROTOTYPE:
818 CODE: 911 CODE:
819 poll_wait (); 912 poll_wait ();
820 RETVAL = poll_cb (); 913 RETVAL = poll_cb ();
821 OUTPUT: 914 OUTPUT:
822 RETVAL 915 RETVAL
823 916
824int 917int
825poll_fileno() 918poll_fileno ()
826 PROTOTYPE: 919 PROTOTYPE:
827 CODE: 920 CODE:
828 RETVAL = respipe [0]; 921 RETVAL = respipe [0];
829 OUTPUT: 922 OUTPUT:
830 RETVAL 923 RETVAL
831 924
832int 925int
833poll_cb(...) 926poll_cb (...)
834 PROTOTYPE: 927 PROTOTYPE:
835 CODE: 928 CODE:
836 RETVAL = poll_cb (); 929 RETVAL = poll_cb ();
837 OUTPUT: 930 OUTPUT:
838 RETVAL 931 RETVAL
839 932
840void 933void
841poll_wait() 934poll_wait ()
842 PROTOTYPE: 935 PROTOTYPE:
843 CODE: 936 CODE:
844 poll_wait (); 937 poll_wait ();
845 938
846int 939int
847nreqs() 940nreqs ()
848 PROTOTYPE: 941 PROTOTYPE:
849 CODE: 942 CODE:
850 RETVAL = nreqs; 943 RETVAL = nreqs;
851 OUTPUT: 944 OUTPUT:
852 RETVAL 945 RETVAL
853 946
854int 947int
855nready() 948nready ()
856 PROTOTYPE: 949 PROTOTYPE:
857 CODE: 950 CODE:
858 RETVAL = get_nready (); 951 RETVAL = get_nready ();
859 OUTPUT: 952 OUTPUT:
860 RETVAL 953 RETVAL
861 954
862int 955int
863npending() 956npending ()
864 PROTOTYPE: 957 PROTOTYPE:
865 CODE: 958 CODE:
866 RETVAL = get_npending (); 959 RETVAL = get_npending ();
867 OUTPUT: 960 OUTPUT:
868 RETVAL 961 RETVAL
869 962
870int 963int
871nthreads() 964nthreads ()
872 PROTOTYPE: 965 PROTOTYPE:
873 CODE: 966 CODE:
874 if (WORDACCESS_UNSAFE) LOCK (wrklock); 967 if (WORDACCESS_UNSAFE) LOCK (wrklock);
875 RETVAL = started; 968 RETVAL = started;
876 if (WORDACCESS_UNSAFE) UNLOCK (wrklock); 969 if (WORDACCESS_UNSAFE) UNLOCK (wrklock);
877 OUTPUT: 970 OUTPUT:
878 RETVAL 971 RETVAL
879 972
973void
974set_sync_prepare (SV *cb)
975 PROTOTYPE: &
976 CODE:
977 SvREFCNT_dec (prepare_cb);
978 prepare_cb = newSVsv (cb);
979
880DB_ENV * 980DB_ENV *
881bdb_env_create (U32 env_flags = 0) 981db_env_create (U32 env_flags = 0)
882 CODE: 982 CODE:
883{ 983{
884 int err = db_env_create (&RETVAL, env_flags); 984 errno = db_env_create (&RETVAL, env_flags);
885 if (err) 985 if (errno)
886 croak ("db_env_create: %s", db_strerror (err)); 986 croak ("db_env_create: %s", db_strerror (errno));
887} 987}
988 OUTPUT:
989 RETVAL
888 990
889void 991void
890bdb_env_open (DB_ENV *env, char *db_home, U32 open_flags, int mode, SV *callback = 0) 992db_env_open (DB_ENV *env, octetstring db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
891 CODE: 993 CODE:
892{ 994{
893 dREQ (REQ_ENV_OPEN); 995 dREQ (REQ_ENV_OPEN);
894 req->env = env; 996 req->env = env;
895 req->uint1 = open_flags; 997 req->uint1 = open_flags | DB_THREAD;
896 req->int1 = mode; 998 req->int1 = mode;
897 req->buf1 = strdup (db_home); 999 req->buf1 = strdup_ornull (db_home);
898 REQ_SEND; 1000 REQ_SEND;
899} 1001}
900 1002
901void 1003void
902bdb_env_close (DB_ENV *env, U32 flags = 0, SV *callback = 0) 1004db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef)
903 CODE: 1005 CODE:
904{ 1006{
905 dREQ (REQ_ENV_CLOSE); 1007 dREQ (REQ_ENV_CLOSE);
906 req->env = env; 1008 req->env = env;
907 req->uint1 = flags; 1009 req->uint1 = flags;
908 REQ_SEND; 1010 REQ_SEND;
909} 1011}
910 1012
911DB * 1013DB *
912bdb_db_create (DB_ENV *env = 0, U32 flags = 0) 1014db_create (DB_ENV *env = 0, U32 flags = 0)
913 CODE: 1015 CODE:
914{ 1016{
915 int err = db_create (&RETVAL, env, flags); 1017 errno = db_create (&RETVAL, env, flags);
916 if (err) 1018 if (errno)
917 croak ("db_env_create: %s", db_strerror (err)); 1019 croak ("db_env_create: %s", db_strerror (errno));
918} 1020}
1021 OUTPUT:
1022 RETVAL
919 1023
920void 1024void
921bdb_db_open (DB *db, DB_TXN *txnid, const char *file, const char *database, int type, U32 flags, int mode, SV *callback = 0) 1025db_open (DB *db, DB_TXN *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
922 CODE: 1026 CODE:
923{ 1027{
924 dREQ (REQ_DB_OPEN); 1028 dREQ (REQ_DB_OPEN);
925 req->db = db; 1029 req->db = db;
926 req->txn = txnid; 1030 req->txn = txnid;
927 req->buf1 = strdup (file); 1031 req->buf1 = strdup_ornull (file);
928 req->buf2 = strdup (database); 1032 req->buf2 = strdup_ornull (database);
929 req->int1 = type; 1033 req->int1 = type;
930 req->uint1 = flags; 1034 req->uint1 = flags | DB_THREAD;
931 req->int2 = mode; 1035 req->int2 = mode;
932 REQ_SEND; 1036 REQ_SEND;
933} 1037}
934 1038
935void 1039void
936bdb_db_close (DB *db, U32 flags = 0, SV *callback = 0) 1040db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
937 CODE: 1041 CODE:
938{ 1042{
939 dREQ (REQ_DB_CLOSE); 1043 dREQ (REQ_DB_CLOSE);
940 req->db = db; 1044 req->db = db;
941 req->uint1 = flags; 1045 req->uint1 = flags;
942 REQ_SEND; 1046 REQ_SEND;
943} 1047}
944 1048
1049void
1050db_compact (DB *db, DB_TXN *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef)
1051 CODE:
1052{
1053 dREQ (REQ_DB_COMPACT);
1054 req->db = db;
1055 req->txn = txn;
1056 set_dbt (&req->dbt1, start);
1057 set_dbt (&req->dbt2, stop);
1058 req->uint1 = flags;
1059 REQ_SEND;
1060}
1061
1062void
1063db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1064 CODE:
1065{
1066 dREQ (REQ_DB_SYNC);
1067 req->db = db;
1068 req->uint1 = flags;
1069 REQ_SEND;
1070}
1071
1072void
1073db_put (DB *db, DB_TXN *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1074 CODE:
1075{
1076 dREQ (REQ_DB_PUT);
1077 req->db = db;
1078 req->txn = 0;
1079 set_dbt (&req->dbt1, key);
1080 set_dbt (&req->dbt2, data);
1081 req->uint1 = flags;
1082 REQ_SEND;
1083}
1084
945 1085
946MODULE = BDB PACKAGE = BDB::Env 1086MODULE = BDB PACKAGE = BDB::Env
947 1087
948int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0) 1088int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0)
1089 CODE:
1090 RETVAL = env->set_cachesize (env, gbytes, bytes, ncache);
1091 OUTPUT:
1092 RETVAL
949 1093
950int set_flags (DB_ENV *env, U32 flags, int onoff) 1094int set_flags (DB_ENV *env, U32 flags, int onoff)
1095 CODE:
1096 RETVAL = env->set_flags (env, flags, onoff);
1097 OUTPUT:
1098 RETVAL
951 1099
952int set_encrypt (DB_ENV *env, const char *password, U32 flags) 1100int set_encrypt (DB_ENV *env, const char *password, U32 flags = 0)
1101 CODE:
1102 RETVAL = env->set_encrypt (env, password, flags);
1103 OUTPUT:
1104 RETVAL
1105
1106int set_timeout (DB_ENV *env, NV timeout, U32 flags)
1107 CODE:
1108 RETVAL = env->set_timeout (env, timeout * 1000000, flags);
1109 OUTPUT:
1110 RETVAL
1111
953 1112
954MODULE = BDB PACKAGE = BDB::Db 1113MODULE = BDB PACKAGE = BDB::Db
955 1114
956int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0) 1115int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0)
1116 CODE:
1117 RETVAL = db->set_cachesize (db, gbytes, bytes, ncache);
1118 OUTPUT:
1119 RETVAL
957 1120
958int set_flags (DB *env, U32 flags, int onoff) 1121int set_flags (DB *db, U32 flags);
1122 CODE:
1123 RETVAL = db->set_flags (db, flags);
1124 OUTPUT:
1125 RETVAL
959 1126
960int set_encrypt (DB *db, const char *password, U32 flags) 1127int set_encrypt (DB *db, const char *password, U32 flags)
1128 CODE:
1129 RETVAL = db->set_encrypt (db, password, flags);
1130 OUTPUT:
1131 RETVAL
961 1132
962int set_lorder (DB *db, int lorder) 1133int set_lorder (DB *db, int lorder)
1134 CODE:
1135 RETVAL = db->set_lorder (db, lorder);
1136 OUTPUT:
1137 RETVAL
963 1138
964 1139
965int set_bt_minkey (DB *db, U32 minkey) 1140int set_bt_minkey (DB *db, U32 minkey)
1141 CODE:
1142 RETVAL = db->set_bt_minkey (db, minkey);
1143 OUTPUT:
1144 RETVAL
966 1145
967int set_re_delim(DB *db, int delim); 1146int set_re_delim(DB *db, int delim);
1147 CODE:
1148 RETVAL = db->set_re_delim (db, delim);
1149 OUTPUT:
1150 RETVAL
968 1151
969int set_re_pad (DB *db, int re_pad) 1152int set_re_pad (DB *db, int re_pad)
1153 CODE:
1154 RETVAL = db->set_re_pad (db, re_pad);
1155 OUTPUT:
1156 RETVAL
970 1157
971int set_re_source (DB *db, char *source) 1158int set_re_source (DB *db, char *source)
1159 CODE:
1160 RETVAL = db->set_re_source (db, source);
1161 OUTPUT:
1162 RETVAL
972 1163
973int set_re_len (DB *db, U32 re_len) 1164int set_re_len (DB *db, U32 re_len)
1165 CODE:
1166 RETVAL = db->set_re_len (db, re_len);
1167 OUTPUT:
1168 RETVAL
974 1169
975int set_h_ffactor (DB *db, U32 h_ffactor) 1170int set_h_ffactor (DB *db, U32 h_ffactor)
1171 CODE:
1172 RETVAL = db->set_h_ffactor (db, h_ffactor);
1173 OUTPUT:
1174 RETVAL
976 1175
977int set_h_nelem (DB *db, U32 h_nelem) 1176int set_h_nelem (DB *db, U32 h_nelem)
1177 CODE:
1178 RETVAL = db->set_h_nelem (db, h_nelem);
1179 OUTPUT:
1180 RETVAL
978 1181
979int set_q_extentsize (DB *db, U32 extentsize) 1182int set_q_extentsize (DB *db, U32 extentsize)
1183 CODE:
1184 RETVAL = db->set_q_extentsize (db, extentsize);
1185 OUTPUT:
1186 RETVAL
980 1187
981 1188

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines