Import BSDDB 4.7.25 (as of svn r89086)

This commit is contained in:
Zachary Ware
2017-09-04 13:40:25 -05:00
parent 4b29e0458f
commit 8f590873d0
4781 changed files with 2241032 additions and 6 deletions

190
libdb_java/README Normal file
View File

@@ -0,0 +1,190 @@
Berkeley DB's Java API
$Id: README,v 12.2 2006/08/24 14:46:10 bostic Exp $
Berkeley DB's Java API is now generated with SWIG
(http://www.swig.org). This document describes how SWIG is used -
what we trust it to do, what things we needed to work around.
Overview
========
SWIG is a tool that generates wrappers around native (C/C++) APIs for
various languages (mainly scripting languages) including Java.
By default, SWIG creates an API in the target language that exactly
replicates the native API (for example, each pointer type in the API
is wrapped as a distinct type in the language). Although this
simplifies the wrapper layer (type translation is trivial), it usually
doesn't result in natural API in the target language.
A further constraint for Berkeley DB's Java API was backwards
compatibility. The original hand-coded Java API is in widespread use,
and included many design decisions about how native types should be
represented in Java. As an example, callback functions are
represented by Java interfaces that applications using Berkeley DB
could implement. The SWIG implementation was required to maintain
backwards compatibility for those applications.
Running SWIG
============
The simplest use of SWIG is to simply run it with a C include file as
input. SWIG parses the file and generates wrapper code for the target
language. For Java, this includes a Java class for each C struct and
a C source file containing the Java Native Interface (JNI) function
calls for each native method.
The s_swig shell script in db/dist runs SWIG, and then post-processes
each Java source file with the sed commands in
libdb_java/java-post.sed. The Java sources are placed in
java/src/com/sleepycat/db, and the native wrapper code is in a single
file in libdb_java/db_java_wrap.c.
The post-processing step modifies code in ways that is difficult with
SWIG (given my current level of knowledge). This includes changing
some access modifiers to hide some of the implementation methods,
selectively adding "throws" clauses to methods, and adding calls to
"initialize" methods in Db and DbEnv after they are constructed (more
below on what these aclls do).
In addition to the source code generated by SWIG, some of the Java
classes are written by hand, and constants and code to fill statistics
structures are generated by the script dist/s_java. The native
statistics code is in libdb_java/java_stat_auto.c, and is compiled
into the db_java_wrap object file with a #include directive. This
allows most functions in that object to be static, which encourages
compiler inlining and reduces the number of symbols we export.
The Implementation
==================
For the reasons mentioned above, Berkeley DB requires a more
sophisticated mapping between the native API and Java, so additional
SWIG directives are added to the input. In particular:
* The general intention is for db.i to contain the full DB API (just
like db.h). As much as possible, this file is kept Java independent
so that it can be updated easily when the API changes. SWIG doesn't
have any builtin rules for how to handle function pointers in a
struct, so each DB method must be added in a SWIG "%extend" block
which includes the method signature and a call to the method.
* SWIG's automatically generated function names happen to collide
with Berkeley DB's naming convention. For example, in a SWIG class
called __db, a method called "open" would result in a wrapper
function called "__db_open", which already exists in DB. This is
another reason why making these static functions is important.
* The main Java support starts in db_java.i - this file includes all
Java code that is explicitly inserted into the generated classes,
and is responsible for defining object lifecycles (handling
allocation and cleanup).
* Methods that need to be wrapped for special handling in Java code
are renamed with a trailing zero (e.g., close becomes close0).
This is invisible to applications.
* Most DB classes that are wrapped have method calls that imply the
cleanup of any native resources associated with the Java object
(for example, Db.close or DbTxn.abort). These methods are wrapped
so that if the object is accessed after the native part has been
destroyed, an exception is thrown rather than a trap that crashes
the JVM.
* Db and DbEnv initialization is more complex: a global reference is
stored in the corresponding struct so that native code can
efficiently map back to Java code. In addition, if a Db is
created without an environment (i.e., in a private environment),
the initialization wraps the internal DbEnv to simplify handling
of various Db methods that just call the corresponding DbEnv
method (like err, errx, etc.). It is important that the global
references are cleaned up before the DB and DB_ENV handles are
closed, so the Java objects can be garbage collected.
* In the case of DbLock and DbLsn, there are no such methods. In
these cases, there is a finalize method that does the appropriate
cleanup. No other classes have finalize methods (in particular,
the Dbt class is now implemented entirely in Java, so no
finalization is necessary).
* Overall initialization code, including the System.loadLibrary call,
is in java_util.i. This includes looking up all class, field and
method handles once so that execution is not slowed down by repeated
runtime type queries.
* Exception handling is in java_except.i. The main non-obvious design
choice was to create a db_ret_t type for methods that return an
error code as an int in the C API, but return void in the Java API
(and throw exceptions on error).
* The only other odd case with exceptions is DbMemoryException -
this is thrown as normal when a call returns ENOMEM, but there is
special handling for the case where a Dbt with DB_DBT_USERMEM is
not big enough to handle a result: in this case, the Dbt handling
code calls the method update_dbt on the exception that is about to
be thrown to register the failed Dbt in the exception.
* Statistics handling is in java_stat.i - this mainly just hooks into
the automatically-generated code in java_stat_auto.c.
* Callbacks: the general approach is that Db and DbEnv maintain
references to the objects that handle each callback, and have a
helper method for each call. This is primarily to simplify the
native code, and performs better than more complex native code.
* One difference with the new approach is that the implementation is
more careful about calling DeleteLocalRef on objects created for
callbacks. This is particularly important for callbacks like
bt_compare, which may be called repeatedly from native code.
Without the DeleteLocalRef calls, the Java objects that are
created can not be collected until the original call returns.
* Most of the rest of the code is in java_typemaps.i. A typemap is a
rule describing how a native type is mapped onto a Java type for
parameters and return values. These handle most of the complexity
of creating exactly the Java API we want.
* One of the main areas of complexity is Dbt handling. The approach
taken is to accept whatever data is passed in by the application,
pass that to native code, and reflect any changes to the native
DBT back into the Java object. In other words, the Dbt typemaps
don't replicate DB's rules about whether Dbts will be modified or
not - they just pass the data through.
* As noted above, when a Dbt is "released" (i.e., no longer needed
in native code), one of the check is whether a DbMemoryException
is pending, and if so, whether this Dbt might be the cause. In
that case, the Dbt is added to the exception via the "update_dbt"
method.
* Constant handling has been simplified by making DbConstants an
interface. This allows the Db class to inherit the constants, and
most can be inlined by javac.
* The danger here is if applications are compiled against one
version of db.jar, but run against another. This danger existed
previously, but was partly ameliorated by a separation of
constants into "case" and "non-case" constants (the non-case
constants were arranged so they could not be inlined). The only
complete solution to this problem is for applications to check the
version returned by DbEnv.get_version* versus the Db.DB_VERSION*
constants.
Application-visible changes
===========================
* The new API is around 5x faster for many operations.
* Some internal methods and constructors that were previously public
have been hidden or removed.
* A few methods that were inconsistent have been cleaned up (e.g.,
Db.close now returns void, was an int but always zero). The
synchronized attributed has been toggled on some methods - this is
an attempt to prevent multi-threaded applications shooting
themselves in the foot by calling close() or similar methods
concurrently from multiple threads.

1690
libdb_java/db.i Normal file

File diff suppressed because it is too large Load Diff

703
libdb_java/db_java.i Normal file
View File

@@ -0,0 +1,703 @@
%module db_java
%include "various.i"
%include "typemaps.i"
%include "java_util.i"
%include "java_except.i"
%include "java_typemaps.i"
%include "java_stat.i"
%include "java_callbacks.i"
/*
* No finalize methods in general - most classes have "destructor" methods
* that applications must call explicitly.
*/
%typemap(javafinalize) SWIGTYPE ""
/*
* These are the exceptions - when there is no "close" method, we need to free
* the native part at finalization time. These are exactly the cases where C
* applications manage the memory for the handles.
*/
%typemap(javafinalize) struct DbLsn, struct DbLock %{
protected void finalize() {
try {
delete();
} catch(Exception e) {
System.err.println("Exception during finalization: " + e);
e.printStackTrace(System.err);
}
}
%}
%typemap(javaimports) SWIGTYPE %{
import com.sleepycat.db.*;
import java.util.Comparator;
%}
/* Class names */
%rename(LogSequenceNumber) DbLsn;
/* Destructors */
%rename(close0) close;
%rename(remove0) remove;
%rename(rename0) rename;
%rename(verify0) verify;
%rename(abort0) abort;
%rename(commit0) commit;
%rename(discard0) discard;
/* Special case methods */
%rename(set_tx_timestamp0) set_tx_timestamp;
/* Extra code in the Java classes */
%typemap(javacode) struct DbEnv %{
/*
* Internally, the JNI layer creates a global reference to each DbEnv,
* which can potentially be different to this. We keep a copy here so
* we can clean up after destructors.
*/
private long dbenv_ref;
public Environment wrapper;
private LogRecordHandler app_dispatch_handler;
private EventHandler event_notify_handler;
private FeedbackHandler env_feedback_handler;
private ErrorHandler error_handler;
private String errpfx;
private MessageHandler message_handler;
private PanicHandler panic_handler;
private ReplicationTransport rep_transport_handler;
private java.io.OutputStream error_stream;
private java.io.OutputStream message_stream;
private ThreadLocal errBuf;
public static class RepProcessMessage {
public int envid;
}
/*
* Called by the public DbEnv constructor and for private environments
* by the Db constructor.
*/
void initialize() {
dbenv_ref = db_java.initDbEnvRef0(this, this);
errBuf = new ThreadLocal();
/* Start with System.err as the default error stream. */
set_error_stream(System.err);
set_message_stream(System.out);
}
void cleanup() {
swigCPtr = 0;
db_java.deleteRef0(dbenv_ref);
dbenv_ref = 0L;
}
public synchronized void close(int flags) throws DatabaseException {
try {
close0(flags);
} finally {
cleanup();
}
}
private final int handle_app_dispatch(DatabaseEntry dbt,
LogSequenceNumber lsn,
int recops) {
return app_dispatch_handler.handleLogRecord(wrapper, dbt, lsn,
RecoveryOperation.fromFlag(recops));
}
public LogRecordHandler get_app_dispatch() {
return app_dispatch_handler;
}
private final void handle_panic_event_notify() {
event_notify_handler.handlePanicEvent();
}
private final void handle_rep_client_event_notify() {
event_notify_handler.handleRepClientEvent();
}
private final void handle_rep_elected_event_notify() {
event_notify_handler.handleRepElectedEvent();
}
private final void handle_rep_master_event_notify() {
event_notify_handler.handleRepMasterEvent();
}
private final void handle_rep_new_master_event_notify(int envid) {
event_notify_handler.handleRepNewMasterEvent(envid);
}
private final void handle_rep_perm_failed_event_notify() {
event_notify_handler.handleRepPermFailedEvent();
}
private final void handle_rep_startup_done_event_notify() {
event_notify_handler.handleRepStartupDoneEvent();
}
private final void handle_write_failed_event_notify(int errno) {
event_notify_handler.handleWriteFailedEvent(errno);
}
public EventHandler get_event_notify() {
return event_notify_handler;
}
private final void handle_env_feedback(int opcode, int percent) {
if (opcode == DbConstants.DB_RECOVER)
env_feedback_handler.recoveryFeedback(wrapper, percent);
/* No other environment feedback type supported. */
}
public FeedbackHandler get_feedback() {
return env_feedback_handler;
}
public void set_errpfx(String errpfx) {
this.errpfx = errpfx;
}
public String get_errpfx() {
return errpfx;
}
private final void handle_error(String msg) {
com.sleepycat.util.ErrorBuffer ebuf = (com.sleepycat.util.ErrorBuffer)errBuf.get();
if (ebuf == null) {
/*
* Populate the errBuf ThreadLocal on demand, since the
* callback can be made from different threads.
*/
ebuf = new com.sleepycat.util.ErrorBuffer(3);
errBuf.set(ebuf);
}
ebuf.append(msg);
error_handler.error(wrapper, this.errpfx, msg);
}
private final String get_err_msg(String orig_msg) {
com.sleepycat.util.ErrorBuffer ebuf = (com.sleepycat.util.ErrorBuffer)errBuf.get();
String ret = null;
if (ebuf != null) {
ret = ebuf.get();
ebuf.clear();
}
if (ret != null && ret.length() > 0)
return orig_msg + ": " + ret;
return orig_msg;
}
public ErrorHandler get_errcall() {
return error_handler;
}
private final void handle_message(String msg) {
message_handler.message(wrapper, msg);
}
public MessageHandler get_msgcall() {
return message_handler;
}
private final void handle_panic(DatabaseException e) {
panic_handler.panic(wrapper, e);
}
public PanicHandler get_paniccall() {
return panic_handler;
}
private final int handle_rep_transport(DatabaseEntry control,
DatabaseEntry rec,
LogSequenceNumber lsn,
int envid, int flags)
throws DatabaseException {
return rep_transport_handler.send(wrapper,
control, rec, lsn, envid,
(flags & DbConstants.DB_REP_NOBUFFER) != 0,
(flags & DbConstants.DB_REP_PERMANENT) != 0,
(flags & DbConstants.DB_REP_ANYWHERE) != 0,
(flags & DbConstants.DB_REP_REREQUEST) != 0);
}
public void lock_vec(/*u_int32_t*/ int locker, int flags,
LockRequest[] list, int offset, int count)
throws DatabaseException {
db_javaJNI.DbEnv_lock_vec(swigCPtr, this, locker, flags, list,
offset, count);
}
public synchronized void remove(String db_home, int flags)
throws DatabaseException, java.io.FileNotFoundException {
try {
remove0(db_home, flags);
} finally {
cleanup();
}
}
public void set_error_stream(java.io.OutputStream stream) {
error_stream = stream;
final java.io.PrintWriter pw = new java.io.PrintWriter(stream);
set_errcall(new ErrorHandler() {
public void error(Environment env,
String prefix, String buf) /* no exception */ {
if (prefix != null)
pw.print(prefix + ": ");
pw.println(buf);
pw.flush();
}
});
}
public java.io.OutputStream get_error_stream() {
return error_stream;
}
public void set_message_stream(java.io.OutputStream stream) {
message_stream = stream;
final java.io.PrintWriter pw = new java.io.PrintWriter(stream);
set_msgcall(new MessageHandler() {
public void message(Environment env, String msg)
/* no exception */ {
pw.println(msg);
pw.flush();
}
});
}
public java.io.OutputStream get_message_stream() {
return message_stream;
}
public void set_tx_timestamp(java.util.Date timestamp) {
set_tx_timestamp0(timestamp.getTime()/1000);
}
%}
%typemap(javacode) struct Db %{
/* package */ static final int GIGABYTE = 1 << 30;
/*
* Internally, the JNI layer creates a global reference to each Db,
* which can potentially be different to this. We keep a copy here so
* we can clean up after destructors.
*/
private long db_ref;
private DbEnv dbenv;
private boolean private_dbenv;
public Database wrapper;
private RecordNumberAppender append_recno_handler;
private Comparator bt_compare_handler;
private BtreePrefixCalculator bt_prefix_handler;
private Comparator dup_compare_handler;
private FeedbackHandler db_feedback_handler;
private Comparator h_compare_handler;
private Hasher h_hash_handler;
private SecondaryKeyCreator seckey_create_handler;
private SecondaryMultiKeyCreator secmultikey_create_handler;
private ForeignKeyNullifier foreignkey_nullify_handler;
private ForeignMultiKeyNullifier foreignmultikey_nullify_handler;
/* Called by the Db constructor */
private void initialize(DbEnv dbenv) {
if (dbenv == null) {
private_dbenv = true;
dbenv = db_java.getDbEnv0(this);
dbenv.initialize();
}
this.dbenv = dbenv;
db_ref = db_java.initDbRef0(this, this);
}
private void cleanup() {
swigCPtr = 0;
db_java.deleteRef0(db_ref);
db_ref = 0L;
if (private_dbenv)
dbenv.cleanup();
dbenv = null;
}
public boolean getPrivateDbEnv() {
return private_dbenv;
}
public synchronized void close(int flags) throws DatabaseException {
try {
close0(flags);
} finally {
cleanup();
}
}
public DbEnv get_env() throws DatabaseException {
return dbenv;
}
private final void handle_append_recno(DatabaseEntry data, int recno)
throws DatabaseException {
append_recno_handler.appendRecordNumber(wrapper, data, recno);
}
public RecordNumberAppender get_append_recno() {
return append_recno_handler;
}
private final int handle_bt_compare(byte[] arr1, byte[] arr2) {
return bt_compare_handler.compare(arr1, arr2);
}
public Comparator get_bt_compare() {
return bt_compare_handler;
}
private final int handle_bt_prefix(DatabaseEntry dbt1,
DatabaseEntry dbt2) {
return bt_prefix_handler.prefix(wrapper, dbt1, dbt2);
}
public BtreePrefixCalculator get_bt_prefix() {
return bt_prefix_handler;
}
private final void handle_db_feedback(int opcode, int percent) {
if (opcode == DbConstants.DB_UPGRADE)
db_feedback_handler.upgradeFeedback(wrapper, percent);
else if (opcode == DbConstants.DB_VERIFY)
db_feedback_handler.upgradeFeedback(wrapper, percent);
/* No other database feedback types known. */
}
public FeedbackHandler get_feedback() {
return db_feedback_handler;
}
private final int handle_h_compare(byte[] arr1, byte[] arr2) {
return h_compare_handler.compare(arr1, arr2);
}
public Comparator get_h_compare() {
return h_compare_handler;
}
private final int handle_dup_compare(byte[] arr1, byte[] arr2) {
return dup_compare_handler.compare(arr1, arr2);
}
public Comparator get_dup_compare() {
return dup_compare_handler;
}
private final int handle_h_hash(byte[] data, int len) {
return h_hash_handler.hash(wrapper, data, len);
}
public Hasher get_h_hash() {
return h_hash_handler;
}
private final boolean handle_foreignkey_nullify(
DatabaseEntry key,
DatabaseEntry data,
DatabaseEntry seckey)
throws DatabaseException {
if (foreignmultikey_nullify_handler != null)
return foreignmultikey_nullify_handler.nullifyForeignKey(
(SecondaryDatabase)wrapper, key, data, seckey);
else
return foreignkey_nullify_handler.nullifyForeignKey(
(SecondaryDatabase)wrapper, data);
}
private final DatabaseEntry[] handle_seckey_create(
DatabaseEntry key,
DatabaseEntry data)
throws DatabaseException {
if (secmultikey_create_handler != null) {
java.util.HashSet keySet = new java.util.HashSet();
secmultikey_create_handler.createSecondaryKeys(
(SecondaryDatabase)wrapper, key, data, keySet);
if (!keySet.isEmpty())
return (DatabaseEntry[])keySet.toArray(
new DatabaseEntry[keySet.size()]);
} else {
DatabaseEntry result = new DatabaseEntry();
if (seckey_create_handler.createSecondaryKey(
(SecondaryDatabase)wrapper, key, data, result)) {
DatabaseEntry[] results = { result };
return results;
}
}
return null;
}
public SecondaryKeyCreator get_seckey_create() {
return seckey_create_handler;
}
public SecondaryMultiKeyCreator get_secmultikey_create() {
return secmultikey_create_handler;
}
public void set_secmultikey_create(
SecondaryMultiKeyCreator secmultikey_create_handler) {
this.secmultikey_create_handler = secmultikey_create_handler;
}
public void set_foreignmultikey_nullifier(ForeignMultiKeyNullifier nullify){
this.foreignmultikey_nullify_handler = nullify;
}
public synchronized void remove(String file, String database, int flags)
throws DatabaseException, java.io.FileNotFoundException {
try {
remove0(file, database, flags);
} finally {
cleanup();
}
}
public synchronized void rename(String file, String database,
String newname, int flags)
throws DatabaseException, java.io.FileNotFoundException {
try {
rename0(file, database, newname, flags);
} finally {
cleanup();
}
}
public synchronized boolean verify(String file, String database,
java.io.OutputStream outfile, int flags)
throws DatabaseException, java.io.FileNotFoundException {
try {
return verify0(file, database, outfile, flags);
} finally {
cleanup();
}
}
public ErrorHandler get_errcall() {
return dbenv.get_errcall();
}
public void set_errcall(ErrorHandler db_errcall_fcn) {
dbenv.set_errcall(db_errcall_fcn);
}
public java.io.OutputStream get_error_stream() {
return dbenv.get_error_stream();
}
public void set_error_stream(java.io.OutputStream stream) {
dbenv.set_error_stream(stream);
}
public void set_errpfx(String errpfx) {
dbenv.set_errpfx(errpfx);
}
public String get_errpfx() {
return dbenv.get_errpfx();
}
public java.io.OutputStream get_message_stream() {
return dbenv.get_message_stream();
}
public void set_message_stream(java.io.OutputStream stream) {
dbenv.set_message_stream(stream);
}
public MessageHandler get_msgcall() {
return dbenv.get_msgcall();
}
public void set_msgcall(MessageHandler db_msgcall_fcn) {
dbenv.set_msgcall(db_msgcall_fcn);
}
public void set_paniccall(PanicHandler db_panic_fcn)
throws DatabaseException {
dbenv.set_paniccall(db_panic_fcn);
}
public PanicHandler get_paniccall() {
return dbenv.get_paniccall();
}
%}
%typemap(javacode) struct Dbc %{
public synchronized void close() throws DatabaseException {
try {
close0();
} finally {
swigCPtr = 0;
}
}
%}
%typemap(javacode) struct DbLock %{
public Lock wrapper;
%}
%typemap(javacode) struct DbLogc %{
public synchronized void close(int flags) throws DatabaseException {
try {
close0(flags);
} finally {
swigCPtr = 0;
}
}
%}
%typemap(javacode) struct DbSequence %{
public Sequence wrapper;
public synchronized void close(int flags) throws DatabaseException {
try {
close0(flags);
} finally {
swigCPtr = 0;
}
}
public synchronized void remove(DbTxn txn, int flags)
throws DatabaseException {
try {
remove0(txn, flags);
} finally {
swigCPtr = 0;
}
}
%}
%typemap(javacode) struct DbTxn %{
public void abort() throws DatabaseException {
try {
abort0();
} finally {
swigCPtr = 0;
}
}
public void commit(int flags) throws DatabaseException {
try {
commit0(flags);
} finally {
swigCPtr = 0;
}
}
public void discard(int flags) throws DatabaseException {
try {
discard0(flags);
} finally {
swigCPtr = 0;
}
}
/*
* We override Object.equals because it is possible for the Java API to
* create multiple DbTxns that reference the same underlying object.
* This can happen for example during DbEnv.txn_recover().
*/
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj != null && (obj instanceof DbTxn)) {
DbTxn that = (DbTxn)obj;
return (this.swigCPtr == that.swigCPtr);
}
return false;
}
/*
* We must override Object.hashCode whenever we override
* Object.equals() to enforce the maxim that equal objects have the
* same hashcode.
*/
public int hashCode()
{
return ((int)swigCPtr ^ (int)(swigCPtr >> 32));
}
%}
%native(initDbEnvRef0) jlong initDbEnvRef0(DB_ENV *self, void *handle);
%native(initDbRef0) jlong initDbRef0(DB *self, void *handle);
%native(deleteRef0) void deleteRef0(jlong ref);
%native(getDbEnv0) DB_ENV *getDbEnv0(DB *self);
%{
SWIGEXPORT jlong JNICALL
Java_com_sleepycat_db_internal_db_1javaJNI_initDbEnvRef0(
JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) {
DB_ENV *self = *(DB_ENV **)(void *)&jarg1;
jlong ret;
COMPQUIET(jcls, NULL);
COMPQUIET(jarg1_, NULL);
DB_ENV_INTERNAL(self) = (void *)(*jenv)->NewGlobalRef(jenv, jarg2);
*(jobject *)(void *)&ret = (jobject)DB_ENV_INTERNAL(self);
return (ret);
}
SWIGEXPORT jlong JNICALL
Java_com_sleepycat_db_internal_db_1javaJNI_initDbRef0(
JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jobject jarg2) {
DB *self = *(DB **)(void *)&jarg1;
jlong ret;
COMPQUIET(jcls, NULL);
COMPQUIET(jarg1_, NULL);
DB_INTERNAL(self) = (void *)(*jenv)->NewGlobalRef(jenv, jarg2);
*(jobject *)(void *)&ret = (jobject)DB_INTERNAL(self);
return (ret);
}
SWIGEXPORT void JNICALL
Java_com_sleepycat_db_internal_db_1javaJNI_deleteRef0(
JNIEnv *jenv, jclass jcls, jlong jarg1) {
jobject jref = *(jobject *)(void *)&jarg1;
COMPQUIET(jcls, NULL);
if (jref != 0L)
(*jenv)->DeleteGlobalRef(jenv, jref);
}
SWIGEXPORT jlong JNICALL
Java_com_sleepycat_db_internal_db_1javaJNI_getDbEnv0(
JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) {
DB *self = *(DB **)(void *)&jarg1;
jlong ret;
COMPQUIET(jenv, NULL);
COMPQUIET(jcls, NULL);
COMPQUIET(jarg1_, NULL);
*(DB_ENV **)(void *)&ret = self->dbenv;
return (ret);
}
SWIGEXPORT jboolean JNICALL
Java_com_sleepycat_db_internal_DbUtil_is_1big_1endian(
JNIEnv *jenv, jclass clazz)
{
COMPQUIET(jenv, NULL);
COMPQUIET(clazz, NULL);
return (__db_isbigendian() ? JNI_TRUE : JNI_FALSE);
}
%}

