NativeMethods.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/farrago/NativeMethods.cpp#37 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2003-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/farrago/NativeMethods.h"
00026 #include "fennel/farrago/CmdInterpreter.h"
00027 #include "fennel/farrago/JavaTransformExecStream.h"
00028 #include "fennel/farrago/JniUtil.h"
00029 #include "fennel/tuple/TupleAccessor.h"
00030 #include "fennel/tuple/AttributeAccessor.h"
00031 #include "fennel/farrago/Fem.h"
00032 #include "fennel/tuple/StandardTypeDescriptor.h"
00033 #include "fennel/common/ByteInputStream.h"
00034 #include "fennel/segment/DynamicDelegatingSegment.h"
00035 #include "fennel/segment/SegmentFactory.h"
00036 #include "fennel/db/Database.h"
00037 #include "fennel/exec/ExecStreamGraph.h"
00038 #include "fennel/exec/ExecStreamScheduler.h"
00039 #include "fennel/exec/ExecStreamBufAccessor.h"
00040 #include "fennel/exec/ExecStreamGovernor.h"
00041 
00042 #include <sstream>
00043 #include <iostream>
00044 #include <string>
00045 
00046 #ifdef __MSVC__
00047 #include <windows.h>
00048 #else
00049 #include <dlfcn.h>
00050 #endif
00051 
00052 // TODO:  figure out how to get compiler to cross-check method declarations in
00053 // NativeMethods.h!
00054 
00055 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/farrago/NativeMethods.cpp#37 $");
00056 
00057 #define JAVAOBJECTHANDLE_TYPE_STR ("JavaObjectHandle")
00058 
00059 #ifdef __MSVC__
00060 extern "C" JNIEXPORT BOOL APIENTRY DllMain(
00061     HANDLE hModule,
00062     DWORD  ul_reason_for_call,
00063     LPVOID lpReserved)
00064 {
00065     return TRUE;
00066 }
00067 #endif
00068 
00069 extern "C" JNIEXPORT jint JNICALL
00070 JNI_OnLoad(JavaVM *vm,void *reserved)
00071 {
00072     JniUtil::initDebug("FENNEL_JNI_DEBUG");
00073     FENNEL_JNI_ONLOAD_COMMON();
00074     jint version = JniUtil::init(vm);
00075     JniEnvAutoRef pEnv;
00076     try {
00077         staticInitFem(pEnv,FemVisitor::visitTbl);
00078     } catch (std::exception &ex) {
00079         pEnv.handleExcn(ex);
00080     }
00081 
00082     // REVIEW jvs 26-Nov-2004:  I had to put this in to squelch strange
00083     // shutdown problems when extension JNI libraries (such as
00084     // libfarrago_dt and libfarrago_lu) are loaded.  It pins our .so
00085     // artificially, which probably isn't a good thing either.
00086 #ifndef __MSVC__
00087     dlopen("libfarrago.so", RTLD_NOW | RTLD_GLOBAL);
00088 #endif
00089 
00090     return version;
00091 }
00092 
00093 extern "C" JNIEXPORT jlong JNICALL
00094 Java_net_sf_farrago_fennel_FennelStorage_executeJavaCmd(
00095     JNIEnv *pEnvInit, jclass, jobject jCmd, jlong jExecHandle)
00096 {
00097     JniEnvRef pEnv(pEnvInit);
00098     try {
00099         ProxyCmd cmd;
00100         cmd.init(pEnv,jCmd);
00101         CmdInterpreter cmdInterpreter;
00102         if (jExecHandle == 0) {
00103             cmdInterpreter.pExecHandle = NULL;
00104         } else {
00105             CmdInterpreter::ExecutionHandle &execHandle =
00106                 CmdInterpreter::getExecutionHandleFromLong(jExecHandle);
00107             cmdInterpreter.pExecHandle = &execHandle;
00108         }
00109         return cmdInterpreter.executeCommand(cmd);
00110     } catch (std::exception &ex) {
00111         pEnv.handleExcn(ex);
00112         return 0;
00113     }
00114 }
00115 
00116 extern "C" JNIEXPORT jint JNICALL
00117 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamFetch(
00118     JNIEnv *pEnvInit, jclass, jlong hStream, jbyteArray byteArray)
00119 {
00120     JniEnvRef pEnv(pEnvInit);
00121     try {
00122         ExecStream &stream =
00123             CmdInterpreter::getExecStreamFromLong(hStream);
00124         ExecStreamScheduler *scheduler = stream.getGraph().getScheduler();
00125         assert(scheduler);
00126         ExecStreamBufAccessor &bufAccessor = scheduler->readStream(stream);
00127         if (bufAccessor.getState() == EXECBUF_EOS) {
00128             return 0;
00129         }
00130         assert(bufAccessor.isConsumptionPossible());
00131         uint cbLimit = uint(pEnv->GetArrayLength(byteArray));
00132         uint cbActual = bufAccessor.getConsumptionAvailableBounded(cbLimit);
00133         assert(cbActual);
00134         PConstBuffer pBuffer = bufAccessor.getConsumptionStart();
00135         assert(cbLimit >= cbActual);
00136         pEnv->SetByteArrayRegion(
00137             byteArray,0,cbActual,(jbyte *)(pBuffer));
00138         bufAccessor.consumeData(pBuffer + cbActual);
00139         return cbActual;
00140     } catch (std::exception &ex) {
00141         pEnv.handleExcn(ex);
00142         return 0;
00143     }
00144 }
00145 
00146 extern "C" JNIEXPORT jint JNICALL
00147 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamTransformFetch(
00148     JNIEnv *pEnvInit, jclass, jlong hStream, jint inputOrdinal,
00149     jbyteArray byteArray)
00150 {
00151     JniEnvRef pEnv(pEnvInit);
00152     try {
00153         ExecStream &stream =
00154             CmdInterpreter::getExecStreamFromLong(hStream);
00155 
00156         uint iInput = static_cast<uint>(inputOrdinal);
00157 
00158         SharedExecStreamBufAccessor bufAccessor =
00159             stream.getGraph().getStreamInputAccessor(
00160                 stream.getStreamId(), iInput);
00161 
00162         if (bufAccessor->getState() == EXECBUF_EOS) {
00163             return 0;
00164         }
00165 
00166         if (!bufAccessor->isConsumptionPossible()) {
00167             return -1;
00168         }
00169 
00170         uint cbLimit = uint(pEnv->GetArrayLength(byteArray));
00171         uint cbActual = bufAccessor->getConsumptionAvailableBounded(cbLimit);
00172         assert(cbActual);
00173         PConstBuffer pBuffer = bufAccessor->getConsumptionStart();
00174         assert(cbLimit >= cbActual);
00175         pEnv->SetByteArrayRegion(
00176             byteArray,0,cbActual,(jbyte *)(pBuffer));
00177         bufAccessor->consumeData(pBuffer + cbActual);
00178         return cbActual;
00179     } catch (std::exception &ex) {
00180         pEnv.handleExcn(ex);
00181         return 0;
00182     }
00183 }
00184 
00185 extern "C" JNIEXPORT void JNICALL
00186 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamGraphGetInputStreams(
00187     JNIEnv *pEnvInit, jclass,
00188     jlong hStreamGraph, jstring baseName, jobject inputStreamNameList)
00189 {
00190     JniEnvRef pEnv(pEnvInit);
00191     try {
00192         // TODO lift these to JniUtil:
00193         jclass classList = pEnv->FindClass("java/util/List");
00194         jmethodID methListAdd = pEnv->GetMethodID(classList, "add", "(Ljava/lang/Object;)Z");
00195         CmdInterpreter::StreamGraphHandle &streamGraphHandle =
00196             CmdInterpreter::getStreamGraphHandleFromLong(hStreamGraph);
00197         SharedExecStreamGraph pgraph = streamGraphHandle.pExecStreamGraph;
00198         assert(pgraph);
00199 
00200         SharedExecStream base =
00201             pgraph->findStream(JniUtil::toStdString(pEnv, baseName));
00202         assert(base);
00203         uint ct = pgraph->getInputCount(base->getStreamId());
00204         for (uint i = 0; i < ct; i++) {
00205             SharedExecStream input =
00206                 pgraph->getStreamInput(base->getStreamId(), i);
00207             assert(input);
00208             jstring inputName = pEnv->NewStringUTF(input->getName().c_str());
00209             pEnv->CallObjectMethod(inputStreamNameList, methListAdd, inputName);
00210         }
00211     } catch (std::exception &ex) {
00212         pEnv.handleExcn(ex);
00213     }
00214 }
00215 
00216 extern "C" JNIEXPORT void JNICALL
00217 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamRestart(
00218     JNIEnv *pEnvInit, jclass, jlong hStream)
00219 {
00220     JniEnvRef pEnv(pEnvInit);
00221     try {
00222         ExecStream &stream =
00223             CmdInterpreter::getExecStreamFromLong(hStream);
00224         stream.open(true);
00225     } catch (std::exception &ex) {
00226         pEnv.handleExcn(ex);
00227     }
00228 }
00229 
00230 extern "C" JNIEXPORT void JNICALL
00231 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamGraphOpen(
00232     JNIEnv *pEnvInit, jclass, jlong hStreamGraph, jlong hTxn,
00233     jobject hJavaStreamMap, jobject hJavaErrorTarget)
00234 {
00235     JniEnvRef pEnv(pEnvInit);
00236     try {
00237         CmdInterpreter::StreamGraphHandle &streamGraphHandle =
00238             CmdInterpreter::getStreamGraphHandleFromLong(hStreamGraph);
00239         CmdInterpreter::TxnHandle &txnHandle =
00240             CmdInterpreter::getTxnHandleFromLong(hTxn);
00241         // Provide runtime context for stream open(), which a scheduler may
00242         // defer til after out java caller returns: hence the global ref.
00243         streamGraphHandle.javaRuntimeContext =
00244             pEnv->NewGlobalRef(hJavaStreamMap);
00245         streamGraphHandle.pExecStreamGraph->setTxn(txnHandle.pTxn);
00246 
00247         // When snapshots are enabled, switch the delegating segment so
00248         // the stream graph accesses the snapshot segment associated with
00249         // the current txn
00250         SharedDatabase pDb = txnHandle.pDb;
00251         if (pDb->areSnapshotsEnabled()) {
00252             DynamicDelegatingSegment *pSegment =
00253                 SegmentFactory::dynamicCast<DynamicDelegatingSegment *>(
00254                     streamGraphHandle.pSegment);
00255             pSegment->setDelegatingSegment(
00256                 WeakSegment(txnHandle.pSnapshotSegment));
00257             pSegment =
00258                 SegmentFactory::dynamicCast<DynamicDelegatingSegment *>(
00259                     streamGraphHandle.pReadCommittedSegment);
00260             pSegment->setDelegatingSegment(
00261                 WeakSegment(txnHandle.pReadCommittedSnapshotSegment));
00262         }
00263         streamGraphHandle.pExecStreamGraph->setErrorTarget(
00264             CmdInterpreter::newErrorTarget(hJavaErrorTarget));
00265         txnHandle.pResourceGovernor->requestResources(
00266             *(streamGraphHandle.pExecStreamGraph));
00267         streamGraphHandle.pExecStreamGraph->open();
00268         if (streamGraphHandle.pScheduler.unique()) {
00269             streamGraphHandle.pScheduler->start();
00270         }
00271     } catch (std::exception &ex) {
00272         pEnv.handleExcn(ex);
00273     }
00274 }
00275 
00276 extern "C" JNIEXPORT void JNICALL
00277 Java_net_sf_farrago_fennel_FennelStorage_tupleStreamGraphClose(
00278     JNIEnv *pEnvInit, jclass, jlong hStreamGraph, jint action)
00279 {
00280     JniEnvRef pEnv(pEnvInit);
00281     try {
00282         CmdInterpreter::StreamGraphHandle &streamGraphHandle =
00283             CmdInterpreter::getStreamGraphHandleFromLong(hStreamGraph);
00284         switch (action) {
00285         case net_sf_farrago_fennel_FennelStorage_CLOSE_RESULT:
00286             if (streamGraphHandle.pScheduler.unique()) {
00287                 streamGraphHandle.pScheduler->stop();
00288             }
00289             if (streamGraphHandle.pExecStreamGraph) {
00290                 streamGraphHandle.pExecStreamGraph->close();
00291             }
00292             break;
00293         case net_sf_farrago_fennel_FennelStorage_CLOSE_ABORT:
00294             if (streamGraphHandle.pScheduler) {
00295                 if (streamGraphHandle.pExecStreamGraph) {
00296                     streamGraphHandle.pScheduler->abort(
00297                         *(streamGraphHandle.pExecStreamGraph));
00298                 }
00299             }
00300             break;
00301         case net_sf_farrago_fennel_FennelStorage_CLOSE_DEALLOCATE:
00302             if (streamGraphHandle.pScheduler) {
00303                 if (streamGraphHandle.pScheduler.unique()) {
00304                     streamGraphHandle.pScheduler->stop();
00305                 }
00306                 streamGraphHandle.pScheduler->removeGraph(
00307                     streamGraphHandle.pExecStreamGraph);
00308             }
00309             delete &streamGraphHandle;
00310             break;
00311         default:
00312             permAssert(false);
00313         }
00314     } catch (std::exception &ex) {
00315         pEnv.handleExcn(ex);
00316     }
00317 }
00318 
00319 extern "C" JNIEXPORT jstring JNICALL
00320 Java_net_sf_farrago_fennel_FennelStorage_getAccessorXmiForTupleDescriptor(
00321     JNIEnv *pEnvInit, jclass, jobject jTupleDesc)
00322 {
00323     JniEnvRef pEnv(pEnvInit);
00324 
00325     // NOTE: Since JniProxies are currently read-only, generate XMI
00326     // representation instead.  If more of this kind of thing starts to
00327     // accumulate, making the JniProxies read-write would be a good idea.
00328 
00329     ProxyTupleDescriptor proxyTupleDesc;
00330     proxyTupleDesc.init(pEnv,jTupleDesc);
00331 
00332     // TODO:  excn handling?
00333 
00334     // TODO:  should take database handle and use its factory instead
00335     StandardTypeDescriptorFactory typeFactory;
00336     TupleDescriptor tupleDescriptor;
00337     CmdInterpreter::readTupleDescriptor(
00338         tupleDescriptor,
00339         proxyTupleDesc,
00340         typeFactory);
00341     TupleAccessor tupleAccessor;
00342     tupleAccessor.compute(tupleDescriptor);
00343     std::ostringstream oss;
00344     oss << "<XMI xmi.version = '1.2' "
00345         << "xmlns:FEMFennel = 'org.omg.xmi.namespace.FEMFennel'>" << std::endl;
00346     oss << "<XMI.content>" << std::endl;
00347     oss << "<FEMFennel:TupleAccessor minByteLength='";
00348     oss << tupleAccessor.getMinByteCount();
00349     oss << "' bitFieldOffset='";
00350     if (!isMAXU(tupleAccessor.getBitFieldOffset())) {
00351         oss << tupleAccessor.getBitFieldOffset();
00352     } else {
00353         oss << "-1";
00354     }
00355     oss << "'>" << std::endl;
00356     for (uint i = 0; i < tupleDescriptor.size(); ++i) {
00357         AttributeAccessor const &attrAccessor =
00358             tupleAccessor.getAttributeAccessor(i);
00359         oss << "<FEMFennel:TupleAccessor.AttrAccessor>";
00360         oss << "<FEMFennel:TupleAttrAccessor ";
00361         oss << "nullBitIndex='";
00362         if (!isMAXU(attrAccessor.iNullBit)) {
00363             oss << attrAccessor.iNullBit;
00364         } else {
00365             oss << "-1";
00366         }
00367         oss << "' ";
00368         oss << "fixedOffset='";
00369         if (!isMAXU(attrAccessor.iFixedOffset)) {
00370             oss << attrAccessor.iFixedOffset;
00371         } else {
00372             oss << "-1";
00373         }
00374         oss << "' ";
00375         oss << "endIndirectOffset='";
00376         if (!isMAXU(attrAccessor.iEndIndirectOffset)) {
00377             oss << attrAccessor.iEndIndirectOffset;
00378         } else {
00379             oss << "-1";
00380         }
00381         oss << "' ";
00382         oss << "bitValueIndex='";
00383         if (!isMAXU(attrAccessor.iValueBit)) {
00384             oss << attrAccessor.iValueBit;
00385         } else {
00386             oss << "-1";
00387         }
00388         oss << "' ";
00389         oss << "/>" << std::endl;
00390         oss << "</FEMFennel:TupleAccessor.AttrAccessor>";
00391     }
00392     oss << "</FEMFennel:TupleAccessor>" << std::endl;
00393     oss << "</XMI.content>" << std::endl;
00394     oss << "</XMI>" << std::endl;
00395     std::string s = oss.str();
00396     return pEnv->NewStringUTF(s.c_str());
00397 }
00398 
00399 extern "C" JNIEXPORT jlong JNICALL
00400 Java_net_sf_farrago_fennel_FennelStorage_newObjectHandle(
00401     JNIEnv *pEnvInit, jclass, jobject obj)
00402 {
00403     // TODO:  excn handling?
00404 
00405     JniEnvRef pEnv(pEnvInit);
00406     jobject jGlobalRef;
00407     if (obj) {
00408         jGlobalRef = pEnv->NewGlobalRef(obj);
00409         // TODO:  convert to Java excn instead
00410         assert(jGlobalRef);
00411     } else {
00412         jGlobalRef = NULL;
00413     }
00414     jobject *pGlobalRef = new jobject;
00415     JniUtil::incrementHandleCount(JAVAOBJECTHANDLE_TYPE_STR, pGlobalRef);
00416     *pGlobalRef = jGlobalRef;
00417     return reinterpret_cast<jlong>(pGlobalRef);
00418 }
00419 
00420 extern "C" JNIEXPORT void JNICALL
00421 Java_net_sf_farrago_fennel_FennelStorage_deleteObjectHandle(
00422     JNIEnv *pEnvInit, jclass, jlong handle)
00423 {
00424     // TODO:  excn handling?
00425 
00426     JniEnvRef pEnv(pEnvInit);
00427     jobject *pGlobalRef = reinterpret_cast<jobject *>(handle);
00428     jobject jGlobalRef = *pGlobalRef;
00429     if (jGlobalRef) {
00430         pEnv->DeleteGlobalRef(jGlobalRef);
00431     }
00432     delete pGlobalRef;
00433     JniUtil::decrementHandleCount(JAVAOBJECTHANDLE_TYPE_STR, pGlobalRef);
00434 }
00435 
00436 // TODO:  share code with new/delete
00437 
00438 extern "C" JNIEXPORT void JNICALL
00439 Java_net_sf_farrago_fennel_FennelStorage_setObjectHandle(
00440     JNIEnv *pEnvInit, jclass, jlong handle, jobject obj)
00441 {
00442     // TODO:  excn handling?
00443 
00444     JniEnvRef pEnv(pEnvInit);
00445     jobject *pGlobalRef = reinterpret_cast<jobject *>(handle);
00446     jobject jGlobalRef = *pGlobalRef;
00447     if (jGlobalRef) {
00448         pEnv->DeleteGlobalRef(jGlobalRef);
00449     }
00450     if (obj) {
00451         jGlobalRef = pEnv->NewGlobalRef(obj);
00452         // TODO:  convert to Java excn instead
00453         assert(jGlobalRef);
00454     } else {
00455         jGlobalRef = NULL;
00456     }
00457     *pGlobalRef = jGlobalRef;
00458 }
00459 
00460 extern "C" JNIEXPORT jint JNICALL
00461 Java_net_sf_farrago_fennel_FennelStorage_getHandleCount(
00462     JNIEnv *pEnvInit, jclass)
00463 {
00464     return JniUtil::getHandleCount();
00465 }
00466 
00467 extern "C" JNIEXPORT jlong JNICALL
00468 Java_net_sf_farrago_fennel_FennelStorage_newExecutionHandle(
00469     JNIEnv *pEnvInit, jclass)
00470 {
00471     CmdInterpreter::ExecutionHandle *pExecHandle =
00472         new CmdInterpreter::ExecutionHandle();
00473     JniUtil::incrementHandleCount(EXECHANDLE_TRACE_TYPE_STR, pExecHandle);
00474     return reinterpret_cast<int64_t>(pExecHandle);
00475 }
00476 
00477 extern "C" JNIEXPORT void JNICALL
00478 Java_net_sf_farrago_fennel_FennelStorage_deleteExecutionHandle(
00479     JNIEnv *pEnvInit, jclass, jlong handle)
00480 {
00481     CmdInterpreter::ExecutionHandle &execHandle =
00482         CmdInterpreter::getExecutionHandleFromLong(handle);
00483     CmdInterpreter::ExecutionHandle *pExecHandle = &execHandle;
00484     JniUtil::decrementHandleCount(EXECHANDLE_TRACE_TYPE_STR, pExecHandle);
00485     deleteAndNullify(pExecHandle);
00486 }
00487 
00488 extern "C" JNIEXPORT void JNICALL
00489 Java_net_sf_farrago_fennel_FennelStorage_cancelExecution(
00490     JNIEnv *pEnvInit, jclass, jlong handle)
00491 {
00492     CmdInterpreter::ExecutionHandle &execHandle =
00493         CmdInterpreter::getExecutionHandleFromLong(handle);
00494     execHandle.aborted = true;
00495 }
00496 
00497 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/farrago/NativeMethods.cpp#37 $");
00498 
00499 // End NativeMethods.cpp

Generated on Mon Jun 22 04:00:19 2009 for Fennel by  doxygen 1.5.1