00001 #include "JNIGateway.hpp"
00002 #include "ValueTypes.hpp"
00003 #include "IndexBuilder.hpp"
00004 #include "IndexSearcher.hpp"
00005
00006
00007 using namespace aitools::invertedindex;
00008
00009 JNIGateway::BuilderMap
00010 JNIGateway::builders;
00011
00012 JNIGateway::SearcherMap
00013 JNIGateway::searchers;
00014
00015 JNIGateway::IteratorMap
00016 JNIGateway::iterators;
00017
00018 boost::mutex
00019 JNIGateway::mutex;
00020
00021 const char*
00022 JNIGateway::java_exception("java/lang/RuntimeException");
00023
00024 void
00025 JNIGateway::copy_string(JNIEnv* env, jstring jstr, std::string& cstr)
00026 {
00027 const char* chars(env->GetStringUTFChars(jstr, 0));
00028 cstr.assign(chars);
00029 env->ReleaseStringUTFChars(jstr, chars);
00030 }
00031
00032
00033 Builder::shared_pointer
00034 JNIGateway::create_builder(JNIEnv* env, jstring jclazz)
00035 throw (std::invalid_argument)
00036 {
00037 std::string value_class;
00038 copy_string(env, jclazz, value_class);
00039 Builder::shared_pointer builder;
00040
00041
00042 if (value_class == "SingleByte")
00043 builder.reset(new IndexBuilder<SingleByte>);
00044 else if (value_class == "SingleFloat")
00045 builder.reset(new IndexBuilder<SingleFloat>);
00046 else if (value_class == "SingleInt")
00047 builder.reset(new IndexBuilder<SingleInt>);
00048 else if (value_class == "SingleLong")
00049 builder.reset(new IndexBuilder<SingleLong>);
00050 else if (value_class == "SingleShort")
00051 builder.reset(new IndexBuilder<SingleShort>);
00052 else if (value_class == "SingleString")
00053 builder.reset(new IndexBuilder<SingleString>);
00054
00055 else if (value_class == "FloatFloat")
00056 builder.reset(new IndexBuilder<FloatFloat>);
00057 else if (value_class == "FloatInt")
00058 builder.reset(new IndexBuilder<FloatInt>);
00059 else if (value_class == "FloatLong")
00060 builder.reset(new IndexBuilder<FloatLong>);
00061 else if (value_class == "IntFloat")
00062 builder.reset(new IndexBuilder<IntFloat>);
00063 else if (value_class == "IntInt")
00064 builder.reset(new IndexBuilder<IntInt>);
00065 else if (value_class == "IntLong")
00066 builder.reset(new IndexBuilder<IntLong>);
00067 else if (value_class == "LongFloat")
00068 builder.reset(new IndexBuilder<LongFloat>);
00069 else if (value_class == "LongInt")
00070 builder.reset(new IndexBuilder<LongInt>);
00071 else if (value_class == "LongLong")
00072 builder.reset(new IndexBuilder<LongLong>);
00073 else if (value_class == "ShortFloat")
00074 builder.reset(new IndexBuilder<ShortFloat>);
00075 else if (value_class == "ShortInt")
00076 builder.reset(new IndexBuilder<ShortInt>);
00077 else if (value_class == "ShortLong")
00078 builder.reset(new IndexBuilder<ShortLong>);
00079
00080 else if (value_class == "ByteString")
00081 builder.reset(new IndexBuilder<ByteString>);
00082 else if (value_class == "FloatString")
00083 builder.reset(new IndexBuilder<FloatString>);
00084 else if (value_class == "IntString")
00085 builder.reset(new IndexBuilder<IntString>);
00086 else if (value_class == "LongString")
00087 builder.reset(new IndexBuilder<LongString>);
00088 else if (value_class == "ShortString")
00089 builder.reset(new IndexBuilder<ShortString>);
00090 else if (value_class == "StringString")
00091 builder.reset(new IndexBuilder<StringString>);
00092
00093 else if (value_class == "FloatFloatFloat")
00094 builder.reset(new IndexBuilder<FloatFloatFloat>);
00095 else if (value_class == "FloatIntFloat")
00096 builder.reset(new IndexBuilder<FloatIntFloat>);
00097 else if (value_class == "FloatIntInt")
00098 builder.reset(new IndexBuilder<FloatIntInt>);
00099 else if (value_class == "IntFloatFloat")
00100 builder.reset(new IndexBuilder<IntFloatFloat>);
00101 else if (value_class == "IntIntFloat")
00102 builder.reset(new IndexBuilder<IntIntFloat>);
00103 else if (value_class == "IntIntInt")
00104 builder.reset(new IndexBuilder<IntIntInt>);
00105 else if (value_class == "LongFloatFloat")
00106 builder.reset(new IndexBuilder<LongFloatFloat>);
00107 else if (value_class == "LongIntFloat")
00108 builder.reset(new IndexBuilder<LongIntFloat>);
00109 else if (value_class == "LongIntInt")
00110 builder.reset(new IndexBuilder<LongIntInt>);
00111 else if (value_class == "ShortFloatFloat")
00112 builder.reset(new IndexBuilder<ShortFloatFloat>);
00113 else if (value_class == "ShortIntFloat")
00114 builder.reset(new IndexBuilder<ShortIntFloat>);
00115 else if (value_class == "ShortIntInt")
00116 builder.reset(new IndexBuilder<ShortIntInt>);
00117
00118 else if (value_class == "IntIntIntInt")
00119 builder.reset(new IndexBuilder<IntIntIntInt>);
00120 else if (value_class == "LongLongLongLong")
00121 builder.reset(new IndexBuilder<LongLongLongLong>);
00122 else if (value_class == "LongLongIntInt")
00123 builder.reset(new IndexBuilder<LongLongIntInt>);
00124 else if (value_class == "LongLongFloatFloat")
00125 builder.reset(new IndexBuilder<LongLongFloatFloat>);
00126 else if (value_class == "LongFloatLongInt")
00127 builder.reset(new IndexBuilder<LongFloatLongInt>);
00128
00129 else Exception::throw_invalid_argument("JNI: Unknown type " + value_class);
00130 return builder;
00131 }
00132
00133 Searcher::SharedPointer
00134 JNIGateway::create_searcher(JNIEnv* env, jstring jclazz)
00135 throw (std::invalid_argument)
00136 {
00137 std::string value_class;
00138 copy_string(env, jclazz, value_class);
00139 Searcher::SharedPointer searcher;
00140
00141
00142 if (value_class == "SingleByte")
00143 searcher.reset(new IndexSearcher<SingleByte>);
00144 else if (value_class == "SingleFloat")
00145 searcher.reset(new IndexSearcher<SingleFloat>);
00146 else if (value_class == "SingleInt")
00147 searcher.reset(new IndexSearcher<SingleInt>);
00148 else if (value_class == "SingleLong")
00149 searcher.reset(new IndexSearcher<SingleLong>);
00150 else if (value_class == "SingleShort")
00151 searcher.reset(new IndexSearcher<SingleShort>);
00152 else if (value_class == "SingleString")
00153 searcher.reset(new IndexSearcher<SingleString>);
00154
00155 else if (value_class == "FloatFloat")
00156 searcher.reset(new IndexSearcher<FloatFloat>);
00157 else if (value_class == "FloatInt")
00158 searcher.reset(new IndexSearcher<FloatInt>);
00159 else if (value_class == "FloatLong")
00160 searcher.reset(new IndexSearcher<FloatLong>);
00161 else if (value_class == "IntFloat")
00162 searcher.reset(new IndexSearcher<IntFloat>);
00163 else if (value_class == "IntInt")
00164 searcher.reset(new IndexSearcher<IntInt>);
00165 else if (value_class == "IntLong")
00166 searcher.reset(new IndexSearcher<IntLong>);
00167 else if (value_class == "LongFloat")
00168 searcher.reset(new IndexSearcher<LongFloat>);
00169 else if (value_class == "LongInt")
00170 searcher.reset(new IndexSearcher<LongInt>);
00171 else if (value_class == "LongLong")
00172 searcher.reset(new IndexSearcher<LongLong>);
00173 else if (value_class == "ShortFloat")
00174 searcher.reset(new IndexSearcher<ShortFloat>);
00175 else if (value_class == "ShortInt")
00176 searcher.reset(new IndexSearcher<ShortInt>);
00177 else if (value_class == "ShortLong")
00178 searcher.reset(new IndexSearcher<ShortLong>);
00179
00180 else if (value_class == "ByteString")
00181 searcher.reset(new IndexSearcher<ByteString>);
00182 else if (value_class == "FloatString")
00183 searcher.reset(new IndexSearcher<FloatString>);
00184 else if (value_class == "IntString")
00185 searcher.reset(new IndexSearcher<IntString>);
00186 else if (value_class == "LongString")
00187 searcher.reset(new IndexSearcher<LongString>);
00188 else if (value_class == "ShortString")
00189 searcher.reset(new IndexSearcher<ShortString>);
00190 else if (value_class == "StringString")
00191 searcher.reset(new IndexSearcher<StringString>);
00192
00193 else if (value_class == "FloatFloatFloat")
00194 searcher.reset(new IndexSearcher<FloatFloatFloat>);
00195 else if (value_class == "FloatIntFloat")
00196 searcher.reset(new IndexSearcher<FloatIntFloat>);
00197 else if (value_class == "FloatIntInt")
00198 searcher.reset(new IndexSearcher<FloatIntInt>);
00199 else if (value_class == "IntFloatFloat")
00200 searcher.reset(new IndexSearcher<IntFloatFloat>);
00201 else if (value_class == "IntIntFloat")
00202 searcher.reset(new IndexSearcher<IntIntFloat>);
00203 else if (value_class == "IntIntInt")
00204 searcher.reset(new IndexSearcher<IntIntInt>);
00205 else if (value_class == "LongFloatFloat")
00206 searcher.reset(new IndexSearcher<LongFloatFloat>);
00207 else if (value_class == "LongIntFloat")
00208 searcher.reset(new IndexSearcher<LongIntFloat>);
00209 else if (value_class == "LongIntInt")
00210 searcher.reset(new IndexSearcher<LongIntInt>);
00211 else if (value_class == "ShortFloatFloat")
00212 searcher.reset(new IndexSearcher<ShortFloatFloat>);
00213 else if (value_class == "ShortIntFloat")
00214 searcher.reset(new IndexSearcher<ShortIntFloat>);
00215 else if (value_class == "ShortIntInt")
00216 searcher.reset(new IndexSearcher<ShortIntInt>);
00217
00218 else if (value_class == "IntIntIntInt")
00219 searcher.reset(new IndexSearcher<IntIntIntInt>);
00220 else if (value_class == "LongLongLongLong")
00221 searcher.reset(new IndexSearcher<LongLongLongLong>);
00222 else if (value_class == "LongLongIntInt")
00223 searcher.reset(new IndexSearcher<LongLongIntInt>);
00224 else if (value_class == "LongLongFloatFloat")
00225 searcher.reset(new IndexSearcher<LongLongFloatFloat>);
00226 else if (value_class == "LongFloatLongInt")
00227 searcher.reset(new IndexSearcher<LongFloatLongInt>);
00228
00229 else Exception::throw_invalid_argument("JNI: Unknown type " + value_class);
00230 return searcher;
00231 }
00232
00233 void
00234 JNIGateway::delete_builder(jint oid)
00235 {
00236 boost::mutex::scoped_lock lock(mutex);
00237 builders.erase(oid);
00238 }
00239
00240 void
00241 JNIGateway::delete_searcher(jint oid)
00242 {
00243 boost::mutex::scoped_lock lock(mutex);
00244 searchers.erase(oid);
00245 }
00246
00247 void
00248 JNIGateway::delete_iterator(jint oid)
00249 {
00250 boost::mutex::scoped_lock lock(mutex);
00251 iterators.erase(oid);
00252 }
00253
00254 Builder::shared_pointer&
00255 JNIGateway::get_builder(jint oid) throw (std::invalid_argument)
00256 {
00257 boost::mutex::scoped_lock lock(mutex);
00258 BuilderMap::iterator it(builders.find(oid));
00259 if (it == builders.end())
00260 {
00261 Exception::throw_invalid_argument("JNI: Invalid object id");
00262 }
00263 return it->second;
00264 }
00265
00266 Searcher::SharedPointer&
00267 JNIGateway::get_searcher(jint oid) throw (std::invalid_argument)
00268 {
00269 boost::mutex::scoped_lock lock(mutex);
00270 SearcherMap::iterator it(searchers.find(oid));
00271 if (it == searchers.end())
00272 {
00273 Exception::throw_invalid_argument("JNI: Invalid object id");
00274 }
00275 return it->second;
00276 }
00277
00278 Iterator::SharedPointer&
00279 JNIGateway::get_iterator(jint oid) throw (std::invalid_argument)
00280 {
00281 boost::mutex::scoped_lock lock(mutex);
00282 IteratorMap::iterator it(iterators.find(oid));
00283 if (it == iterators.end())
00284 {
00285 Exception::throw_invalid_argument("JNI: Invalid object id");
00286 }
00287 return it->second;
00288 }
00289
00290 jint
00291 JNIGateway::put_builder(const Builder::shared_pointer& builder)
00292 {
00293 jint oid(-1);
00294 if (builder)
00295 {
00296 oid = std::rand();
00297 boost::mutex::scoped_lock lock(mutex);
00298 while (builders.find(oid) != builders.end())
00299 {
00300 oid = std::rand();
00301 }
00302 builders.insert(std::make_pair(oid, builder));
00303 }
00304 return oid;
00305 }
00306
00307 jint
00308 JNIGateway::put_searcher(const Searcher::SharedPointer& searcher)
00309 {
00310 jint oid(-1);
00311 if (searcher)
00312 {
00313 oid = std::rand();
00314 boost::mutex::scoped_lock lock(mutex);
00315 while (searchers.find(oid) != searchers.end())
00316 {
00317 oid = std::rand();
00318 }
00319 searchers.insert(std::make_pair(oid, searcher));
00320 }
00321 return oid;
00322 }
00323
00324 jint
00325 JNIGateway::put_iterator(const Iterator::SharedPointer& iterator)
00326 {
00327 jint oid(-1);
00328 if (iterator && iterator->header().value_count != 0)
00329 {
00330 oid = std::rand();
00331 boost::mutex::scoped_lock lock(mutex);
00332 while (iterators.find(oid) != iterators.end())
00333 {
00334 oid = std::rand();
00335 }
00336 iterators.insert(std::make_pair(oid, iterator));
00337 }
00338 return oid;
00339 }