10741
libdb_java/db_java_wrap.c Normal file

File diff suppressed because it is too large Load Diff

23
libdb_java/java-post.pl Normal file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env perl -p
# Hide some symbols
s!public (class db_java|[^(]* delete|[^(]* [A-Za-z_]*0\()!/* package */ $1!;
# Mark methods that don't throw exceptions
s!public [^(]*get_version_[a-z]*\([^)]*\)!$& /* no exception */!;
s!public [^(]*[ _]err[a-z_]*\([^)]*\)!$& /* no exception */!;
s!public [^(]*[ _]msg[a-z_]*\([^)]*\)!$& /* no exception */!;
s!public [^(]*[ _]message[a-z_]*\([^)]*\)!$& /* no exception */!;
s!public [^(]*[ _]strerror\([^)]*\)!$& /* no exception */!;
s!public [^(]*log_compare\([^)]*\)!$& /* no exception */!;
s!public [^(]* feedback\([^)]*\)!$& /* no exception */!;
# Mark methods that throw special exceptions
m/DbSequence/ || s!(public [^(]*(open|remove|rename)0?\([^)]*\))( {|;)!$1 throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException$3!;
# Everything else throws a DbException
s!(public [^(]*\([^)]*\))(;| {)!$1 throws com.sleepycat.db.DatabaseException$2!;
# Add initialize methods for Java parts of Db and DbEnv
s!\.new_DbEnv\(.*$!$&\n initialize();!;
s!\.new_Db\(.*$!$&\n initialize(dbenv);!;

663
libdb_java/java_callbacks.i Normal file
View File

@@ -0,0 +1,663 @@
/* Callbacks */
%define JAVA_CALLBACK(_sig, _jclass, _name)
JAVA_TYPEMAP(_sig, _jclass, jboolean)
%typemap(jtype) _sig "boolean"
%typemap(javain) _sig %{ (_name##_handler = $javainput) != null %}
/*
* The Java object is stored in the Db or DbEnv class.
* Here we only care whether it is non-NULL.
*/
%typemap(in) _sig %{
$1 = ($input == JNI_TRUE) ? __dbj_##_name : NULL;
%}
%enddef
%{
static void __dbj_error(const DB_ENV *dbenv,
const char *prefix, const char *msg)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
jobject jmsg;
COMPQUIET(prefix, NULL);
if (jdbenv != NULL){
jmsg = (*jenv)->NewStringUTF(jenv, msg);
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class,
errcall_method, jmsg);
(*jenv)->DeleteLocalRef(jenv, jmsg);
}
}
static void __dbj_env_feedback(DB_ENV *dbenv, int opcode, int percent)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
if (jdbenv != NULL)
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class,
env_feedback_method, opcode, percent);
}
static void __dbj_message(const DB_ENV *dbenv, const char *msg)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
jobject jmsg;
if (jdbenv != NULL){
jmsg = (*jenv)->NewStringUTF(jenv, msg);
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class,
msgcall_method, jmsg);
(*jenv)->DeleteLocalRef(jenv, jmsg);
}
}
static void __dbj_panic(DB_ENV *dbenv, int err)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
if (jdbenv != NULL)
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv, dbenv_class,
paniccall_method,
__dbj_get_except(jenv, err, NULL, NULL, jdbenv));
}
static int __dbj_app_dispatch(DB_ENV *dbenv,
DBT *dbt, DB_LSN *lsn, db_recops recops)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
jobject jdbt, jlsn;
jbyteArray jdbtarr;
int ret;
if (jdbenv == NULL)
return (EINVAL);
jdbt = (*jenv)->NewObject(jenv, dbt_class, dbt_construct);
__dbj_dbt_copyout(jenv, dbt, &jdbtarr, jdbt);
if (jdbt == NULL)
return (ENOMEM); /* An exception is pending */
jlsn = (lsn == NULL) ? NULL : __dbj_wrap_DB_LSN(jenv, lsn);
ret = (*jenv)->CallNonvirtualIntMethod(jenv, jdbenv, dbenv_class,
app_dispatch_method, jdbt, jlsn, recops);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
}
(*jenv)->DeleteLocalRef(jenv, jdbtarr);
(*jenv)->DeleteLocalRef(jenv, jdbt);
if (jlsn != NULL)
(*jenv)->DeleteLocalRef(jenv, jlsn);
return (ret);
}
static void __dbj_event_notify(DB_ENV *dbenv, u_int32_t event_id, void * info)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
if (jdbenv == NULL)
return ;
switch (event_id) {
case DB_EVENT_PANIC:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, panic_event_notify_method);
break;
case DB_EVENT_REP_CLIENT:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_client_event_notify_method);
break;
case DB_EVENT_REP_ELECTED:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_elected_event_notify_method);
break;
case DB_EVENT_REP_MASTER:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_master_event_notify_method);
break;
case DB_EVENT_REP_NEWMASTER:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_new_master_event_notify_method,
*(int*)info);
break;
case DB_EVENT_REP_PERM_FAILED:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_perm_failed_event_notify_method);
break;
case DB_EVENT_REP_STARTUPDONE:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, rep_startup_done_event_notify_method);
break;
case DB_EVENT_WRITE_FAILED:
(*jenv)->CallNonvirtualVoidMethod(jenv, jdbenv,
dbenv_class, write_failed_event_notify_method,
*(int*)info);
break;
default:
dbenv->errx(dbenv, "Unhandled event callback in the Java API");
DB_ASSERT(dbenv->env, 0);
}
}
static int __dbj_rep_transport(DB_ENV *dbenv,
const DBT *control, const DBT *rec, const DB_LSN *lsn, int envid,
u_int32_t flags)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdbenv = (jobject)DB_ENV_INTERNAL(dbenv);
jobject jcontrol, jrec, jlsn;
jbyteArray jcontrolarr, jrecarr;
int ret;
if (jdbenv == NULL)
return (EINVAL);
jcontrol = (*jenv)->NewObject(jenv, dbt_class, dbt_construct);
jrec = (*jenv)->NewObject(jenv, dbt_class, dbt_construct);
if (jcontrol == NULL || jrec == NULL)
return (ENOMEM); /* An exception is pending */
__dbj_dbt_copyout(jenv, control, &jcontrolarr, jcontrol);
__dbj_dbt_copyout(jenv, rec, &jrecarr, jrec);
jlsn = (lsn == NULL) ? NULL : __dbj_wrap_DB_LSN(jenv, (DB_LSN *)lsn);
if (jcontrolarr == NULL || jrecarr == NULL)
return (ENOMEM); /* An exception is pending */
ret = (*jenv)->CallNonvirtualIntMethod(jenv, jdbenv, dbenv_class,
rep_transport_method, jcontrol, jrec, jlsn, envid, flags);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
}
(*jenv)->DeleteLocalRef(jenv, jrecarr);
(*jenv)->DeleteLocalRef(jenv, jcontrolarr);
(*jenv)->DeleteLocalRef(jenv, jrec);
(*jenv)->DeleteLocalRef(jenv, jcontrol);
if (jlsn != NULL)
(*jenv)->DeleteLocalRef(jenv, jlsn);
return (ret);
}
static int __dbj_foreignkey_nullify(DB *db,
const DBT *key, DBT *data, const DBT *skey, int *changed)
{
DBT_LOCKED lresult;
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jobject jkey, jdata, jskey;
jbyteArray jkeyarr, jdataarr, jskeyarr;
jboolean jresult;
int ret;
if (jdb == NULL)
return (EINVAL);
jkey = (key->app_data != NULL) ?
((DBT_LOCKED *)key->app_data)->jdbt :
(*jenv)->NewObject(jenv, dbt_class, dbt_construct);
jdata = (data->app_data != NULL) ?
((DBT_LOCKED *)data->app_data)->jdbt :
(*jenv)->NewObject(jenv, dbt_class, dbt_construct);
jskey = (skey->app_data != NULL) ?
((DBT_LOCKED *)skey->app_data)->jdbt :
(*jenv)->NewObject(jenv, dbt_class, dbt_construct);
if (jkey == NULL || jdata == NULL || jskey == NULL)
return (ENOMEM); /* An exception is pending */
if (key->app_data == NULL) {
__dbj_dbt_copyout(jenv, key, &jkeyarr, jkey);
if (jkeyarr == NULL)
return (ENOMEM); /* An exception is pending */
}
if (data->app_data == NULL) {
__dbj_dbt_copyout(jenv, data, &jdataarr, jdata);
if (jdataarr == NULL)
return (ENOMEM); /* An exception is pending */
}
if (skey->app_data == NULL) {
__dbj_dbt_copyout(jenv, skey, &jskeyarr, jskey);
if (jskeyarr == NULL)
return (ENOMEM); /* An exception is pending */
}
jresult = (*jenv)->CallNonvirtualBooleanMethod(jenv, jdb, db_class, foreignkey_nullify_method, jkey, jdata, jskey);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
goto err;
}
if (jresult == JNI_FALSE)
*changed = ret = 0;
else{
*changed = 1;
/* copy jdata into data */
if ((ret = __dbj_dbt_copyin(jenv, &lresult, NULL, jdata, 0)) != 0)
goto err;
if (lresult.dbt.size != 0){
data->size = lresult.dbt.size;
if ((ret = __os_umalloc(
NULL, data->size, &data->data)) != 0)
goto err;
if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0,
data->data, data->size, DB_USERCOPY_GETDATA)) != 0)
goto err;
__dbj_dbt_release(jenv, jdata, &lresult.dbt, &lresult);
(*jenv)->DeleteLocalRef(jenv, lresult.jarr);
F_SET(data, DB_DBT_APPMALLOC);
}
}
err: if (key->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jkeyarr);
(*jenv)->DeleteLocalRef(jenv, jkey);
}
if (data->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jdataarr);
(*jenv)->DeleteLocalRef(jenv, jdata);
}
return ret;
}
static int __dbj_seckey_create(DB *db,
const DBT *key, const DBT *data, DBT *result)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jobject jkey, jdata, jresult;
jobjectArray jskeys;
jsize i, num_skeys;
jbyteArray jkeyarr, jdataarr;
DBT_LOCKED lresult;
DBT *tresult;
int ret;
if (jdb == NULL)
return (EINVAL);
jkey = (key->app_data != NULL) ?
((DBT_LOCKED *)key->app_data)->jdbt :
(*jenv)->NewObject(jenv, dbt_class, dbt_construct);
jdata = (data->app_data != NULL) ?
((DBT_LOCKED *)data->app_data)->jdbt :
(*jenv)->NewObject(jenv, dbt_class, dbt_construct);
if (jkey == NULL || jdata == NULL)
return (ENOMEM); /* An exception is pending */
if (key->app_data == NULL) {
__dbj_dbt_copyout(jenv, key, &jkeyarr, jkey);
if (jkeyarr == NULL)
return (ENOMEM); /* An exception is pending */
}
if (data->app_data == NULL) {
__dbj_dbt_copyout(jenv, data, &jdataarr, jdata);
if (jdataarr == NULL)
return (ENOMEM); /* An exception is pending */
}
jskeys = (jobjectArray)(*jenv)->CallNonvirtualObjectMethod(jenv,
jdb, db_class, seckey_create_method, jkey, jdata);
if (jskeys == NULL ||
(num_skeys = (*jenv)->GetArrayLength(jenv, jskeys)) == 0) {
ret = DB_DONOTINDEX;
goto err;
} else if (num_skeys == 1) {
memset(result, 0, sizeof (DBT));
tresult = result;
} else {
if ((ret = __os_umalloc(db->env,
num_skeys * sizeof (DBT), &result->data)) != 0)
goto err;
memset(result->data, 0, num_skeys * sizeof (DBT));
result->size = num_skeys;
F_SET(result, DB_DBT_APPMALLOC | DB_DBT_MULTIPLE);
tresult = (DBT *)result->data;
}
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
goto err;
}
for (i = 0; i < num_skeys; i++, tresult++) {
jresult = (*jenv)->GetObjectArrayElement(jenv, jskeys, i);
if ((ret =
__dbj_dbt_copyin(jenv, &lresult, NULL, jresult, 0)) != 0)
goto err;
if (lresult.dbt.size != 0) {
/* If there's data, we need to take a copy of it. */
tresult->size = lresult.dbt.size;
if ((ret = __os_umalloc(NULL,
tresult->size, &tresult->data)) != 0)
goto err;
if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0,
tresult->data, tresult->size,
DB_USERCOPY_GETDATA)) != 0)
goto err;
__dbj_dbt_release(jenv,
jresult, &lresult.dbt, &lresult);
(*jenv)->DeleteLocalRef(jenv, lresult.jarr);
F_SET(tresult, DB_DBT_APPMALLOC);
}
(*jenv)->DeleteLocalRef(jenv, jresult);
}
err: if (key->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jkeyarr);
(*jenv)->DeleteLocalRef(jenv, jkey);
}
if (data->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jdataarr);
(*jenv)->DeleteLocalRef(jenv, jdata);
}
return (ret);
}
static int __dbj_append_recno(DB *db, DBT *dbt, db_recno_t recno)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jobject jdbt;
DBT_LOCKED lresult;
jbyteArray jdbtarr;
int ret;
if (jdb == NULL)
return (EINVAL);
/*
* The dbt we're passed will be from the application, but we can't
* just reuse it, since we will have already taken a copy of the data.
* Make a new DatabaseEntry object here for the callback.
*/
jdbt = (*jenv)->NewObject(jenv, dbt_class, dbt_construct);
if (jdbt == NULL)
return (ENOMEM); /* An exception is pending */
__dbj_dbt_copyout(jenv, dbt, &jdbtarr, jdbt);
if (jdbtarr == NULL)
return (ENOMEM); /* An exception is pending */
ret = 0;
(*jenv)->CallNonvirtualVoidMethod(jenv, jdb, db_class,
append_recno_method, jdbt, recno);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
return (EINVAL);
}
ret = __dbj_dbt_copyin(jenv, &lresult, NULL, jdbt, 0);
memset(dbt, 0, sizeof (DBT));
if (ret == 0 && lresult.dbt.size != 0) {
/* If there's data, we need to take a copy of it. */
dbt->size = lresult.dbt.size;
if ((ret =
__os_umalloc(NULL, dbt->size, &dbt->data)) != 0)
goto err;
if ((ret = __dbj_dbt_memcopy(&lresult.dbt, 0,
dbt->data, dbt->size,
DB_USERCOPY_GETDATA)) != 0)
goto err;
__dbj_dbt_release(jenv, jdbt, &lresult.dbt, &lresult);
(*jenv)->DeleteLocalRef(jenv, lresult.jarr);
F_SET(dbt, DB_DBT_APPMALLOC);
}
err: (*jenv)->DeleteLocalRef(jenv, jdbtarr);
(*jenv)->DeleteLocalRef(jenv, jdbt);
return (ret);
}
/*
* Shared by __dbj_bt_compare and __dbj_h_compare
*/
static int __dbj_am_compare(DB *db, const DBT *dbt1, const DBT *dbt2,
jmethodID compare_method)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jbyteArray jdbtarr1, jdbtarr2;
int ret;
if (jdb == NULL)
return (EINVAL);
if (dbt1->app_data != NULL)
jdbtarr1 = ((DBT_LOCKED *)dbt1->app_data)->jarr;
else {
jdbtarr1 = (*jenv)->NewByteArray(jenv, (jsize)dbt1->size);
if (jdbtarr1 == NULL)
return (ENOMEM);
(*jenv)->SetByteArrayRegion(jenv, jdbtarr1, 0,
(jsize)dbt1->size, (jbyte *)dbt1->data);
}
if (dbt2->app_data != NULL)
jdbtarr2 = ((DBT_LOCKED *)dbt2->app_data)->jarr;
else {
jdbtarr2 = (*jenv)->NewByteArray(jenv, (jsize)dbt2->size);
if (jdbtarr2 == NULL)
return (ENOMEM);
(*jenv)->SetByteArrayRegion(jenv, jdbtarr2, 0,
(jsize)dbt2->size, (jbyte *)dbt2->data);
}
ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class,
compare_method, jdbtarr1, jdbtarr2);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
}
if (dbt1->app_data == NULL)
(*jenv)->DeleteLocalRef(jenv, jdbtarr1);
if (dbt2->app_data == NULL)
(*jenv)->DeleteLocalRef(jenv, jdbtarr2);
return (ret);
}
static int __dbj_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2)
{
return __dbj_am_compare(db, dbt1, dbt2, bt_compare_method);
}
static size_t __dbj_bt_prefix(DB *db, const DBT *dbt1, const DBT *dbt2)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jobject jdbt1, jdbt2;
jbyteArray jdbtarr1, jdbtarr2;
int ret;
if (jdb == NULL)
return (EINVAL);
if (dbt1->app_data != NULL)
jdbt1 = ((DBT_LOCKED *)dbt1->app_data)->jdbt;
else {
if ((jdbt1 =
(*jenv)->NewObject(jenv, dbt_class, dbt_construct)) == NULL)
return (ENOMEM); /* An exception is pending */
__dbj_dbt_copyout(jenv, dbt1, &jdbtarr1, jdbt1);
if (jdbtarr1 == NULL)
return (ENOMEM); /* An exception is pending */
}
if (dbt2->app_data != NULL)
jdbt2 = ((DBT_LOCKED *)dbt2->app_data)->jdbt;
else {
if ((jdbt2 =
(*jenv)->NewObject(jenv, dbt_class, dbt_construct)) == NULL)
return (ENOMEM); /* An exception is pending */
__dbj_dbt_copyout(jenv, dbt2, &jdbtarr2, jdbt2);
if (jdbtarr2 == NULL)
return (ENOMEM); /* An exception is pending */
}
ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class,
bt_prefix_method, jdbt1, jdbt2);
if (dbt1->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jdbtarr1);
(*jenv)->DeleteLocalRef(jenv, jdbt1);
}
if (dbt2->app_data == NULL) {
(*jenv)->DeleteLocalRef(jenv, jdbtarr2);
(*jenv)->DeleteLocalRef(jenv, jdbt2);
}
return (ret);
}
static int __dbj_dup_compare(DB *db, const DBT *dbt1, const DBT *dbt2)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jbyteArray jdbtarr1, jdbtarr2;
int ret;
if (jdb == NULL)
return (EINVAL);
jdbtarr1 = (*jenv)->NewByteArray(jenv, (jsize)dbt1->size);
if (jdbtarr1 == NULL)
return (ENOMEM);
(*jenv)->SetByteArrayRegion(jenv, jdbtarr1, 0, (jsize)dbt1->size,
(jbyte *)dbt1->data);
jdbtarr2 = (*jenv)->NewByteArray(jenv, (jsize)dbt2->size);
if (jdbtarr2 == NULL)
return (ENOMEM);
(*jenv)->SetByteArrayRegion(jenv, jdbtarr2, 0, (jsize)dbt2->size,
(jbyte *)dbt2->data);
ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class,
dup_compare_method, jdbtarr1, jdbtarr2);
if ((*jenv)->ExceptionOccurred(jenv)) {
/* The exception will be thrown, so this could be any error. */
ret = EINVAL;
}
(*jenv)->DeleteLocalRef(jenv, jdbtarr2);
(*jenv)->DeleteLocalRef(jenv, jdbtarr1);
return (ret);
}
static void __dbj_db_feedback(DB *db, int opcode, int percent)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
if (jdb != NULL)
(*jenv)->CallNonvirtualVoidMethod(jenv, jdb, db_class,
db_feedback_method, opcode, percent);
}
static int __dbj_h_compare(DB *db, const DBT *dbt1, const DBT *dbt2)
{
return __dbj_am_compare(db, dbt1, dbt2, h_compare_method);
}
static u_int32_t __dbj_h_hash(DB *db, const void *data, u_int32_t len)
{
JNIEnv *jenv = __dbj_get_jnienv();
jobject jdb = (jobject)DB_INTERNAL(db);
jbyteArray jarr = (*jenv)->NewByteArray(jenv, (jsize)len);
int ret;
if (jdb == NULL)
return (EINVAL);
if ((jarr = (*jenv)->NewByteArray(jenv, (jsize)len)) == NULL)
return (ENOMEM); /* An exception is pending */
(*jenv)->SetByteArrayRegion(jenv, jarr, 0, (jsize)len, (jbyte *)data);
ret = (int)(*jenv)->CallNonvirtualIntMethod(jenv, jdb, db_class,
h_hash_method, jarr, len);
(*jenv)->DeleteLocalRef(jenv, jarr);
return (ret);
}
%}
JAVA_CALLBACK(void (*db_errcall_fcn)(const DB_ENV *,
const char *, const char *), com.sleepycat.db.ErrorHandler, error)
JAVA_CALLBACK(void (*env_feedback_fcn)(DB_ENV *, int, int),
com.sleepycat.db.FeedbackHandler, env_feedback)
JAVA_CALLBACK(void (*db_msgcall_fcn)(const DB_ENV *, const char *),
com.sleepycat.db.MessageHandler, message)
JAVA_CALLBACK(void (*db_panic_fcn)(DB_ENV *, int),
com.sleepycat.db.PanicHandler, panic)
JAVA_CALLBACK(void (*event_notify)(DB_ENV *, u_int32_t, void *),
com.sleepycat.db.EventHandler, event_notify)
JAVA_CALLBACK(int (*tx_recover)(DB_ENV *, DBT *, DB_LSN *, db_recops),
com.sleepycat.db.LogRecordHandler, app_dispatch)
JAVA_CALLBACK(int (*send)(DB_ENV *, const DBT *, const DBT *,
const DB_LSN *, int, u_int32_t),
com.sleepycat.db.ReplicationTransport, rep_transport)
/*
* Db.associate is a special case, because the handler must be set in the
* secondary DB - that's what we have in the callback. In addition, there
* are two flavors of callback (single key and multi-key), so we need to
* check for both types when working out whether the C callback should
* be NULL. Note that this implies that the multi-key callback will be set
* on the secondary database *before* associate is called.
*/
JAVA_CALLBACK(int (*callback)(DB *, const DBT *, const DBT *, DBT *),
com.sleepycat.db.SecondaryKeyCreator, seckey_create)
%typemap(javain) int (*callback)(DB *, const DBT *, const DBT *, DBT *)
%{ (secondary.seckey_create_handler = $javainput) != null ||
(secondary.secmultikey_create_handler != null) %}
JAVA_CALLBACK(int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *),
com.sleepycat.db.ForeignKeyNullifier, foreignkey_nullify)
%typemap(javain) int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *)
%{ (primary.foreignkey_nullify_handler = $javainput) != null ||
(primary.foreignmultikey_nullify_handler != null) %}
JAVA_CALLBACK(int (*db_append_recno_fcn)(DB *, DBT *, db_recno_t),
com.sleepycat.db.RecordNumberAppender, append_recno)
JAVA_CALLBACK(int (*bt_compare_fcn)(DB *, const DBT *, const DBT *),
java.util.Comparator, bt_compare)
JAVA_CALLBACK(size_t (*bt_prefix_fcn)(DB *, const DBT *, const DBT *),
com.sleepycat.db.BtreePrefixCalculator, bt_prefix)
JAVA_CALLBACK(int (*dup_compare_fcn)(DB *, const DBT *, const DBT *),
java.util.Comparator, dup_compare)
JAVA_CALLBACK(void (*db_feedback_fcn)(DB *, int, int),
com.sleepycat.db.FeedbackHandler, db_feedback)
JAVA_CALLBACK(int (*h_compare_fcn)(DB *, const DBT *, const DBT *),
java.util.Comparator, h_compare)
JAVA_CALLBACK(u_int32_t (*h_hash_fcn)(DB *, const void *, u_int32_t),
com.sleepycat.db.Hasher, h_hash)

