diff options
author | ram@mysql.r18.ru <> | 2002-10-30 15:57:05 +0400 |
---|---|---|
committer | ram@mysql.r18.ru <> | 2002-10-30 15:57:05 +0400 |
commit | 5e09392faa62ea38baa4bd46de5e4183da538e79 (patch) | |
tree | 6881a3cca88bea0bb9eeffd5aae34be437152786 /bdb/libdb_java/java_info.c | |
parent | 1c0f1712ca4869b537ada297930ef01dcb039bb9 (diff) | |
download | mariadb-git-5e09392faa62ea38baa4bd46de5e4183da538e79.tar.gz |
BDB 4.1.24
Diffstat (limited to 'bdb/libdb_java/java_info.c')
-rw-r--r-- | bdb/libdb_java/java_info.c | 816 |
1 files changed, 470 insertions, 346 deletions
diff --git a/bdb/libdb_java/java_info.c b/bdb/libdb_java/java_info.c index ccd469fa256..22fcbd23d46 100644 --- a/bdb/libdb_java/java_info.c +++ b/bdb/libdb_java/java_info.c @@ -1,13 +1,13 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 1998, 1999, 2000 + * Copyright (c) 1997-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: java_info.c,v 11.18 2000/10/28 13:09:39 dda Exp $"; +static const char revid[] = "$Id: java_info.c,v 11.46 2002/08/29 14:22:23 margo Exp $"; #endif /* not lint */ #include <jni.h> @@ -15,63 +15,74 @@ static const char revid[] = "$Id: java_info.c,v 11.18 2000/10/28 13:09:39 dda Ex #include <stdlib.h> #include <string.h> -#include "db.h" #include "db_int.h" #include "java_util.h" /**************************************************************** * * Callback functions - * */ +static int Db_assoc_callback(DB *db, + const DBT *key, + const DBT *data, + DBT *retval) +{ + DB_JAVAINFO *dbinfo; + + DB_ASSERT(db != NULL); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_assoc(dbinfo, db, dbinfo->jdbref, + key, data, retval)); +} + static void Db_feedback_callback(DB *db, int opcode, int percent) { DB_JAVAINFO *dbinfo; DB_ASSERT(db != NULL); - dbinfo = (DB_JAVAINFO *)db->cj_internal; - dbji_call_feedback(dbinfo, db, dbinfo->jdbref_, opcode, percent); + dbinfo = (DB_JAVAINFO *)db->api_internal; + dbji_call_feedback(dbinfo, db, dbinfo->jdbref, opcode, percent); } static int Db_append_recno_callback(DB *db, DBT *dbt, db_recno_t recno) { DB_JAVAINFO *dbinfo; - dbinfo = (DB_JAVAINFO *)db->cj_internal; - return (dbji_call_append_recno(dbinfo, db, dbinfo->jdbref_, dbt, recno)); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_append_recno(dbinfo, db, dbinfo->jdbref, dbt, recno)); } static int Db_bt_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2) { DB_JAVAINFO *dbinfo; - dbinfo = (DB_JAVAINFO *)db->cj_internal; - return (dbji_call_bt_compare(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2)); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_bt_compare(dbinfo, db, dbinfo->jdbref, dbt1, dbt2)); } static size_t Db_bt_prefix_callback(DB *db, const DBT *dbt1, const DBT *dbt2) { DB_JAVAINFO *dbinfo; - dbinfo = (DB_JAVAINFO *)db->cj_internal; - return (dbji_call_bt_prefix(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2)); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_bt_prefix(dbinfo, db, dbinfo->jdbref, dbt1, dbt2)); } static int Db_dup_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2) { DB_JAVAINFO *dbinfo; - dbinfo = (DB_JAVAINFO *)db->cj_internal; - return (dbji_call_dup_compare(dbinfo, db, dbinfo->jdbref_, dbt1, dbt2)); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_dup_compare(dbinfo, db, dbinfo->jdbref, dbt1, dbt2)); } static u_int32_t Db_h_hash_callback(DB *db, const void *data, u_int32_t len) { DB_JAVAINFO *dbinfo; - dbinfo = (DB_JAVAINFO *)db->cj_internal; - return (dbji_call_h_hash(dbinfo, db, dbinfo->jdbref_, data, len)); + dbinfo = (DB_JAVAINFO *)db->api_internal; + return (dbji_call_h_hash(dbinfo, db, dbinfo->jdbref, data, len)); } static void DbEnv_feedback_callback(DB_ENV *dbenv, int opcode, int percent) @@ -79,91 +90,87 @@ static void DbEnv_feedback_callback(DB_ENV *dbenv, int opcode, int percent) DB_ENV_JAVAINFO *dbinfo; DB_ASSERT(dbenv != NULL); - dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal; - dbjie_call_feedback(dbinfo, dbenv, dbinfo->jenvref_, opcode, percent); + dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal; + dbjie_call_feedback(dbinfo, dbenv, dbinfo->jenvref, opcode, percent); } -static int DbEnv_recovery_init_callback(DB_ENV *dbenv) +static int DbEnv_rep_transport_callback(DB_ENV *dbenv, + const DBT *control, const DBT *rec, + int envid, u_int32_t flags) { DB_ENV_JAVAINFO *dbinfo; - dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal; - return (dbjie_call_recovery_init(dbinfo, dbenv, dbinfo->jenvref_)); + dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal; + return (dbjie_call_rep_transport(dbinfo, dbenv, + dbinfo->jenvref, control, rec, envid, (int)flags)); } -static int DbEnv_tx_recover_callback(DB_ENV *dbenv, DBT *dbt, +static int DbEnv_app_dispatch_callback(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, db_recops recops) { DB_ENV_JAVAINFO *dbinfo; DB_ASSERT(dbenv != NULL); - dbinfo = (DB_ENV_JAVAINFO *)dbenv->cj_internal; - return dbjie_call_tx_recover(dbinfo, dbenv, dbinfo->jenvref_, dbt, - lsn, recops); + dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal; + return (dbjie_call_app_dispatch(dbinfo, dbenv, dbinfo->jenvref, dbt, + lsn, recops)); } /**************************************************************** * * Implementation of class DBT_javainfo - * */ DBT_JAVAINFO * dbjit_construct() { DBT_JAVAINFO *dbjit; + int err; + + /*XXX should return err*/ + if ((err = __os_malloc(NULL, sizeof(DBT_JAVAINFO), &dbjit)) != 0) + return (NULL); - dbjit = (DBT_JAVAINFO *)malloc(sizeof(DBT_JAVAINFO)); memset(dbjit, 0, sizeof(DBT_JAVAINFO)); return (dbjit); } void dbjit_destroy(DBT_JAVAINFO *dbjit) { - /* Sanity check: - * We cannot delete the global ref because we don't have a JNIEnv. - */ - if (dbjit->array_ != NULL) { - fprintf(stderr, "object is not freed\n"); - } - + DB_ASSERT(!F_ISSET(dbjit, DBT_JAVAINFO_LOCKED)); /* Extra paranoia */ - memset(dbjit, 0, sizeof(DB_JAVAINFO)); - free(dbjit); -} - -void dbjit_release(DBT_JAVAINFO *dbjit, JNIEnv *jnienv) -{ - if (dbjit->array_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjit->array_); - dbjit->array_ = NULL; - } + memset(dbjit, 0, sizeof(DBT_JAVAINFO)); + (void)__os_free(NULL, dbjit); } /**************************************************************** * * Implementation of class DB_ENV_JAVAINFO - * */ /* create/initialize an object */ DB_ENV_JAVAINFO * dbjie_construct(JNIEnv *jnienv, + jobject jenv, jobject default_errcall, int is_dbopen) { DB_ENV_JAVAINFO *dbjie; + int err; - dbjie = (DB_ENV_JAVAINFO *)malloc(sizeof(DB_ENV_JAVAINFO)); + /*XXX should return err*/ + if ((err = __os_malloc(NULL, sizeof(DB_ENV_JAVAINFO), &dbjie)) != 0) + return (NULL); memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO)); - dbjie->is_dbopen_ = is_dbopen; + dbjie->is_dbopen = is_dbopen; - if ((*jnienv)->GetJavaVM(jnienv, &dbjie->javavm_) != 0) { - free(dbjie); + if ((*jnienv)->GetJavaVM(jnienv, &dbjie->javavm) != 0) { + __os_free(NULL, dbjie); report_exception(jnienv, "cannot get Java VM", 0, 0); return (NULL); } - /* The default error call just prints to the 'System.err' + /* + * The default error call just prints to the 'System.err' * stream. If the user does set_errcall to null, we'll * want to have a reference to set it back to. * @@ -172,42 +179,44 @@ dbjie_construct(JNIEnv *jnienv, * error prefix, error stream, and user's error callback * that much easier. */ - dbjie->default_errcall_ = NEW_GLOBAL_REF(jnienv, default_errcall); - dbjie->errcall_ = NEW_GLOBAL_REF(jnienv, default_errcall); + dbjie->default_errcall = NEW_GLOBAL_REF(jnienv, default_errcall); + dbjie->errcall = NEW_GLOBAL_REF(jnienv, default_errcall); + dbjie->jenvref = NEW_GLOBAL_REF(jnienv, jenv); return (dbjie); } /* release all objects held by this this one */ void dbjie_dealloc(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv) { - if (dbjie->recovery_init_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->recovery_init_); - dbjie->recovery_init_ = NULL; + if (dbjie->feedback != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->feedback); + dbjie->feedback = NULL; } - if (dbjie->feedback_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->feedback_); - dbjie->feedback_ = NULL; + if (dbjie->app_dispatch != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->app_dispatch); + dbjie->app_dispatch = NULL; } - if (dbjie->tx_recover_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->tx_recover_); - dbjie->tx_recover_ = NULL; + if (dbjie->errcall != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->errcall); + dbjie->errcall = NULL; } - if (dbjie->errcall_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->errcall_); - dbjie->errcall_ = NULL; + if (dbjie->default_errcall != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->default_errcall); + dbjie->default_errcall = NULL; } - if (dbjie->default_errcall_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->default_errcall_); - dbjie->default_errcall_ = NULL; + if (dbjie->jenvref != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->jenvref); + dbjie->jenvref = NULL; } - if (dbjie->conflict_ != NULL) { - free(dbjie->conflict_); - dbjie->conflict_ = NULL; + if (dbjie->conflict != NULL) { + __os_free(NULL, dbjie->conflict); + dbjie->conflict = NULL; + dbjie->conflict_size = 0; } - if (dbjie->errpfx_ != NULL) { - free(dbjie->errpfx_); - dbjie->errpfx_ = NULL; + if (dbjie->errpfx != NULL) { + __os_free(NULL, dbjie->errpfx); + dbjie->errpfx = NULL; } } @@ -218,17 +227,19 @@ void dbjie_destroy(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv) /* Extra paranoia */ memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO)); - free(dbjie); + (void)__os_free(NULL, dbjie); } -/* Attach to the current thread that is running and +/* + * Attach to the current thread that is running and * return that. We use the java virtual machine * that we saved in the constructor. */ JNIEnv * dbjie_get_jnienv(DB_ENV_JAVAINFO *dbjie) { - /* Note: + /* + * Note: * Different versions of the JNI disagree on the signature * for AttachCurrentThread. The most recent documentation * seems to say that (JNIEnv **) is correct, but newer @@ -240,10 +251,12 @@ dbjie_get_jnienv(DB_ENV_JAVAINFO *dbjie) JNIEnv *attachret = 0; #endif - /* This should always succeed, as we are called via + /* + * This should always succeed, as we are called via * some Java activity. I think therefore I am (a thread). */ - if ((*dbjie->javavm_)->AttachCurrentThread(dbjie->javavm_, &attachret, 0) != 0) + if ((*dbjie->javavm)->AttachCurrentThread(dbjie->javavm, &attachret, 0) + != 0) return (0); return ((JNIEnv *)attachret); @@ -252,40 +265,42 @@ dbjie_get_jnienv(DB_ENV_JAVAINFO *dbjie) jstring dbjie_get_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv) { - return (get_java_string(jnienv, dbjie->errpfx_)); + return (get_java_string(jnienv, dbjie->errpfx)); } void dbjie_set_errcall(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jobject new_errcall) { - /* If the new_errcall is null, we'll set the error call + /* + * If the new_errcall is null, we'll set the error call * to the default one. */ if (new_errcall == NULL) - new_errcall = dbjie->default_errcall_; + new_errcall = dbjie->default_errcall; - DELETE_GLOBAL_REF(jnienv, dbjie->errcall_); - dbjie->errcall_ = NEW_GLOBAL_REF(jnienv, new_errcall); + DELETE_GLOBAL_REF(jnienv, dbjie->errcall); + dbjie->errcall = NEW_GLOBAL_REF(jnienv, new_errcall); } void dbjie_set_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jstring errpfx) { - if (dbjie->errpfx_ != NULL) - free(dbjie->errpfx_); + if (dbjie->errpfx != NULL) + __os_free(NULL, dbjie->errpfx); if (errpfx) - dbjie->errpfx_ = get_c_string(jnienv, errpfx); + dbjie->errpfx = get_c_string(jnienv, errpfx); else - dbjie->errpfx_ = NULL; + dbjie->errpfx = NULL; } void -dbjie_set_conflict(DB_ENV_JAVAINFO *dbjie, unsigned char *newarr) +dbjie_set_conflict(DB_ENV_JAVAINFO *dbjie, u_char *newarr, size_t size) { - if (dbjie->conflict_) - free(dbjie->conflict_); - dbjie->conflict_ = newarr; + if (dbjie->conflict != NULL) + (void)__os_free(NULL, dbjie->conflict); + dbjie->conflict = newarr; + dbjie->conflict_size = size; } void dbjie_set_feedback_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, @@ -293,8 +308,8 @@ void dbjie_set_feedback_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, { int err; - if (dbjie->feedback_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->feedback_); + if (dbjie->feedback != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->feedback); } if (jfeedback == NULL) { if ((err = dbenv->set_feedback(dbenv, NULL)) != 0) @@ -308,7 +323,7 @@ void dbjie_set_feedback_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, err, 0); } - dbjie->feedback_ = NEW_GLOBAL_REF(jnienv, jfeedback); + dbjie->feedback = NEW_GLOBAL_REF(jnienv, jfeedback); } void dbjie_call_feedback(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv, @@ -325,97 +340,107 @@ void dbjie_call_feedback(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv, return; } - feedback_class = get_class(jnienv, name_DbEnvFeedback); + if ((feedback_class = + get_class(jnienv, name_DbEnvFeedback)) == NULL) { + fprintf(stderr, "Cannot find callback class %s\n", + name_DbEnvFeedback); + return; /* An exception has been posted. */ + } id = (*jnienv)->GetMethodID(jnienv, feedback_class, "feedback", "(Lcom/sleepycat/db/DbEnv;II)V"); if (!id) { - fprintf(stderr, "Cannot find callback class\n"); + fprintf(stderr, "Cannot find callback method feedback\n"); return; } - (*jnienv)->CallVoidMethod(jnienv, dbjie->feedback_, id, + (*jnienv)->CallVoidMethod(jnienv, dbjie->feedback, id, jenv, (jint)opcode, (jint)percent); } -void dbjie_set_recovery_init_object(DB_ENV_JAVAINFO *dbjie, - JNIEnv *jnienv, DB_ENV *dbenv, - jobject jrecovery_init) +void dbjie_set_rep_transport_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, + DB_ENV *dbenv, int id, jobject jtransport) { int err; - if (dbjie->recovery_init_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->recovery_init_); - } - if (jrecovery_init == NULL) { - if ((err = dbenv->set_recovery_init(dbenv, NULL)) != 0) - report_exception(jnienv, "set_recovery_init failed", - err, 0); - } - else { - if ((err = dbenv->set_recovery_init(dbenv, - DbEnv_recovery_init_callback)) != 0) - report_exception(jnienv, "set_recovery_init failed", - err, 0); - } + if (dbjie->rep_transport != NULL) + DELETE_GLOBAL_REF(jnienv, dbjie->rep_transport); + + err = dbenv->set_rep_transport(dbenv, id, + DbEnv_rep_transport_callback); + verify_return(jnienv, err, 0); - dbjie->recovery_init_ = NEW_GLOBAL_REF(jnienv, jrecovery_init); + dbjie->rep_transport = NEW_GLOBAL_REF(jnienv, jtransport); } -int dbjie_call_recovery_init(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, - jobject jenv) +int dbjie_call_rep_transport(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, + jobject jenv, const DBT *control, + const DBT *rec, int flags, int envid) { JNIEnv *jnienv; - jclass recovery_init_class; - jmethodID id; + jclass rep_transport_class; + jmethodID jid; + jobject jcdbt, jrdbt; COMPQUIET(dbenv, NULL); jnienv = dbjie_get_jnienv(dbjie); if (jnienv == NULL) { fprintf(stderr, "Cannot attach to current thread!\n"); - return (EINVAL); + return (0); } - recovery_init_class = get_class(jnienv, name_DbRecoveryInit); - id = (*jnienv)->GetMethodID(jnienv, recovery_init_class, - "recovery_init", - "(Lcom/sleepycat/db/DbEnv;)V"); - if (!id) { - fprintf(stderr, "Cannot find callback class\n"); - return (EINVAL); + if ((rep_transport_class = + get_class(jnienv, name_DbRepTransport)) == NULL) { + fprintf(stderr, "Cannot find callback class %s\n", + name_DbRepTransport); + return (0); /* An exception has been posted. */ } - return (*jnienv)->CallIntMethod(jnienv, dbjie->recovery_init_, - id, jenv); + jid = (*jnienv)->GetMethodID(jnienv, rep_transport_class, + "send", + "(Lcom/sleepycat/db/DbEnv;" + "Lcom/sleepycat/db/Dbt;" + "Lcom/sleepycat/db/Dbt;II)I"); + + if (!jid) { + fprintf(stderr, "Cannot find callback method send\n"); + return (0); + } + + jcdbt = get_const_Dbt(jnienv, control, NULL); + jrdbt = get_const_Dbt(jnienv, rec, NULL); + + return (*jnienv)->CallIntMethod(jnienv, dbjie->rep_transport, jid, jenv, + jcdbt, jrdbt, flags, envid); } -void dbjie_set_tx_recover_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, - DB_ENV *dbenv, jobject jtx_recover) +void dbjie_set_app_dispatch_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, + DB_ENV *dbenv, jobject japp_dispatch) { int err; - if (dbjie->tx_recover_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbjie->tx_recover_); + if (dbjie->app_dispatch != NULL) { + DELETE_GLOBAL_REF(jnienv, dbjie->app_dispatch); } - if (jtx_recover == NULL) { - if ((err = dbenv->set_tx_recover(dbenv, NULL)) != 0) - report_exception(jnienv, "set_tx_recover failed", + if (japp_dispatch == NULL) { + if ((err = dbenv->set_app_dispatch(dbenv, NULL)) != 0) + report_exception(jnienv, "set_app_dispatch failed", err, 0); } else { - if ((err = dbenv->set_tx_recover(dbenv, - DbEnv_tx_recover_callback)) != 0) - report_exception(jnienv, "set_tx_recover failed", + if ((err = dbenv->set_app_dispatch(dbenv, + DbEnv_app_dispatch_callback)) != 0) + report_exception(jnienv, "set_app_dispatch failed", err, 0); } - dbjie->tx_recover_ = NEW_GLOBAL_REF(jnienv, jtx_recover); + dbjie->app_dispatch = NEW_GLOBAL_REF(jnienv, japp_dispatch); } -int dbjie_call_tx_recover(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv, +int dbjie_call_app_dispatch(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv, DBT *dbt, DB_LSN *lsn, int recops) { JNIEnv *jnienv; - jclass tx_recover_class; + jclass app_dispatch_class; jmethodID id; jobject jdbt; jobject jlsn; @@ -427,90 +452,104 @@ int dbjie_call_tx_recover(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv, return (0); } - tx_recover_class = get_class(jnienv, name_DbTxnRecover); - id = (*jnienv)->GetMethodID(jnienv, tx_recover_class, - "tx_recover", + if ((app_dispatch_class = + get_class(jnienv, name_DbTxnRecover)) == NULL) { + fprintf(stderr, "Cannot find callback class %s\n", + name_DbTxnRecover); + return (0); /* An exception has been posted. */ + } + id = (*jnienv)->GetMethodID(jnienv, app_dispatch_class, + "app_dispatch", "(Lcom/sleepycat/db/DbEnv;" "Lcom/sleepycat/db/Dbt;" "Lcom/sleepycat/db/DbLsn;" "I)I"); if (!id) { - fprintf(stderr, "Cannot find callback class\n"); + fprintf(stderr, "Cannot find callback method app_dispatch\n"); return (0); } - if (dbt == NULL) - jdbt = NULL; - else - jdbt = get_Dbt(jnienv, dbt); + jdbt = get_Dbt(jnienv, dbt, NULL); if (lsn == NULL) jlsn = NULL; else jlsn = get_DbLsn(jnienv, *lsn); - return (*jnienv)->CallIntMethod(jnienv, dbjie->tx_recover_, id, jenv, + return (*jnienv)->CallIntMethod(jnienv, dbjie->app_dispatch, id, jenv, jdbt, jlsn, recops); } jobject dbjie_get_errcall(DB_ENV_JAVAINFO *dbjie) { - return (dbjie->errcall_); + return (dbjie->errcall); } -int dbjie_is_dbopen(DB_ENV_JAVAINFO *dbjie) +jint dbjie_is_dbopen(DB_ENV_JAVAINFO *dbjie) { - return (dbjie->is_dbopen_); + return (dbjie->is_dbopen); } /**************************************************************** * * Implementation of class DB_JAVAINFO - * */ -DB_JAVAINFO *dbji_construct(JNIEnv *jnienv, jint flags) +DB_JAVAINFO *dbji_construct(JNIEnv *jnienv, jobject jdb, jint flags) { DB_JAVAINFO *dbji; + int err; + + /*XXX should return err*/ + if ((err = __os_malloc(NULL, sizeof(DB_JAVAINFO), &dbji)) != 0) + return (NULL); - dbji = (DB_JAVAINFO *)malloc(sizeof(DB_JAVAINFO)); memset(dbji, 0, sizeof(DB_JAVAINFO)); - if ((*jnienv)->GetJavaVM(jnienv, &dbji->javavm_) != 0) { + if ((*jnienv)->GetJavaVM(jnienv, &dbji->javavm) != 0) { report_exception(jnienv, "cannot get Java VM", 0, 0); - free(dbji); + (void)__os_free(NULL, dbji); return (NULL); } - dbji->construct_flags_ = flags; + dbji->jdbref = NEW_GLOBAL_REF(jnienv, jdb); + dbji->construct_flags = flags; return (dbji); } void dbji_dealloc(DB_JAVAINFO *dbji, JNIEnv *jnienv) { - if (dbji->append_recno_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->append_recno_); - dbji->append_recno_ = NULL; + if (dbji->append_recno != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->append_recno); + dbji->append_recno = NULL; + } + if (dbji->assoc != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->assoc); + dbji->assoc = NULL; + } + if (dbji->bt_compare != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->bt_compare); + dbji->bt_compare = NULL; } - if (dbji->bt_compare_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->bt_compare_); - dbji->bt_compare_ = NULL; + if (dbji->bt_prefix != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix); + dbji->bt_prefix = NULL; } - if (dbji->bt_prefix_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix_); - dbji->bt_prefix_ = NULL; + if (dbji->dup_compare != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->dup_compare); + dbji->dup_compare = NULL; } - if (dbji->dup_compare_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->dup_compare_); - dbji->dup_compare_ = NULL; + if (dbji->feedback != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->feedback); + dbji->feedback = NULL; } - if (dbji->feedback_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->feedback_); - dbji->feedback_ = NULL; + if (dbji->h_hash != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->h_hash); + dbji->h_hash = NULL; } - if (dbji->h_hash_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->h_hash_); - dbji->h_hash_ = NULL; + if (dbji->jdbref != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->jdbref); + dbji->jdbref = NULL; } } @@ -518,12 +557,13 @@ void dbji_destroy(DB_JAVAINFO *dbji, JNIEnv *jnienv) { dbji_dealloc(dbji, jnienv); - free(dbji); + __os_free(NULL, dbji); } JNIEnv *dbji_get_jnienv(DB_JAVAINFO *dbji) { - /* Note: + /* + * Note: * Different versions of the JNI disagree on the signature * for AttachCurrentThread. The most recent documentation * seems to say that (JNIEnv **) is correct, but newer @@ -535,10 +575,12 @@ JNIEnv *dbji_get_jnienv(DB_JAVAINFO *dbji) JNIEnv *attachret = 0; #endif - /* This should always succeed, as we are called via + /* + * This should always succeed, as we are called via * some Java activity. I think therefore I am (a thread). */ - if ((*dbji->javavm_)->AttachCurrentThread(dbji->javavm_, &attachret, 0) != 0) + if ((*dbji->javavm)->AttachCurrentThread(dbji->javavm, &attachret, 0) + != 0) return (0); return ((JNIEnv *)attachret); @@ -546,7 +588,7 @@ JNIEnv *dbji_get_jnienv(DB_JAVAINFO *dbji) jint dbji_get_flags(DB_JAVAINFO *dbji) { - return (dbji->construct_flags_); + return (dbji->construct_flags); } void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, @@ -554,14 +596,17 @@ void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass feedback_class; - if (dbji->feedback_method_id_ == NULL) { - feedback_class = get_class(jnienv, name_DbFeedback); - dbji->feedback_method_id_ = + if (dbji->feedback_method_id == NULL) { + if ((feedback_class = + get_class(jnienv, name_DbFeedback)) == NULL) + return; /* An exception has been posted. */ + dbji->feedback_method_id = (*jnienv)->GetMethodID(jnienv, feedback_class, "feedback", "(Lcom/sleepycat/db/Db;II)V"); - if (dbji->feedback_method_id_ != NULL) { - /* XXX + if (dbji->feedback_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -572,8 +617,8 @@ void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->feedback_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->feedback_); + if (dbji->feedback != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->feedback); } if (jfeedback == NULL) { db->set_feedback(db, NULL); @@ -582,7 +627,7 @@ void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, db->set_feedback(db, Db_feedback_callback); } - dbji->feedback_ = NEW_GLOBAL_REF(jnienv, jfeedback); + dbji->feedback = NEW_GLOBAL_REF(jnienv, jfeedback); } @@ -598,9 +643,9 @@ void dbji_call_feedback(DB_JAVAINFO *dbji, DB *db, jobject jdb, return; } - DB_ASSERT(dbji->feedback_method_id_ != NULL); - (*jnienv)->CallVoidMethod(jnienv, dbji->feedback_, - dbji->feedback_method_id_, + DB_ASSERT(dbji->feedback_method_id != NULL); + (*jnienv)->CallVoidMethod(jnienv, dbji->feedback, + dbji->feedback_method_id, jdb, (jint)opcode, (jint)percent); } @@ -609,15 +654,18 @@ void dbji_set_append_recno_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass append_recno_class; - if (dbji->append_recno_method_id_ == NULL) { - append_recno_class = get_class(jnienv, name_DbAppendRecno); - dbji->append_recno_method_id_ = + if (dbji->append_recno_method_id == NULL) { + if ((append_recno_class = + get_class(jnienv, name_DbAppendRecno)) == NULL) + return; /* An exception has been posted. */ + dbji->append_recno_method_id = (*jnienv)->GetMethodID(jnienv, append_recno_class, "db_append_recno", "(Lcom/sleepycat/db/Db;" "Lcom/sleepycat/db/Dbt;I)V"); - if (dbji->append_recno_method_id_ == NULL) { - /* XXX + if (dbji->append_recno_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -628,8 +676,8 @@ void dbji_set_append_recno_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->append_recno_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->append_recno_); + if (dbji->append_recno != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->append_recno); } if (jcallback == NULL) { db->set_append_recno(db, NULL); @@ -638,51 +686,36 @@ void dbji_set_append_recno_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, db->set_append_recno(db, Db_append_recno_callback); } - dbji->append_recno_ = NEW_GLOBAL_REF(jnienv, jcallback); + dbji->append_recno = NEW_GLOBAL_REF(jnienv, jcallback); } extern int dbji_call_append_recno(DB_JAVAINFO *dbji, DB *db, jobject jdb, DBT *dbt, jint recno) { JNIEnv *jnienv; - jobject jdbt; + jobject jresult; DBT_JAVAINFO *dbtji; - jbyteArray arr; - unsigned int arraylen; - unsigned char *data; + LOCKED_DBT lresult; + DB_ENV *dbenv; + u_char *bytearray; + int err; - COMPQUIET(db, NULL); jnienv = dbji_get_jnienv(dbji); + dbenv = db->dbenv; if (jnienv == NULL) { fprintf(stderr, "Cannot attach to current thread!\n"); return (0); } - /* XXX - * We should have a pool of Dbt objects used for this purpose - * instead of creating new ones each time. Because of - * multithreading, we may need an arbitrary number (more than two). - * We might also have a byte arrays that grow as needed, - * so we don't need to allocate those either. - * - * Note, we do not set the 'create_array_' flag as on other - * callbacks as we are creating the array here. - */ - jdbt = create_default_object(jnienv, name_DBT); - dbtji = get_DBT_JAVAINFO(jnienv, jdbt); - memcpy(&dbtji->dbt, dbt, sizeof(DBT)); - dbtji->dbt.data = NULL; - arr = (*jnienv)->NewByteArray(jnienv, dbt->size); - (*jnienv)->SetByteArrayRegion(jnienv, arr, 0, dbt->size, - (jbyte *)dbt->data); - dbtji->array_ = (jbyteArray)NEW_GLOBAL_REF(jnienv, arr); - - DB_ASSERT(dbji->append_recno_method_id_ != NULL); - (*jnienv)->CallVoidMethod(jnienv, dbji->append_recno_, - dbji->append_recno_method_id_, - jdb, jdbt, recno); - - /* The underlying C API requires that an errno be returned + jresult = get_Dbt(jnienv, dbt, &dbtji); + + DB_ASSERT(dbji->append_recno_method_id != NULL); + (*jnienv)->CallVoidMethod(jnienv, dbji->append_recno, + dbji->append_recno_method_id, + jdb, jresult, recno); + + /* + * The underlying C API requires that an errno be returned * on error. Java users know nothing of errnos, so we * allow them to throw exceptions instead. We leave the * exception in place and return DB_JAVA_CALLBACK to the C API @@ -701,26 +734,146 @@ extern int dbji_call_append_recno(DB_JAVAINFO *dbji, DB *db, jobject jdb, if ((*jnienv)->ExceptionOccurred(jnienv) != NULL) return (DB_JAVA_CALLBACK); - if (dbtji->array_ == NULL) { - report_exception(jnienv, "Dbt.data is null", 0, 0); - return (EFAULT); + /* + * Now get the DBT back from java, because the user probably + * changed it. We'll have to copy back the array too and let + * our caller free it. + * + * We expect that the user *has* changed the DBT (why else would + * they set up an append_recno callback?) so we don't + * worry about optimizing the unchanged case. + */ + if ((err = locked_dbt_get(&lresult, jnienv, dbenv, jresult, inOp)) != 0) + return (err); + + memcpy(dbt, &lresult.javainfo->dbt, sizeof(DBT)); + if ((err = __os_malloc(dbenv, dbt->size, &bytearray)) != 0) + goto out; + + memcpy(bytearray, dbt->data, dbt->size); + dbt->data = bytearray; + dbt->flags |= DB_DBT_APPMALLOC; + + out: + locked_dbt_put(&lresult, jnienv, dbenv); + return (err); +} + +void dbji_set_assoc_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, + DB *db, DB_TXN *txn, DB *second, + jobject jcallback, int flags) +{ + jclass assoc_class; + int err; + + if (dbji->assoc_method_id == NULL) { + if ((assoc_class = + get_class(jnienv, name_DbSecondaryKeyCreate)) == NULL) + return; /* An exception has been posted. */ + dbji->assoc_method_id = + (*jnienv)->GetMethodID(jnienv, assoc_class, + "secondary_key_create", + "(Lcom/sleepycat/db/Db;" + "Lcom/sleepycat/db/Dbt;" + "Lcom/sleepycat/db/Dbt;" + "Lcom/sleepycat/db/Dbt;)I"); + if (dbji->assoc_method_id == NULL) { + /* + * XXX + * We should really have a better way + * to translate this to a Java exception class. + * In theory, it shouldn't happen. + */ + report_exception(jnienv, "Cannot find callback method", + EFAULT, 0); + return; + } } - arraylen = (*jnienv)->GetArrayLength(jnienv, dbtji->array_); - if (dbtji->offset_ < 0 ) { - report_exception(jnienv, "Dbt.offset illegal", 0, 0); - return (EFAULT); + if (dbji->assoc != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->assoc); + dbji->assoc = NULL; } - if (dbt->ulen + dbtji->offset_ > arraylen) { - report_exception(jnienv, - "Dbt.ulen + Dbt.offset greater than array length", 0, 0); - return (EFAULT); + + if (jcallback == NULL) + err = db->associate(db, txn, second, NULL, flags); + else + err = db->associate(db, txn, second, Db_assoc_callback, flags); + + if (verify_return(jnienv, err, 0)) + dbji->assoc = NEW_GLOBAL_REF(jnienv, jcallback); +} + +extern int dbji_call_assoc(DB_JAVAINFO *dbji, DB *db, jobject jdb, + const DBT *key, const DBT *value, DBT *result) +{ + JNIEnv *jnienv; + jobject jresult; + LOCKED_DBT lresult; + DB_ENV *dbenv; + int err; + int sz; + u_char *bytearray; + jint retval; + + jnienv = dbji_get_jnienv(dbji); + if (jnienv == NULL) { + fprintf(stderr, "Cannot attach to current thread!\n"); + return (0); } - data = (*jnienv)->GetByteArrayElements(jnienv, dbtji->array_, - (jboolean *)0); - dbt->data = data + dbtji->offset_; - return (0); + DB_ASSERT(dbji->assoc_method_id != NULL); + + dbenv = db->dbenv; + jresult = create_default_object(jnienv, name_DBT); + + retval = (*jnienv)->CallIntMethod(jnienv, dbji->assoc, + dbji->assoc_method_id, jdb, + get_const_Dbt(jnienv, key, NULL), + get_const_Dbt(jnienv, value, NULL), + jresult); + if (retval != 0) + return (retval); + + if ((*jnienv)->ExceptionOccurred(jnienv) != NULL) + return (DB_JAVA_CALLBACK); + + if ((err = locked_dbt_get(&lresult, jnienv, dbenv, jresult, inOp)) != 0) + return (err); + + sz = lresult.javainfo->dbt.size; + if (sz > 0) { + bytearray = (u_char *)lresult.javainfo->dbt.data; + + /* + * If the byte array is in the range of one of the + * arrays passed to us we can use it directly. + * If not, we must create our own array and + * fill it in with the java array. Since + * the java array may disappear and we don't + * want to keep its memory locked indefinitely, + * we cannot just pin the array. + * + * XXX consider pinning the array, and having + * some way for the C layer to notify the java + * layer when it can be unpinned. + */ + if ((bytearray < (u_char *)key->data || + bytearray + sz > (u_char *)key->data + key->size) && + (bytearray < (u_char *)value->data || + bytearray + sz > (u_char *)value->data + value->size)) { + + result->flags |= DB_DBT_APPMALLOC; + if ((err = __os_malloc(dbenv, sz, &bytearray)) != 0) + goto out; + memcpy(bytearray, lresult.javainfo->dbt.data, sz); + } + result->data = bytearray; + result->size = sz; + } + out: + locked_dbt_put(&lresult, jnienv, dbenv); + return (err); } void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, @@ -728,16 +881,19 @@ void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass bt_compare_class; - if (dbji->bt_compare_method_id_ == NULL) { - bt_compare_class = get_class(jnienv, name_DbBtreeCompare); - dbji->bt_compare_method_id_ = + if (dbji->bt_compare_method_id == NULL) { + if ((bt_compare_class = + get_class(jnienv, name_DbBtreeCompare)) == NULL) + return; /* An exception has been posted. */ + dbji->bt_compare_method_id = (*jnienv)->GetMethodID(jnienv, bt_compare_class, "bt_compare", "(Lcom/sleepycat/db/Db;" "Lcom/sleepycat/db/Dbt;" "Lcom/sleepycat/db/Dbt;)I"); - if (dbji->bt_compare_method_id_ == NULL) { - /* XXX + if (dbji->bt_compare_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -748,8 +904,8 @@ void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->bt_compare_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->bt_compare_); + if (dbji->bt_compare != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->bt_compare); } if (jcompare == NULL) { db->set_bt_compare(db, NULL); @@ -758,7 +914,7 @@ void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, db->set_bt_compare(db, Db_bt_compare_callback); } - dbji->bt_compare_ = NEW_GLOBAL_REF(jnienv, jcompare); + dbji->bt_compare = NEW_GLOBAL_REF(jnienv, jcompare); } int dbji_call_bt_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, @@ -766,7 +922,6 @@ int dbji_call_bt_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, { JNIEnv *jnienv; jobject jdbt1, jdbt2; - DBT_JAVAINFO *dbtji1, *dbtji2; COMPQUIET(db, NULL); jnienv = dbji_get_jnienv(dbji); @@ -775,25 +930,12 @@ int dbji_call_bt_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, return (0); } - /* XXX - * We should have a pool of Dbt objects used for this purpose - * instead of creating new ones each time. Because of - * multithreading, we may need an arbitrary number (more than two). - * We might also have a byte arrays that grow as needed, - * so we don't need to allocate those either. - */ - jdbt1 = create_default_object(jnienv, name_DBT); - jdbt2 = create_default_object(jnienv, name_DBT); - dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1); - memcpy(&dbtji1->dbt, dbt1, sizeof(DBT)); - dbtji1->create_array_ = 1; - dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2); - memcpy(&dbtji2->dbt, dbt2, sizeof(DBT)); - dbtji2->create_array_ = 1; - - DB_ASSERT(dbji->bt_compare_method_id_ != NULL); - return (*jnienv)->CallIntMethod(jnienv, dbji->bt_compare_, - dbji->bt_compare_method_id_, + jdbt1 = get_const_Dbt(jnienv, dbt1, NULL); + jdbt2 = get_const_Dbt(jnienv, dbt2, NULL); + + DB_ASSERT(dbji->bt_compare_method_id != NULL); + return (*jnienv)->CallIntMethod(jnienv, dbji->bt_compare, + dbji->bt_compare_method_id, jdb, jdbt1, jdbt2); } @@ -802,16 +944,19 @@ void dbji_set_bt_prefix_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass bt_prefix_class; - if (dbji->bt_prefix_method_id_ == NULL) { - bt_prefix_class = get_class(jnienv, name_DbBtreePrefix); - dbji->bt_prefix_method_id_ = + if (dbji->bt_prefix_method_id == NULL) { + if ((bt_prefix_class = + get_class(jnienv, name_DbBtreePrefix)) == NULL) + return; /* An exception has been posted. */ + dbji->bt_prefix_method_id = (*jnienv)->GetMethodID(jnienv, bt_prefix_class, "bt_prefix", "(Lcom/sleepycat/db/Db;" "Lcom/sleepycat/db/Dbt;" "Lcom/sleepycat/db/Dbt;)I"); - if (dbji->bt_prefix_method_id_ == NULL) { - /* XXX + if (dbji->bt_prefix_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -822,8 +967,8 @@ void dbji_set_bt_prefix_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->bt_prefix_ != NULL) { - DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix_); + if (dbji->bt_prefix != NULL) { + DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix); } if (jprefix == NULL) { db->set_bt_prefix(db, NULL); @@ -832,7 +977,7 @@ void dbji_set_bt_prefix_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, db->set_bt_prefix(db, Db_bt_prefix_callback); } - dbji->bt_prefix_ = NEW_GLOBAL_REF(jnienv, jprefix); + dbji->bt_prefix = NEW_GLOBAL_REF(jnienv, jprefix); } size_t dbji_call_bt_prefix(DB_JAVAINFO *dbji, DB *db, jobject jdb, @@ -840,7 +985,6 @@ size_t dbji_call_bt_prefix(DB_JAVAINFO *dbji, DB *db, jobject jdb, { JNIEnv *jnienv; jobject jdbt1, jdbt2; - DBT_JAVAINFO *dbtji1, *dbtji2; COMPQUIET(db, NULL); jnienv = dbji_get_jnienv(dbji); @@ -849,25 +993,12 @@ size_t dbji_call_bt_prefix(DB_JAVAINFO *dbji, DB *db, jobject jdb, return (0); } - /* XXX - * We should have a pool of Dbt objects used for this purpose - * instead of creating new ones each time. Because of - * multithreading, we may need an arbitrary number (more than two). - * We might also have a byte arrays that grow as needed, - * so we don't need to allocate those either. - */ - jdbt1 = create_default_object(jnienv, name_DBT); - jdbt2 = create_default_object(jnienv, name_DBT); - dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1); - memcpy(&dbtji1->dbt, dbt1, sizeof(DBT)); - dbtji1->create_array_ = 1; - dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2); - memcpy(&dbtji2->dbt, dbt2, sizeof(DBT)); - dbtji2->create_array_ = 1; - - DB_ASSERT(dbji->bt_prefix_method_id_ != NULL); - return (size_t)(*jnienv)->CallIntMethod(jnienv, dbji->bt_prefix_, - dbji->bt_prefix_method_id_, + jdbt1 = get_const_Dbt(jnienv, dbt1, NULL); + jdbt2 = get_const_Dbt(jnienv, dbt2, NULL); + + DB_ASSERT(dbji->bt_prefix_method_id != NULL); + return (size_t)(*jnienv)->CallIntMethod(jnienv, dbji->bt_prefix, + dbji->bt_prefix_method_id, jdb, jdbt1, jdbt2); } @@ -876,16 +1007,19 @@ void dbji_set_dup_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass dup_compare_class; - if (dbji->dup_compare_method_id_ == NULL) { - dup_compare_class = get_class(jnienv, name_DbDupCompare); - dbji->dup_compare_method_id_ = + if (dbji->dup_compare_method_id == NULL) { + if ((dup_compare_class = + get_class(jnienv, name_DbDupCompare)) == NULL) + return; /* An exception has been posted. */ + dbji->dup_compare_method_id = (*jnienv)->GetMethodID(jnienv, dup_compare_class, "dup_compare", "(Lcom/sleepycat/db/Db;" "Lcom/sleepycat/db/Dbt;" "Lcom/sleepycat/db/Dbt;)I"); - if (dbji->dup_compare_method_id_ == NULL) { - /* XXX + if (dbji->dup_compare_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -896,15 +1030,15 @@ void dbji_set_dup_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->dup_compare_ != NULL) - DELETE_GLOBAL_REF(jnienv, dbji->dup_compare_); + if (dbji->dup_compare != NULL) + DELETE_GLOBAL_REF(jnienv, dbji->dup_compare); if (jcompare == NULL) db->set_dup_compare(db, NULL); else db->set_dup_compare(db, Db_dup_compare_callback); - dbji->dup_compare_ = NEW_GLOBAL_REF(jnienv, jcompare); + dbji->dup_compare = NEW_GLOBAL_REF(jnienv, jcompare); } int dbji_call_dup_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, @@ -912,7 +1046,6 @@ int dbji_call_dup_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, { JNIEnv *jnienv; jobject jdbt1, jdbt2; - DBT_JAVAINFO *dbtji1, *dbtji2; COMPQUIET(db, NULL); jnienv = dbji_get_jnienv(dbji); @@ -921,25 +1054,12 @@ int dbji_call_dup_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb, return (0); } - /* XXX - * We should have a pool of Dbt objects used for this purpose - * instead of creating new ones each time. Because of - * multithreading, we may need an arbitrary number (more than two). - * We might also have a byte arrays that grow as needed, - * so we don't need to allocate those either. - */ - jdbt1 = create_default_object(jnienv, name_DBT); - jdbt2 = create_default_object(jnienv, name_DBT); - dbtji1 = get_DBT_JAVAINFO(jnienv, jdbt1); - memcpy(&dbtji1->dbt, dbt1, sizeof(DBT)); - dbtji1->create_array_ = 1; - dbtji2 = get_DBT_JAVAINFO(jnienv, jdbt2); - memcpy(&dbtji2->dbt, dbt2, sizeof(DBT)); - dbtji2->create_array_ = 1; - - DB_ASSERT(dbji->dup_compare_method_id_ != NULL); - return (*jnienv)->CallIntMethod(jnienv, dbji->dup_compare_, - dbji->dup_compare_method_id_, + jdbt1 = get_const_Dbt(jnienv, dbt1, NULL); + jdbt2 = get_const_Dbt(jnienv, dbt2, NULL); + + DB_ASSERT(dbji->dup_compare_method_id != NULL); + return (*jnienv)->CallIntMethod(jnienv, dbji->dup_compare, + dbji->dup_compare_method_id, jdb, jdbt1, jdbt2); } @@ -948,15 +1068,18 @@ void dbji_set_h_hash_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, { jclass h_hash_class; - if (dbji->h_hash_method_id_ == NULL) { - h_hash_class = get_class(jnienv, name_DbHash); - dbji->h_hash_method_id_ = + if (dbji->h_hash_method_id == NULL) { + if ((h_hash_class = + get_class(jnienv, name_DbHash)) == NULL) + return; /* An exception has been posted. */ + dbji->h_hash_method_id = (*jnienv)->GetMethodID(jnienv, h_hash_class, "hash", "(Lcom/sleepycat/db/Db;" "[BI)I"); - if (dbji->h_hash_method_id_ == NULL) { - /* XXX + if (dbji->h_hash_method_id == NULL) { + /* + * XXX * We should really have a better way * to translate this to a Java exception class. * In theory, it shouldn't happen. @@ -967,22 +1090,22 @@ void dbji_set_h_hash_object(DB_JAVAINFO *dbji, JNIEnv *jnienv, } } - if (dbji->h_hash_ != NULL) - DELETE_GLOBAL_REF(jnienv, dbji->h_hash_); + if (dbji->h_hash != NULL) + DELETE_GLOBAL_REF(jnienv, dbji->h_hash); if (jhash == NULL) db->set_h_hash(db, NULL); else db->set_h_hash(db, Db_h_hash_callback); - dbji->h_hash_ = NEW_GLOBAL_REF(jnienv, jhash); + dbji->h_hash = NEW_GLOBAL_REF(jnienv, jhash); } int dbji_call_h_hash(DB_JAVAINFO *dbji, DB *db, jobject jdb, const void *data, int len) { JNIEnv *jnienv; - jbyteArray jarray; + jbyteArray jdata; COMPQUIET(db, NULL); jnienv = dbji_get_jnienv(dbji); @@ -991,11 +1114,12 @@ int dbji_call_h_hash(DB_JAVAINFO *dbji, DB *db, jobject jdb, return (0); } - DB_ASSERT(dbji->h_hash_method_id_ != NULL); + DB_ASSERT(dbji->h_hash_method_id != NULL); - jarray = (*jnienv)->NewByteArray(jnienv, len); - (*jnienv)->SetByteArrayRegion(jnienv, jarray, 0, len, (void *)data); - return (*jnienv)->CallIntMethod(jnienv, dbji->h_hash_, - dbji->h_hash_method_id_, - jdb, jarray, len); + if ((jdata = (*jnienv)->NewByteArray(jnienv, len)) == NULL) + return (0); /* An exception has been posted by the JVM */ + (*jnienv)->SetByteArrayRegion(jnienv, jdata, 0, len, (void *)data); + return (*jnienv)->CallIntMethod(jnienv, dbji->h_hash, + dbji->h_hash_method_id, + jdb, jdata, len); } |