180
libdb_java/java_except.i Normal file
View File

@@ -0,0 +1,180 @@
%{
/*
* Macros to find the Java DbEnv object for methods in various classes.
* Note that "arg1" is from the code SWIG generates for the "this"/"self".
*/
#define JDBENV (arg1 ? (jobject)DB_ENV_INTERNAL(arg1) : NULL)
#define DB2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->dbenv))
#define DBC2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->dbp->dbenv))
#define TXN2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->mgrp->env->dbenv))
%}
/* Common case exception handling */
%typemap(check) SWIGTYPE *self %{
if ($input == 0) {
__dbj_throw(jenv, EINVAL, "call on closed handle", NULL, NULL);
return $null;
}%}
%define JAVA_EXCEPT_NONE
%exception %{ $action %}
%enddef
/* Most methods return an error code. */
%define JAVA_EXCEPT(_retcheck, _jdbenv)
%exception %{
$action
if (!_retcheck(result)) {
__dbj_throw(jenv, result, NULL, NULL, _jdbenv);
}
%}
%enddef
/* For everything else, errno is set in db.i. */
%define JAVA_EXCEPT_ERRNO(_retcheck, _jdbenv)
%exception %{
errno = 0;
$action
if (!_retcheck(errno)) {
__dbj_throw(jenv, errno, NULL, NULL, _jdbenv);
}
%}
%enddef
/* And then there are these (extra) special cases. */
%exception __db_env::lock_get %{
errno = 0;
$action
if (errno == DB_LOCK_NOTGRANTED) {
(*jenv)->Throw(jenv,
(*jenv)->NewObject(jenv, lockex_class, lockex_construct,
(*jenv)->NewStringUTF(jenv, "DbEnv.lock_get not granted"),
DB_LOCK_GET, arg5, jarg4, NULL, -1, JDBENV));
} else if (!DB_RETOK_STD(errno)) {
__dbj_throw(jenv, errno, NULL, NULL, JDBENV);
}
%}
%{
static jthrowable __dbj_get_except(JNIEnv *jenv,
int err, const char *msg, jobject obj, jobject jdbenv) {
jobject jmsg;
if (msg == NULL)
msg = db_strerror(err);
jmsg = (*jenv)->NewStringUTF(jenv, msg);
/* Retrieve error message logged by DB */
if (jdbenv != NULL) {
jmsg = (jstring) (*jenv)->CallNonvirtualObjectMethod(jenv,
jdbenv, dbenv_class, get_err_msg_method, jmsg);
}
switch (err) {
case EINVAL:
return (jthrowable)(*jenv)->NewObject(jenv,
illegalargex_class, illegalargex_construct, jmsg);
case ENOENT:
return (jthrowable)(*jenv)->NewObject(jenv,
filenotfoundex_class, filenotfoundex_construct, jmsg);
case ENOMEM:
return (jthrowable)(*jenv)->NewObject(jenv,
outofmemerr_class, outofmemerr_construct, jmsg);
case DB_BUFFER_SMALL:
return (jthrowable)(*jenv)->NewObject(jenv, memex_class,
memex_construct, jmsg, obj, err, jdbenv);
case DB_REP_DUPMASTER:
return (jthrowable)(*jenv)->NewObject(jenv,
repdupmasterex_class, repdupmasterex_construct,
jmsg, err, jdbenv);
case DB_REP_HANDLE_DEAD:
return (jthrowable)(*jenv)->NewObject(jenv,
rephandledeadex_class, rephandledeadex_construct,
jmsg, err, jdbenv);
case DB_REP_HOLDELECTION:
return (jthrowable)(*jenv)->NewObject(jenv,
repholdelectionex_class, repholdelectionex_construct,
jmsg, err, jdbenv);
case DB_REP_JOIN_FAILURE:
return (jthrowable)(*jenv)->NewObject(jenv,
repjoinfailex_class, repjoinfailex_construct,
jmsg, err, jdbenv);
case DB_REP_LEASE_EXPIRED:
return (jthrowable)(*jenv)->NewObject(jenv,
repleaseexpiredex_class, repleaseexpiredex_construct,
jmsg, err, jdbenv);
case DB_REP_LEASE_TIMEOUT:
return (jthrowable)(*jenv)->NewObject(jenv,
repleasetimeoutex_class, repleasetimeoutex_construct,
jmsg, err, jdbenv);
case DB_REP_LOCKOUT:
return (jthrowable)(*jenv)->NewObject(jenv,
replockoutex_class, replockoutex_construct,
jmsg, err, jdbenv);
case DB_REP_UNAVAIL:
return (jthrowable)(*jenv)->NewObject(jenv,
repunavailex_class, repunavailex_construct,
jmsg, err, jdbenv);
case DB_RUNRECOVERY:
return (jthrowable)(*jenv)->NewObject(jenv, runrecex_class,
runrecex_construct, jmsg, err, jdbenv);
case DB_LOCK_DEADLOCK:
return (jthrowable)(*jenv)->NewObject(jenv, deadex_class,
deadex_construct, jmsg, err, jdbenv);
case DB_LOCK_NOTGRANTED:
return (jthrowable)(*jenv)->NewObject(jenv, lockex_class,
lockex_construct, jmsg, err, 0, NULL, NULL, 0, jdbenv);
case DB_VERSION_MISMATCH:
return (jthrowable)(*jenv)->NewObject(jenv, versionex_class,
versionex_construct, jmsg, err, jdbenv);
default:
return (jthrowable)(*jenv)->NewObject(jenv, dbex_class,
dbex_construct, jmsg, err, jdbenv);
}
}
static int __dbj_throw(JNIEnv *jenv,
int err, const char *msg, jobject obj, jobject jdbenv)
{
jthrowable t;
/* If an exception is pending, ignore requests to throw a new one. */
if ((*jenv)->ExceptionOccurred(jenv) == NULL) {
t = __dbj_get_except(jenv, err, msg, obj, jdbenv);
if (t == NULL) {
/*
* This is a problem - something went wrong creating an
* exception. We have to assume there is an exception
* created by the JVM that is pending as a result
* (e.g., OutOfMemoryError), but we don't want to lose
* this error, so we just call __db_errx here.
*/
if (msg == NULL)
msg = db_strerror(err);
__db_errx(NULL, "Couldn't create exception for: '%s'",
msg);
} else
(*jenv)->Throw(jenv, t);
}
return (err);
}
%}

176
libdb_java/java_stat.i Normal file
View File

@@ -0,0 +1,176 @@
/* Statistics classes */
%{
/*
* These macros are used by code generated by the s_java script.
*/
#define JAVADB_STAT_INT(jenv, jobj, fid, statp, name) \
(*jenv)->SetIntField(jenv, jobj, fid, (jint)statp->name)
#define JAVADB_STAT_STRING(jenv, jobj, fid, statp, name) \
(*jenv)->SetObjectField(jenv, jobj, fid, \
(*jenv)->NewStringUTF(jenv, statp->name))
#define JAVADB_STAT_LSN(jenv, jobj, fid, statp, name) \
(*jenv)->SetObjectField(jenv, jobj, fid, \
__dbj_wrap_DB_LSN(jenv, &statp->name))
#define JAVADB_STAT_LONG(jenv, jobj, fid, statp, name) \
(*jenv)->SetLongField(jenv, jobj, fid, \
(jlong)statp->name)
#define JAVADB_STAT_XID(jenv, jobj, fid, statp, name) { \
jobject jarr = \
(*jenv)->NewByteArray(jenv, (jsize)DB_XIDDATASIZE); \
(*jenv)->SetByteArrayRegion(jenv, jarr, \
0, (jsize)DB_XIDDATASIZE, (jbyte *)statp->name); \
(*jenv)->SetObjectField(jenv, jobj, fid, jarr); \
}
/*
* We build the active list separately.
*/
#define JAVADB_STAT_ACTIVE(jenv, cl, jobj, statp, name) \
do {} while(0)
#include "java_stat_auto.c"
%}
%define JAVA_STAT_CLASS(_ctype, _jtype, _name)
JAVA_TYPEMAP(_ctype, _jtype, jobject)
%typemap(out) _ctype %{
$result = (*jenv)->NewObject(jenv, _name##_class, _name##_construct);
if ($result != NULL)
__dbj_fill_##_name(jenv, $result, $1);
__os_ufree(NULL, $1);
%}
%enddef
JAVA_STAT_CLASS(DB_COMPACT *, com.sleepycat.db.CompactStats, compact)
%typemap(freearg) DB_COMPACT * %{ __dbj_fill_compact(jenv, $input, $1); %}
%typemap(in) DB_COMPACT * (DB_COMPACT compact) %{
memset(&compact, 0, sizeof (DB_COMPACT));
$1 = &compact;
$1->compact_fillpercent = (*jenv)->GetIntField(jenv, $input,
compact_compact_fillpercent_fid);
$1->compact_timeout = (*jenv)->GetIntField(jenv, $input,
compact_compact_timeout_fid);
$1->compact_pages = (*jenv)->GetIntField(jenv, $input,
compact_compact_pages_fid);
%}
JAVA_STAT_CLASS(DB_LOCK_STAT *, com.sleepycat.db.LockStats, lock_stat)
JAVA_STAT_CLASS(DB_LOG_STAT *, com.sleepycat.db.LogStats, log_stat)
JAVA_STAT_CLASS(DB_MPOOL_STAT *, com.sleepycat.db.CacheStats, mpool_stat)
JAVA_TYPEMAP(DB_MPOOL_FSTAT **, com.sleepycat.db.CacheFileStats[], jobjectArray)
%typemap(out) DB_MPOOL_FSTAT ** {
int i, len;
len = 0;
while ($1[len] != NULL)
len++;
$result = (*jenv)->NewObjectArray(jenv, (jsize)len,
mpool_fstat_class, 0);
if ($result == NULL) {
__os_ufree(NULL, $1);
return $null;
}
for (i = 0; i < len; i++) {
jobject obj = (*jenv)->NewObject(jenv, mpool_fstat_class,
mpool_fstat_construct);
if (obj == NULL) {
__os_ufree(NULL, $1);
return $null; /* an exception is pending */
}
(*jenv)->SetObjectArrayElement(jenv, $result, i, obj);
__dbj_fill_mpool_fstat(jenv, obj, $1[i]);
}
__os_ufree(NULL, $1);
}
JAVA_STAT_CLASS(DB_MUTEX_STAT *, com.sleepycat.db.MutexStats, mutex_stat)
JAVA_STAT_CLASS(DB_REP_STAT *, com.sleepycat.db.ReplicationStats, rep_stat)
JAVA_STAT_CLASS(DB_REPMGR_STAT *, com.sleepycat.db.ReplicationManagerStats, repmgr_stat)
JAVA_STAT_CLASS(DB_SEQUENCE_STAT *, com.sleepycat.db.SequenceStats, seq_stat)
JAVA_TYPEMAP(DB_TXN_STAT *, com.sleepycat.db.TransactionStats, jobject)
%typemap(out) DB_TXN_STAT * {
unsigned int i;
jobjectArray actives;
$result = (*jenv)->NewObject(jenv, txn_stat_class, txn_stat_construct);
if ($result != NULL)
__dbj_fill_txn_stat(jenv, $result, $1);
actives = (*jenv)->NewObjectArray(jenv, (jsize)$1->st_nactive,
txn_active_class, 0);
if (actives == NULL) {
__os_ufree(NULL, $1);
return $null;
}
(*jenv)->SetObjectField(jenv, $result,
txn_stat_st_txnarray_fid, actives);
for (i = 0; i < $1->st_nactive; i++) {
jobject obj = (*jenv)->NewObject(jenv, txn_active_class,
txn_active_construct);
if (obj == NULL) {
__os_ufree(NULL, $1);
return $null; /* an exception is pending */
}
(*jenv)->SetObjectArrayElement(jenv, actives, (jsize)i, obj);
__dbj_fill_txn_active(jenv, obj, &$1->st_txnarray[i]);
}
__os_ufree(NULL, $1);
}
/* Db.stat return - special case */
%typemap(out) void * %{
if ($1 == NULL)
$result = NULL;
else {
DB *db = (DB *)arg1;
DBTYPE dbtype;
int err;
if ((err = db->get_type(db, &dbtype)) != 0) {
__dbj_throw(jenv, err, NULL, NULL, DB2JDBENV);
return $null;
}
switch (dbtype) {
/* Btree and recno share the same stat structure */
case DB_BTREE:
case DB_RECNO:
$result = (*jenv)->NewObject(jenv, bt_stat_class,
bt_stat_construct);
if ($result != NULL)
__dbj_fill_bt_stat(jenv, $result,
(DB_BTREE_STAT *)$1);
break;
/* Hash stat structure */
case DB_HASH:
$result = (*jenv)->NewObject(jenv, h_stat_class,
h_stat_construct);
if ($result != NULL)
__dbj_fill_h_stat(jenv, $result,
(DB_HASH_STAT *)$1);
break;
case DB_QUEUE:
$result = (*jenv)->NewObject(jenv, qam_stat_class,
qam_stat_construct);
if ($result != NULL)
__dbj_fill_qam_stat(jenv, $result,
(DB_QUEUE_STAT *)$1);
break;
/* That's all the database types we're aware of! */
default:
__dbj_throw(jenv, EINVAL, "Db.stat only implemented for"
" BTREE, HASH, QUEUE and RECNO", NULL, DB2JDBENV);
break;
}
__os_ufree(db->env, $1);
}
%}

342
libdb_java/java_stat_auto.c Normal file
View File

@@ -0,0 +1,342 @@
/*-
* Automatically built by dist/s_java_stat.
* Only the javadoc comments can be edited.
*
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002,2008 Oracle. All rights reserved.
*/
static int __dbj_fill_bt_stat(JNIEnv *jnienv,
jobject jobj, struct __db_bt_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_magic_fid, statp, bt_magic);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_version_fid, statp, bt_version);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_metaflags_fid, statp, bt_metaflags);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_nkeys_fid, statp, bt_nkeys);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_ndata_fid, statp, bt_ndata);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_pagecnt_fid, statp, bt_pagecnt);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_pagesize_fid, statp, bt_pagesize);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_minkey_fid, statp, bt_minkey);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_re_len_fid, statp, bt_re_len);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_re_pad_fid, statp, bt_re_pad);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_levels_fid, statp, bt_levels);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_int_pg_fid, statp, bt_int_pg);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_leaf_pg_fid, statp, bt_leaf_pg);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_dup_pg_fid, statp, bt_dup_pg);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_over_pg_fid, statp, bt_over_pg);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_empty_pg_fid, statp, bt_empty_pg);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_free_fid, statp, bt_free);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_int_pgfree_fid, statp, bt_int_pgfree);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_leaf_pgfree_fid, statp, bt_leaf_pgfree);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_dup_pgfree_fid, statp, bt_dup_pgfree);
JAVADB_STAT_INT(jnienv, jobj, bt_stat_bt_over_pgfree_fid, statp, bt_over_pgfree);
return (0);
}
static int __dbj_fill_compact(JNIEnv *jnienv,
jobject jobj, struct __db_compact *statp) {
JAVADB_STAT_INT(jnienv, jobj, compact_compact_fillpercent_fid, statp, compact_fillpercent);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_timeout_fid, statp, compact_timeout);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_pages_fid, statp, compact_pages);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_pages_free_fid, statp, compact_pages_free);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_pages_examine_fid, statp, compact_pages_examine);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_levels_fid, statp, compact_levels);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_deadlock_fid, statp, compact_deadlock);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_pages_truncated_fid, statp, compact_pages_truncated);
JAVADB_STAT_INT(jnienv, jobj, compact_compact_truncate_fid, statp, compact_truncate);
return (0);
}
static int __dbj_fill_h_stat(JNIEnv *jnienv,
jobject jobj, struct __db_h_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_magic_fid, statp, hash_magic);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_version_fid, statp, hash_version);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_metaflags_fid, statp, hash_metaflags);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_nkeys_fid, statp, hash_nkeys);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_ndata_fid, statp, hash_ndata);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_pagecnt_fid, statp, hash_pagecnt);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_pagesize_fid, statp, hash_pagesize);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_ffactor_fid, statp, hash_ffactor);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_buckets_fid, statp, hash_buckets);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_free_fid, statp, hash_free);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_bfree_fid, statp, hash_bfree);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_bigpages_fid, statp, hash_bigpages);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_big_bfree_fid, statp, hash_big_bfree);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_overflows_fid, statp, hash_overflows);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_ovfl_free_fid, statp, hash_ovfl_free);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_dup_fid, statp, hash_dup);
JAVADB_STAT_INT(jnienv, jobj, h_stat_hash_dup_free_fid, statp, hash_dup_free);
return (0);
}
static int __dbj_fill_lock_stat(JNIEnv *jnienv,
jobject jobj, struct __db_lock_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_id_fid, statp, st_id);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_cur_maxid_fid, statp, st_cur_maxid);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxlocks_fid, statp, st_maxlocks);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxlockers_fid, statp, st_maxlockers);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxobjects_fid, statp, st_maxobjects);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_partitions_fid, statp, st_partitions);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nmodes_fid, statp, st_nmodes);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nlockers_fid, statp, st_nlockers);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nlocks_fid, statp, st_nlocks);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxnlocks_fid, statp, st_maxnlocks);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxhlocks_fid, statp, st_maxhlocks);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_locksteals_fid, statp, st_locksteals);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxlsteals_fid, statp, st_maxlsteals);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxnlockers_fid, statp, st_maxnlockers);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nobjects_fid, statp, st_nobjects);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxnobjects_fid, statp, st_maxnobjects);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxhobjects_fid, statp, st_maxhobjects);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_objectsteals_fid, statp, st_objectsteals);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_maxosteals_fid, statp, st_maxosteals);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nrequests_fid, statp, st_nrequests);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nreleases_fid, statp, st_nreleases);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nupgrade_fid, statp, st_nupgrade);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_ndowngrade_fid, statp, st_ndowngrade);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_lock_wait_fid, statp, st_lock_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_lock_nowait_fid, statp, st_lock_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_ndeadlocks_fid, statp, st_ndeadlocks);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_locktimeout_fid, statp, st_locktimeout);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_nlocktimeouts_fid, statp, st_nlocktimeouts);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_txntimeout_fid, statp, st_txntimeout);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_ntxntimeouts_fid, statp, st_ntxntimeouts);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_part_wait_fid, statp, st_part_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_part_nowait_fid, statp, st_part_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_part_max_wait_fid, statp, st_part_max_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_part_max_nowait_fid, statp, st_part_max_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_objs_wait_fid, statp, st_objs_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_objs_nowait_fid, statp, st_objs_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_lockers_wait_fid, statp, st_lockers_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_lockers_nowait_fid, statp, st_lockers_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_region_wait_fid, statp, st_region_wait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_region_nowait_fid, statp, st_region_nowait);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_hash_len_fid, statp, st_hash_len);
JAVADB_STAT_INT(jnienv, jobj, lock_stat_st_regsize_fid, statp, st_regsize);
return (0);
}
static int __dbj_fill_log_stat(JNIEnv *jnienv,
jobject jobj, struct __db_log_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_magic_fid, statp, st_magic);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_version_fid, statp, st_version);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_mode_fid, statp, st_mode);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_lg_bsize_fid, statp, st_lg_bsize);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_lg_size_fid, statp, st_lg_size);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_wc_bytes_fid, statp, st_wc_bytes);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_wc_mbytes_fid, statp, st_wc_mbytes);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_record_fid, statp, st_record);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_w_bytes_fid, statp, st_w_bytes);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_w_mbytes_fid, statp, st_w_mbytes);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_wcount_fid, statp, st_wcount);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_wcount_fill_fid, statp, st_wcount_fill);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_rcount_fid, statp, st_rcount);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_scount_fid, statp, st_scount);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_region_wait_fid, statp, st_region_wait);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_region_nowait_fid, statp, st_region_nowait);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_cur_file_fid, statp, st_cur_file);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_cur_offset_fid, statp, st_cur_offset);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_disk_file_fid, statp, st_disk_file);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_disk_offset_fid, statp, st_disk_offset);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_maxcommitperflush_fid, statp, st_maxcommitperflush);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_mincommitperflush_fid, statp, st_mincommitperflush);
JAVADB_STAT_INT(jnienv, jobj, log_stat_st_regsize_fid, statp, st_regsize);
return (0);
}
static int __dbj_fill_mpool_fstat(JNIEnv *jnienv,
jobject jobj, struct __db_mpool_fstat *statp) {
JAVADB_STAT_STRING(jnienv, jobj, mpool_fstat_file_name_fid, statp, file_name);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_pagesize_fid, statp, st_pagesize);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_map_fid, statp, st_map);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_cache_hit_fid, statp, st_cache_hit);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_cache_miss_fid, statp, st_cache_miss);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_page_create_fid, statp, st_page_create);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_page_in_fid, statp, st_page_in);
JAVADB_STAT_INT(jnienv, jobj, mpool_fstat_st_page_out_fid, statp, st_page_out);
return (0);
}
static int __dbj_fill_mpool_stat(JNIEnv *jnienv,
jobject jobj, struct __db_mpool_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_gbytes_fid, statp, st_gbytes);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_bytes_fid, statp, st_bytes);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_ncache_fid, statp, st_ncache);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_max_ncache_fid, statp, st_max_ncache);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_mmapsize_fid, statp, st_mmapsize);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_maxopenfd_fid, statp, st_maxopenfd);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_maxwrite_fid, statp, st_maxwrite);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_maxwrite_sleep_fid, statp, st_maxwrite_sleep);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_pages_fid, statp, st_pages);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_map_fid, statp, st_map);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_cache_hit_fid, statp, st_cache_hit);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_cache_miss_fid, statp, st_cache_miss);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_create_fid, statp, st_page_create);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_in_fid, statp, st_page_in);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_out_fid, statp, st_page_out);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_ro_evict_fid, statp, st_ro_evict);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_rw_evict_fid, statp, st_rw_evict);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_trickle_fid, statp, st_page_trickle);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_clean_fid, statp, st_page_clean);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_page_dirty_fid, statp, st_page_dirty);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_buckets_fid, statp, st_hash_buckets);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_searches_fid, statp, st_hash_searches);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_longest_fid, statp, st_hash_longest);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_examined_fid, statp, st_hash_examined);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_nowait_fid, statp, st_hash_nowait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_wait_fid, statp, st_hash_wait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_max_nowait_fid, statp, st_hash_max_nowait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_hash_max_wait_fid, statp, st_hash_max_wait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_region_nowait_fid, statp, st_region_nowait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_region_wait_fid, statp, st_region_wait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_mvcc_frozen_fid, statp, st_mvcc_frozen);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_mvcc_thawed_fid, statp, st_mvcc_thawed);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_mvcc_freed_fid, statp, st_mvcc_freed);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_alloc_fid, statp, st_alloc);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_alloc_buckets_fid, statp, st_alloc_buckets);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_alloc_max_buckets_fid, statp, st_alloc_max_buckets);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_alloc_pages_fid, statp, st_alloc_pages);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_alloc_max_pages_fid, statp, st_alloc_max_pages);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_io_wait_fid, statp, st_io_wait);
JAVADB_STAT_INT(jnienv, jobj, mpool_stat_st_regsize_fid, statp, st_regsize);
return (0);
}
static int __dbj_fill_mutex_stat(JNIEnv *jnienv,
jobject jobj, struct __db_mutex_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_align_fid, statp, st_mutex_align);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_tas_spins_fid, statp, st_mutex_tas_spins);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_cnt_fid, statp, st_mutex_cnt);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_free_fid, statp, st_mutex_free);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_inuse_fid, statp, st_mutex_inuse);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_mutex_inuse_max_fid, statp, st_mutex_inuse_max);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_region_wait_fid, statp, st_region_wait);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_region_nowait_fid, statp, st_region_nowait);
JAVADB_STAT_INT(jnienv, jobj, mutex_stat_st_regsize_fid, statp, st_regsize);
return (0);
}
static int __dbj_fill_qam_stat(JNIEnv *jnienv,
jobject jobj, struct __db_qam_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_magic_fid, statp, qs_magic);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_version_fid, statp, qs_version);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_metaflags_fid, statp, qs_metaflags);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_nkeys_fid, statp, qs_nkeys);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_ndata_fid, statp, qs_ndata);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_pagesize_fid, statp, qs_pagesize);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_extentsize_fid, statp, qs_extentsize);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_pages_fid, statp, qs_pages);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_re_len_fid, statp, qs_re_len);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_re_pad_fid, statp, qs_re_pad);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_pgfree_fid, statp, qs_pgfree);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_first_recno_fid, statp, qs_first_recno);
JAVADB_STAT_INT(jnienv, jobj, qam_stat_qs_cur_recno_fid, statp, qs_cur_recno);
return (0);
}
static int __dbj_fill_rep_stat(JNIEnv *jnienv,
jobject jobj, struct __db_rep_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_queued_fid, statp, st_log_queued);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_startup_complete_fid, statp, st_startup_complete);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_status_fid, statp, st_status);
JAVADB_STAT_LSN(jnienv, jobj, rep_stat_st_next_lsn_fid, statp, st_next_lsn);
JAVADB_STAT_LSN(jnienv, jobj, rep_stat_st_waiting_lsn_fid, statp, st_waiting_lsn);
JAVADB_STAT_LSN(jnienv, jobj, rep_stat_st_max_perm_lsn_fid, statp, st_max_perm_lsn);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_next_pg_fid, statp, st_next_pg);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_waiting_pg_fid, statp, st_waiting_pg);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_dupmasters_fid, statp, st_dupmasters);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_env_id_fid, statp, st_env_id);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_env_priority_fid, statp, st_env_priority);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_bulk_fills_fid, statp, st_bulk_fills);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_bulk_overflows_fid, statp, st_bulk_overflows);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_bulk_records_fid, statp, st_bulk_records);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_bulk_transfers_fid, statp, st_bulk_transfers);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_client_rerequests_fid, statp, st_client_rerequests);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_client_svc_req_fid, statp, st_client_svc_req);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_client_svc_miss_fid, statp, st_client_svc_miss);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_gen_fid, statp, st_gen);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_egen_fid, statp, st_egen);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_duplicated_fid, statp, st_log_duplicated);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_queued_max_fid, statp, st_log_queued_max);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_queued_total_fid, statp, st_log_queued_total);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_records_fid, statp, st_log_records);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_log_requested_fid, statp, st_log_requested);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_master_fid, statp, st_master);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_master_changes_fid, statp, st_master_changes);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_msgs_badgen_fid, statp, st_msgs_badgen);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_msgs_processed_fid, statp, st_msgs_processed);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_msgs_recover_fid, statp, st_msgs_recover);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_msgs_send_failures_fid, statp, st_msgs_send_failures);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_msgs_sent_fid, statp, st_msgs_sent);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_newsites_fid, statp, st_newsites);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_nsites_fid, statp, st_nsites);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_nthrottles_fid, statp, st_nthrottles);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_outdated_fid, statp, st_outdated);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_pg_duplicated_fid, statp, st_pg_duplicated);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_pg_records_fid, statp, st_pg_records);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_pg_requested_fid, statp, st_pg_requested);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_txns_applied_fid, statp, st_txns_applied);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_startsync_delayed_fid, statp, st_startsync_delayed);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_elections_fid, statp, st_elections);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_elections_won_fid, statp, st_elections_won);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_cur_winner_fid, statp, st_election_cur_winner);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_gen_fid, statp, st_election_gen);
JAVADB_STAT_LSN(jnienv, jobj, rep_stat_st_election_lsn_fid, statp, st_election_lsn);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_nsites_fid, statp, st_election_nsites);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_nvotes_fid, statp, st_election_nvotes);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_priority_fid, statp, st_election_priority);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_status_fid, statp, st_election_status);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_tiebreaker_fid, statp, st_election_tiebreaker);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_votes_fid, statp, st_election_votes);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_sec_fid, statp, st_election_sec);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_election_usec_fid, statp, st_election_usec);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_max_lease_sec_fid, statp, st_max_lease_sec);
JAVADB_STAT_INT(jnienv, jobj, rep_stat_st_max_lease_usec_fid, statp, st_max_lease_usec);
return (0);
}
static int __dbj_fill_repmgr_stat(JNIEnv *jnienv,
jobject jobj, struct __db_repmgr_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, repmgr_stat_st_perm_failed_fid, statp, st_perm_failed);
JAVADB_STAT_INT(jnienv, jobj, repmgr_stat_st_msgs_queued_fid, statp, st_msgs_queued);
JAVADB_STAT_INT(jnienv, jobj, repmgr_stat_st_msgs_dropped_fid, statp, st_msgs_dropped);
JAVADB_STAT_INT(jnienv, jobj, repmgr_stat_st_connection_drop_fid, statp, st_connection_drop);
JAVADB_STAT_INT(jnienv, jobj, repmgr_stat_st_connect_fail_fid, statp, st_connect_fail);
return (0);
}
static int __dbj_fill_seq_stat(JNIEnv *jnienv,
jobject jobj, struct __db_seq_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, seq_stat_st_wait_fid, statp, st_wait);
JAVADB_STAT_INT(jnienv, jobj, seq_stat_st_nowait_fid, statp, st_nowait);
JAVADB_STAT_LONG(jnienv, jobj, seq_stat_st_current_fid, statp, st_current);
JAVADB_STAT_LONG(jnienv, jobj, seq_stat_st_value_fid, statp, st_value);
JAVADB_STAT_LONG(jnienv, jobj, seq_stat_st_last_value_fid, statp, st_last_value);
JAVADB_STAT_LONG(jnienv, jobj, seq_stat_st_min_fid, statp, st_min);
JAVADB_STAT_LONG(jnienv, jobj, seq_stat_st_max_fid, statp, st_max);
JAVADB_STAT_INT(jnienv, jobj, seq_stat_st_cache_size_fid, statp, st_cache_size);
JAVADB_STAT_INT(jnienv, jobj, seq_stat_st_flags_fid, statp, st_flags);
return (0);
}
static int __dbj_fill_txn_stat(JNIEnv *jnienv,
jobject jobj, struct __db_txn_stat *statp) {
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_nrestores_fid, statp, st_nrestores);
JAVADB_STAT_LSN(jnienv, jobj, txn_stat_st_last_ckp_fid, statp, st_last_ckp);
JAVADB_STAT_LONG(jnienv, jobj, txn_stat_st_time_ckp_fid, statp, st_time_ckp);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_last_txnid_fid, statp, st_last_txnid);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_maxtxns_fid, statp, st_maxtxns);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_naborts_fid, statp, st_naborts);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_nbegins_fid, statp, st_nbegins);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_ncommits_fid, statp, st_ncommits);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_nactive_fid, statp, st_nactive);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_nsnapshot_fid, statp, st_nsnapshot);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_maxnactive_fid, statp, st_maxnactive);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_maxnsnapshot_fid, statp, st_maxnsnapshot);
JAVADB_STAT_ACTIVE(jnienv, jobj, txn_stat_st_txnarray_fid, statp, st_txnarray);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_region_wait_fid, statp, st_region_wait);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_region_nowait_fid, statp, st_region_nowait);
JAVADB_STAT_INT(jnienv, jobj, txn_stat_st_regsize_fid, statp, st_regsize);
return (0);
}
static int __dbj_fill_txn_active(JNIEnv *jnienv,
jobject jobj, struct __db_txn_active *statp) {
JAVADB_STAT_INT(jnienv, jobj, txn_active_txnid_fid, statp, txnid);
JAVADB_STAT_INT(jnienv, jobj, txn_active_parentid_fid, statp, parentid);
JAVADB_STAT_INT(jnienv, jobj, txn_active_pid_fid, statp, pid);
JAVADB_STAT_LSN(jnienv, jobj, txn_active_lsn_fid, statp, lsn);
JAVADB_STAT_LSN(jnienv, jobj, txn_active_read_lsn_fid, statp, read_lsn);
JAVADB_STAT_INT(jnienv, jobj, txn_active_mvcc_ref_fid, statp, mvcc_ref);
JAVADB_STAT_INT(jnienv, jobj, txn_active_status_fid, statp, status);
JAVADB_STAT_INT(jnienv, jobj, txn_active_xa_status_fid, statp, xa_status);
JAVADB_STAT_XID(jnienv, jobj, txn_active_xid_fid, statp, xid);
JAVADB_STAT_STRING(jnienv, jobj, txn_active_name_fid, statp, name);
return (0);
}

759
libdb_java/java_typemaps.i Normal file
View File

@@ -0,0 +1,759 @@
/* Typemaps */
%define JAVA_TYPEMAP(_ctype, _jtype, _jnitype)
%typemap(jstype) _ctype #_jtype
%typemap(jtype) _ctype #_jtype
%typemap(jni) _ctype #_jnitype
%typemap(out) _ctype %{ $result = (_jnitype)$1; %}
%typemap(javain) _ctype "$javainput"
%typemap(javaout) _ctype { return $jnicall; }
%enddef
JAVA_TYPEMAP(int32_t, int, jint)
JAVA_TYPEMAP(u_int32_t, int, jint)
JAVA_TYPEMAP(u_int32_t pagesize, long, jlong)
JAVA_TYPEMAP(long, long, jlong)
JAVA_TYPEMAP(db_seq_t, long, jlong)
JAVA_TYPEMAP(pid_t, long, jlong)
#ifndef SWIGJAVA
JAVA_TYPEMAP(db_threadid_t, long, jlong)
#endif
JAVA_TYPEMAP(db_timeout_t, long, jlong)
JAVA_TYPEMAP(size_t, long, jlong)
JAVA_TYPEMAP(db_ret_t, void, void)
%typemap(javaout) db_ret_t { $jnicall; }
%typemap(out) db_ret_t ""
JAVA_TYPEMAP(int_bool, boolean, jboolean)
%typemap(in) int_bool %{ $1 = ($input == JNI_TRUE); %}
%typemap(out) int_bool %{ $result = ($1) ? JNI_TRUE : JNI_FALSE; %}
/* Dbt handling */
JAVA_TYPEMAP(DBT *, com.sleepycat.db.DatabaseEntry, jobject)
%{
typedef struct __dbt_locked {
JNIEnv *jenv;
jobject jdbt;
DBT dbt;
jobject jdata_nio;
jbyteArray jarr;
jint offset;
int reuse;
u_int32_t orig_size;
jsize array_len;
} DBT_LOCKED;
static int __dbj_dbt_memcopy(DBT *dbt, u_int32_t offset, void *buf, u_int32_t size, u_int32_t flags) {
DBT_LOCKED *ldbt = dbt->app_data;
JNIEnv *jenv = ldbt->jenv;
if (size == 0)
return (0);
else if (!F_ISSET(dbt, DB_DBT_USERCOPY)) {
/*
* For simplicity, the Java API calls this function directly,
* so it needs to work with regular DBTs.
*/
switch (flags) {
case DB_USERCOPY_GETDATA:
memcpy(buf, (u_int8_t *)dbt->data + offset, size);
return (0);
case DB_USERCOPY_SETDATA:
memcpy((u_int8_t *)dbt->data + offset, buf, size);
return (0);
default:
return (EINVAL);
}
}
switch (flags) {
case DB_USERCOPY_GETDATA:
(*jenv)->GetByteArrayRegion(jenv, ldbt->jarr, ldbt->offset +
offset, size, buf);
break;
case DB_USERCOPY_SETDATA:
/*
* Check whether this is the first time through the callback by relying
* on the offset being zero.
*/
if (offset == 0 && (!ldbt->reuse ||
(jsize)(ldbt->offset + dbt->size) > ldbt->array_len)) {
if (ldbt->jarr != NULL)
(*jenv)->DeleteLocalRef(jenv, ldbt->jarr);
ldbt->jarr = (*jenv)->NewByteArray(jenv, (jsize)dbt->size);
if (ldbt->jarr == NULL)
return (ENOMEM);
(*jenv)->SetObjectField(jenv, ldbt->jdbt, dbt_data_fid, ldbt->jarr);
/* We've allocated a new array, start from the beginning. */
ldbt->offset = 0;
}
(*jenv)->SetByteArrayRegion(jenv, ldbt->jarr, ldbt->offset +
offset, size, buf);
break;
default:
return (EINVAL);
}
return ((*jenv)->ExceptionOccurred(jenv) ? EINVAL : 0);
}
static void __dbj_dbt_copyout(
JNIEnv *jenv, const DBT *dbt, jbyteArray *jarr, jobject jdbt)
{
jbyteArray newarr = (*jenv)->NewByteArray(jenv, (jsize)dbt->size);
if (newarr == NULL)
return; /* An exception is pending */
(*jenv)->SetByteArrayRegion(jenv, newarr, 0, (jsize)dbt->size,
(jbyte *)dbt->data);
(*jenv)->SetObjectField(jenv, jdbt, dbt_data_fid, newarr);
(*jenv)->SetIntField(jenv, jdbt, dbt_offset_fid, 0);
(*jenv)->SetIntField(jenv, jdbt, dbt_size_fid, (jint)dbt->size);
if (jarr != NULL)
*jarr = newarr;
else
(*jenv)->DeleteLocalRef(jenv, newarr);
}
static int __dbj_dbt_copyin(
JNIEnv *jenv, DBT_LOCKED *ldbt, DBT **dbtp, jobject jdbt, int allow_null)
{
DBT *dbt;
jlong capacity;
memset(ldbt, 0, sizeof (*ldbt));
ldbt->jenv = jenv;
ldbt->jdbt = jdbt;
if (jdbt == NULL) {
if (allow_null) {
*dbtp = NULL;
return (0);
} else {
return (__dbj_throw(jenv, EINVAL,
"DatabaseEntry must not be null", NULL, NULL));
}
}
dbt = &ldbt->dbt;
if (dbtp != NULL)
*dbtp = dbt;
ldbt->jdata_nio = (*jenv)->GetObjectField(jenv, jdbt, dbt_data_nio_fid);
if (ldbt->jdata_nio != NULL)
F_SET(dbt, DB_DBT_USERMEM);
else
ldbt->jarr = (jbyteArray)(*jenv)->GetObjectField(jenv, jdbt, dbt_data_fid);
ldbt->offset = (*jenv)->GetIntField(jenv, jdbt, dbt_offset_fid);
dbt->size = (*jenv)->GetIntField(jenv, jdbt, dbt_size_fid);
ldbt->orig_size = dbt->size;
dbt->flags = (*jenv)->GetIntField(jenv, jdbt, dbt_flags_fid);
if (F_ISSET(dbt, DB_DBT_USERMEM))
dbt->ulen = (*jenv)->GetIntField(jenv, jdbt, dbt_ulen_fid);
if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
dbt->dlen = (*jenv)->GetIntField(jenv, jdbt, dbt_dlen_fid);
dbt->doff = (*jenv)->GetIntField(jenv, jdbt, dbt_doff_fid);
if ((jint)dbt->doff < 0)
return (__dbj_throw(jenv, EINVAL, "DatabaseEntry doff illegal",
NULL, NULL));
}
/*
* We don't support DB_DBT_REALLOC - map anything that's not USERMEM to
* MALLOC.
*/
if (!F_ISSET(dbt, DB_DBT_USERMEM)) {
ldbt->reuse = !F_ISSET(dbt, DB_DBT_MALLOC);
F_CLR(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC);
}
/* Verify parameters before allocating or locking data. */
if (ldbt->jdata_nio != NULL) {
capacity = (*jenv)->GetDirectBufferCapacity(jenv,
ldbt->jdata_nio);
if (capacity > (jlong)UINT32_MAX)
return (__dbj_throw(jenv, EINVAL,
"DirectBuffer may not be larger than 4GB",
NULL, NULL));
ldbt->array_len = (u_int32_t)capacity;
} else if (ldbt->jarr == NULL) {
/*
* Some code makes the assumption that if a DBT's size or ulen
* is non-zero, there is data to copy from dbt->data.
*
* Clean up the dbt fields so we don't run into trouble.
* (Note that doff, dlen, and flags all may contain
* meaningful values.)
*/
dbt->data = NULL;
ldbt->array_len = ldbt->offset = dbt->size = dbt->ulen = 0;
} else
ldbt->array_len = (*jenv)->GetArrayLength(jenv, ldbt->jarr);
if (F_ISSET(dbt, DB_DBT_USERMEM)) {
if (ldbt->offset < 0)
return (__dbj_throw(jenv, EINVAL,
"offset cannot be negative",
NULL, NULL));
if (dbt->size > dbt->ulen)
return (__dbj_throw(jenv, EINVAL,
"size must be less than or equal to ulen",
NULL, NULL));
if ((jsize)(ldbt->offset + dbt->ulen) > ldbt->array_len)
return (__dbj_throw(jenv, EINVAL,
"offset + ulen greater than array length",
NULL, NULL));
}
if (ldbt->jdata_nio) {
dbt->data = (*jenv)->GetDirectBufferAddress(jenv,
ldbt->jdata_nio);
dbt->data = (u_int8_t *)dbt->data + ldbt->offset;
} else if (F_ISSET(dbt, DB_DBT_USERMEM)) {
if (ldbt->jarr != NULL &&
(dbt->data = (*jenv)->GetByteArrayElements(jenv,
ldbt->jarr, NULL)) == NULL)
return (EINVAL); /* an exception will be pending */
dbt->data = (u_int8_t *)dbt->data + ldbt->offset;
} else
F_SET(dbt, DB_DBT_USERCOPY);
dbt->app_data = ldbt;
return (0);
}
static void __dbj_dbt_release(
JNIEnv *jenv, jobject jdbt, DBT *dbt, DBT_LOCKED *ldbt) {
jthrowable t;
if (dbt == NULL)
return;
if (dbt->size != ldbt->orig_size)
(*jenv)->SetIntField(jenv, jdbt, dbt_size_fid, (jint)dbt->size);
if (F_ISSET(dbt, DB_DBT_USERMEM)) {
if (ldbt->jarr != NULL)
(*jenv)->ReleaseByteArrayElements(jenv, ldbt->jarr,
(jbyte *)dbt->data - ldbt->offset, 0);
if (dbt->size > dbt->ulen &&
(t = (*jenv)->ExceptionOccurred(jenv)) != NULL &&
(*jenv)->IsInstanceOf(jenv, t, memex_class)) {
(*jenv)->CallNonvirtualVoidMethod(jenv, t, memex_class,
memex_update_method, jdbt);
/*
* We have to rethrow the exception because calling
* into Java clears it.
*/
(*jenv)->Throw(jenv, t);
}
}
}
%}
%typemap(in) DBT * (DBT_LOCKED ldbt) %{
if (__dbj_dbt_copyin(jenv, &ldbt, &$1, $input, 0) != 0) {
return $null; /* An exception will be pending. */
}%}
/* Special cases for DBTs that may be null: DbEnv.rep_start and Db.compact */
%typemap(in) DBT *data_or_null (DBT_LOCKED ldbt) %{
if (__dbj_dbt_copyin(jenv, &ldbt, &$1, $input, 1) != 0) {
return $null; /* An exception will be pending. */
}%}
%apply DBT *data_or_null {DBT *cdata, DBT *start, DBT *stop, DBT *end};
%typemap(freearg) DBT * %{ __dbj_dbt_release(jenv, $input, $1, &ldbt$argnum); %}
/* DbLsn handling */
JAVA_TYPEMAP(DB_LSN *, com.sleepycat.db.LogSequenceNumber, jobject)
%typemap(check) DB_LSN *lsn_or_null ""
%typemap(check) DB_LSN * %{
if ($1 == NULL) {
__dbj_throw(jenv, EINVAL, "null LogSequenceNumber", NULL, NULL);
return $null;
}
%}
%typemap(in) DB_LSN * (DB_LSN lsn) %{
if ($input == NULL) {
$1 = NULL;
} else {
$1 = &lsn;
$1->file = (*jenv)->GetIntField(jenv, $input, dblsn_file_fid);
$1->offset = (*jenv)->GetIntField(jenv, $input,
dblsn_offset_fid);
}
%}
%typemap(freearg) DB_LSN * %{
if ($input != NULL) {
(*jenv)->SetIntField(jenv, $input, dblsn_file_fid, $1->file);
(*jenv)->SetIntField(jenv, $input,
dblsn_offset_fid, $1->offset);
}
%}
/* Various typemaps */
JAVA_TYPEMAP(time_t, long, jlong)
JAVA_TYPEMAP(time_t *, long, jlong)
%typemap(in) time_t * (time_t time) %{
time = (time_t)$input;
$1 = &time;
%}
JAVA_TYPEMAP(DB_KEY_RANGE *, com.sleepycat.db.KeyRange, jobject)
%typemap(in) DB_KEY_RANGE * (DB_KEY_RANGE range) {
$1 = &range;
}
%typemap(argout) DB_KEY_RANGE * {
(*jenv)->SetDoubleField(jenv, $input, kr_less_fid, $1->less);
(*jenv)->SetDoubleField(jenv, $input, kr_equal_fid, $1->equal);
(*jenv)->SetDoubleField(jenv, $input, kr_greater_fid, $1->greater);
}
JAVA_TYPEMAP(DBC **, Dbc[], jobjectArray)
%typemap(in) DBC ** {
int i, count, err;
count = (*jenv)->GetArrayLength(jenv, $input);
if ((err = __os_malloc(NULL, (count + 1) * sizeof(DBC *), &$1)) != 0) {
__dbj_throw(jenv, err, NULL, NULL, DB2JDBENV);
return $null;
}
for (i = 0; i < count; i++) {
jobject jobj = (*jenv)->GetObjectArrayElement(jenv, $input, i);
/*
* A null in the array is treated as an endpoint.
*/
if (jobj == NULL) {
$1[i] = NULL;
break;
} else {
jlong jptr = (*jenv)->GetLongField(jenv, jobj,
dbc_cptr_fid);
$1[i] = *(DBC **)(void *)&jptr;
}
}
$1[count] = NULL;
}
%typemap(freearg) DBC ** %{
__os_free(NULL, $1);
%}
JAVA_TYPEMAP(u_int8_t *gid, byte[], jbyteArray)
%typemap(check) u_int8_t *gid %{
if ((*jenv)->GetArrayLength(jenv, $input) < DB_XIDDATASIZE) {
__dbj_throw(jenv, EINVAL,
"DbTxn.prepare gid array must be >= 128 bytes", NULL,
TXN2JDBENV);
return $null;
}
%}
%typemap(in) u_int8_t *gid %{
$1 = (u_int8_t *)(*jenv)->GetByteArrayElements(jenv, $input, NULL);
%}
%typemap(freearg) u_int8_t *gid %{
(*jenv)->ReleaseByteArrayElements(jenv, $input, (jbyte *)$1, 0);
%}
%define STRING_ARRAY_OUT
int i, len;
len = 0;
while ($1[len] != NULL)
len++;
if (($result = (*jenv)->NewObjectArray(jenv, (jsize)len, string_class,
NULL)) == NULL)
return $null; /* an exception is pending */
for (i = 0; i < len; i++) {
jstring str = (*jenv)->NewStringUTF(jenv, $1[i]);
(*jenv)->SetObjectArrayElement(jenv, $result, (jsize)i, str);
}
%enddef
JAVA_TYPEMAP(char **, String[], jobjectArray)
%typemap(out) const char ** {
if ($1 != NULL) {
STRING_ARRAY_OUT
}
}
%typemap(out) char ** {
if ($1 != NULL) {
STRING_ARRAY_OUT
__os_ufree(NULL, $1);
}
}
JAVA_TYPEMAP(struct __db_lk_conflicts, byte[][], jobjectArray)
%typemap(in) struct __db_lk_conflicts {
int i, len, err;
size_t bytesize;
len = $1.lk_modes = (*jenv)->GetArrayLength(jenv, $input);
bytesize = sizeof(u_char) * len * len;
if ((err = __os_malloc(NULL, bytesize, &$1.lk_conflicts)) != 0) {
__dbj_throw(jenv, err, NULL, NULL, JDBENV);
return $null;
}
for (i = 0; i < len; i++) {
jobject sub_array = (*jenv)->GetObjectArrayElement(jenv,
$input, i);
(*jenv)->GetByteArrayRegion(jenv,(jbyteArray)sub_array, 0, len,
(jbyte *)&$1.lk_conflicts[i * len]);
}
}
%typemap(freearg) struct __db_lk_conflicts %{
__os_free(NULL, $1.lk_conflicts);
%}
%typemap(out) struct __db_lk_conflicts {
int i;
jbyteArray bytes;
$result = (*jenv)->NewObjectArray(jenv,
(jsize)$1.lk_modes, bytearray_class, NULL);
if ($result == NULL)
return $null; /* an exception is pending */
for (i = 0; i < $1.lk_modes; i++) {
bytes = (*jenv)->NewByteArray(jenv, (jsize)$1.lk_modes);
if (bytes == NULL)
return $null; /* an exception is pending */
(*jenv)->SetByteArrayRegion(jenv, bytes, 0, (jsize)$1.lk_modes,
(jbyte *)($1.lk_conflicts + i * $1.lk_modes));
(*jenv)->SetObjectArrayElement(jenv, $result, (jsize)i, bytes);
}
}
%{
struct __dbj_verify_data {
JNIEnv *jenv;
jobject streamobj;
jbyteArray bytes;
int nbytes;
};
static int __dbj_verify_callback(void *handle, const void *str_arg) {
char *str;
struct __dbj_verify_data *vd;
int len;
JNIEnv *jenv;
str = (char *)str_arg;
vd = (struct __dbj_verify_data *)handle;
jenv = vd->jenv;
len = strlen(str) + 1;
if (len > vd->nbytes) {
vd->nbytes = len;
if (vd->bytes != NULL)
(*jenv)->DeleteLocalRef(jenv, vd->bytes);
if ((vd->bytes = (*jenv)->NewByteArray(jenv, (jsize)len))
== NULL)
return (ENOMEM);
}
if (vd->bytes != NULL) {
(*jenv)->SetByteArrayRegion(jenv, vd->bytes, 0, (jsize)len,
(jbyte*)str);
(*jenv)->CallVoidMethod(jenv, vd->streamobj,
outputstream_write_method, vd->bytes, 0, len - 1);
}
if ((*jenv)->ExceptionOccurred(jenv) != NULL)
return (EIO);
return (0);
}
%}
JAVA_TYPEMAP(struct __db_out_stream, java.io.OutputStream, jobject)
%typemap(in) struct __db_out_stream (struct __dbj_verify_data data) {
data.jenv = jenv;
data.streamobj = $input;
data.bytes = NULL;
data.nbytes = 0;
$1.handle = &data;
$1.callback = __dbj_verify_callback;
}
JAVA_TYPEMAP(DB_PREPLIST *, com.sleepycat.db.PreparedTransaction[],
jobjectArray)
%typemap(out) DB_PREPLIST * {
int i, len;
len = 0;
while ($1[len].txn != NULL)
len++;
$result = (*jenv)->NewObjectArray(jenv, (jsize)len, dbpreplist_class,
NULL);
if ($result == NULL)
return $null; /* an exception is pending */
for (i = 0; i < len; i++) {
jobject jtxn = (*jenv)->NewObject(jenv, dbtxn_class,
dbtxn_construct, $1[i].txn, JNI_FALSE);
jobject bytearr = (*jenv)->NewByteArray(jenv,
(jsize)sizeof($1[i].gid));
jobject obj = (*jenv)->NewObject(jenv, dbpreplist_class,
dbpreplist_construct, jtxn, bytearr);
if (jtxn == NULL || bytearr == NULL || obj == NULL)
return $null; /* An exception is pending */
(*jenv)->SetByteArrayRegion(jenv, bytearr, 0,
(jsize)sizeof($1[i].gid), (jbyte *)$1[i].gid);
(*jenv)->SetObjectArrayElement(jenv, $result, i, obj);
}
__os_ufree(NULL, $1);
}
JAVA_TYPEMAP(DB_LOCKREQ *, com.sleepycat.db.LockRequest[], jobjectArray)
%native(DbEnv_lock_vec) void DbEnv_lock_vec(DB_ENV *dbenv, u_int32_t locker,
u_int32_t flags, DB_LOCKREQ *list, int offset, int nlist);
%{
SWIGEXPORT void JNICALL
Java_com_sleepycat_db_internal_db_1javaJNI_DbEnv_1lock_1vec(JNIEnv *jenv,
jclass jcls, jlong jdbenvp, jobject jdbenv, jint locker, jint flags,
jobjectArray list, jint offset, jint count) {
DB_ENV *dbenv;
DB_LOCKREQ *lockreq;
DB_LOCKREQ *prereq; /* preprocessed requests */
DB_LOCKREQ *failedreq;
DB_LOCK *lockp;
DBT_LOCKED *locked_dbts;
DBT *obj;
ENV *env;
int err, alloc_err, i;
size_t bytesize, ldbtsize;
jobject jlockreq;
db_lockop_t op;
jobject jobj, jlock;
jlong jlockp;
int completed;
COMPQUIET(jcls, NULL);
dbenv = *(DB_ENV **)(void *)&jdbenvp;
env = dbenv->env;
if (dbenv == NULL) {
__dbj_throw(jenv, EINVAL, "null object", NULL, jdbenv);
return;
}
if ((*jenv)->GetArrayLength(jenv, list) < offset + count) {
__dbj_throw(jenv, EINVAL,
"DbEnv.lock_vec array not large enough", NULL, jdbenv);
goto out0;
}
bytesize = sizeof(DB_LOCKREQ) * count;
if ((err = __os_malloc(env, bytesize, &lockreq)) != 0) {
__dbj_throw(jenv, err, NULL, NULL, jdbenv);
goto out0;
}
memset(lockreq, 0, bytesize);
ldbtsize = sizeof(DBT_LOCKED) * count;
if ((err = __os_malloc(env, ldbtsize, &locked_dbts)) != 0) {
__dbj_throw(jenv, err, NULL, NULL, jdbenv);
goto out1;
}
memset(locked_dbts, 0, ldbtsize);
prereq = &lockreq[0];
/* fill in the lockreq array */
for (i = 0, prereq = &lockreq[0]; i < count; i++, prereq++) {
jlockreq = (*jenv)->GetObjectArrayElement(jenv, list,
offset + i);
if (jlockreq == NULL) {
__dbj_throw(jenv, EINVAL,
"DbEnv.lock_vec list entry is null", NULL, jdbenv);
goto out2;
}
op = (*jenv)->GetIntField(jenv, jlockreq, lockreq_op_fid);
prereq->op = op;
switch (op) {
case DB_LOCK_GET_TIMEOUT:
/* Needed: mode, timeout, obj. Returned: lock. */
prereq->op = (*jenv)->GetIntField(jenv, jlockreq,
lockreq_timeout_fid);
/* FALLTHROUGH */
case DB_LOCK_GET:
/* Needed: mode, obj. Returned: lock. */
prereq->mode = (*jenv)->GetIntField(jenv, jlockreq,
lockreq_modeflag_fid);
jobj = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_obj_fid);
if ((err = __dbj_dbt_copyin(jenv,
&locked_dbts[i], &obj, jobj, 0)) != 0 ||
(err =
__os_umalloc(env, obj->size, &obj->data)) != 0 ||
(err = __dbj_dbt_memcopy(obj, 0,
obj->data, obj->size, DB_USERCOPY_GETDATA)) != 0)
goto out2;
prereq->obj = obj;
break;
case DB_LOCK_PUT:
/* Needed: lock. Ignored: mode, obj. */
jlock = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_lock_fid);
if (jlock == NULL ||
(jlockp = (*jenv)->GetLongField(jenv, jlock,
lock_cptr_fid)) == 0L) {
__dbj_throw(jenv, EINVAL,
"LockRequest lock field is NULL", NULL,
jdbenv);
goto out2;
}
lockp = *(DB_LOCK **)(void *)&jlockp;
prereq->lock = *lockp;
break;
case DB_LOCK_PUT_ALL:
case DB_LOCK_TIMEOUT:
/* Needed: (none). Ignored: lock, mode, obj. */
break;
case DB_LOCK_PUT_OBJ:
/* Needed: obj. Ignored: lock, mode. */
jobj = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_obj_fid);
if ((err = __dbj_dbt_copyin(jenv,
&locked_dbts[i], &obj, jobj, 0)) != 0 ||
(err =
__os_umalloc(env, obj->size, &obj->data)) != 0 ||
(err = __dbj_dbt_memcopy(obj, 0,
obj->data, obj->size, DB_USERCOPY_GETDATA)) != 0)
goto out2;
prereq->obj = obj;
break;
default:
__dbj_throw(jenv, EINVAL,
"DbEnv.lock_vec bad op value", NULL, jdbenv);
goto out2;
}
}
err = dbenv->lock_vec(dbenv, (u_int32_t)locker, (u_int32_t)flags,
lockreq, count, &failedreq);
if (err == 0)
completed = count;
else
completed = failedreq - lockreq;
/* do post processing for any and all requests that completed */
for (i = 0; i < completed; i++) {
op = lockreq[i].op;
if (op == DB_LOCK_PUT) {
/*
* After a successful put, the DbLock can no longer be
* used, so we release the storage related to it.
*/
jlockreq = (*jenv)->GetObjectArrayElement(jenv,
list, i + offset);
jlock = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_lock_fid);
jlockp = (*jenv)->GetLongField(jenv, jlock,
lock_cptr_fid);
lockp = *(DB_LOCK **)(void *)&jlockp;
__os_free(NULL, lockp);
(*jenv)->SetLongField(jenv, jlock, lock_cptr_fid,
(jlong)0);
}
else if (op == DB_LOCK_GET) {
/*
* Store the lock that was obtained. We need to create
* storage for it since the lockreq array only exists
* during this method call.
*/
if ((alloc_err =
__os_malloc(env, sizeof(DB_LOCK), &lockp)) != 0) {
__dbj_throw(jenv, alloc_err, NULL, NULL,
jdbenv);
goto out2;
}
*lockp = lockreq[i].lock;
*(DB_LOCK **)(void *)&jlockp = lockp;
jlockreq = (*jenv)->GetObjectArrayElement(jenv,
list, i + offset);
jlock = (*jenv)->NewObject(jenv, lock_class,
lock_construct, jlockp, JNI_TRUE);
if (jlock == NULL)
goto out2; /* An exception is pending */
(*jenv)->SetLongField(jenv, jlock, lock_cptr_fid,
jlockp);
(*jenv)->SetObjectField(jenv, jlockreq,
lockreq_lock_fid, jlock);
}
}
/* If one of the locks was not granted, build the exception now. */
if (err == DB_LOCK_NOTGRANTED && i < count) {
jlockreq = (*jenv)->GetObjectArrayElement(jenv, list,
i + offset);
jobj = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_obj_fid);
jlock = (*jenv)->GetObjectField(jenv, jlockreq,
lockreq_lock_fid);
(*jenv)->Throw(jenv,
(*jenv)->NewObject(jenv, lockex_class, lockex_construct,
(*jenv)->NewStringUTF(jenv, "DbEnv.lock_vec incomplete"),
lockreq[i].op, lockreq[i].mode, jobj, jlock, i, jdbenv));
} else if (err != 0)
__dbj_throw(jenv, err, NULL, NULL, jdbenv);
out2: __os_free(env, locked_dbts);
out1: for (i = 0, prereq = &lockreq[0]; i < count; i++, prereq++)
if ((prereq->op == DB_LOCK_GET || prereq->op == DB_LOCK_PUT) &&
prereq->obj->data != NULL)
__os_ufree(env, prereq->obj->data);
__os_free(env, lockreq);
out0: return;
}
%}
JAVA_TYPEMAP(struct __db_repmgr_sites,
com.sleepycat.db.ReplicationManagerSiteInfo[], jobjectArray)
%typemap(out) struct __db_repmgr_sites
{
int i, len;
jobject jrep_addr, jrep_info;
len = $1.nsites;
$result = (*jenv)->NewObjectArray(jenv, (jsize)len, repmgr_siteinfo_class,
NULL);
if ($result == NULL)
return $null; /* an exception is pending */
for (i = 0; i < len; i++) {
jstring addr_host = (*jenv)->NewStringUTF(jenv, $1.sites[i].host);
if (addr_host == NULL)
return $null; /* An exception is pending */
jrep_addr = (*jenv)->NewObject(jenv,
rephost_class, rephost_construct, addr_host, $1.sites[i].port);
if (jrep_addr == NULL)
return $null; /* An exception is pending */
jrep_info = (*jenv)->NewObject(jenv,
repmgr_siteinfo_class, repmgr_siteinfo_construct, jrep_addr, $1.sites[i].eid);
(*jenv)->SetIntField(jenv, jrep_info, repmgr_siteinfo_status_fid,
$1.sites[i].status);
if (jrep_info == NULL)
return $null; /* An exception is pending */
(*jenv)->SetObjectArrayElement(jenv, $result, i, jrep_info);
}
__os_ufree(NULL, $1.sites);
}
JAVA_TYPEMAP(void *, Object, jobject)

1023
libdb_java/java_util.i Normal file

File diff suppressed because it is too large Load Diff