rocksjni.cc 129 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // This file implements the "bridge" between Java and C++ and enables
  7. // calling c++ ROCKSDB_NAMESPACE::DB methods from Java side.
  8. #include <jni.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <algorithm>
  12. #include <functional>
  13. #include <memory>
  14. #include <string>
  15. #include <tuple>
  16. #include <vector>
  17. #include "include/org_rocksdb_RocksDB.h"
  18. #include "rocksdb/cache.h"
  19. #include "rocksdb/convenience.h"
  20. #include "rocksdb/db.h"
  21. #include "rocksdb/options.h"
  22. #include "rocksdb/perf_context.h"
  23. #include "rocksdb/types.h"
  24. #include "rocksdb/version.h"
  25. #include "rocksjni/cplusplus_to_java_convert.h"
  26. #include "rocksjni/jni_multiget_helpers.h"
  27. #include "rocksjni/kv_helper.h"
  28. #include "rocksjni/portal.h"
  29. #ifdef min
  30. #undef min
  31. #endif
  32. jlong rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, jstring jdb_path,
  33. std::function<ROCKSDB_NAMESPACE::Status(
  34. const ROCKSDB_NAMESPACE::Options&,
  35. const std::string&, ROCKSDB_NAMESPACE::DB**)>
  36. open_fn) {
  37. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  38. if (db_path == nullptr) {
  39. // exception thrown: OutOfMemoryError
  40. return 0;
  41. }
  42. auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(jopt_handle);
  43. ROCKSDB_NAMESPACE::DB* db = nullptr;
  44. ROCKSDB_NAMESPACE::Status s = open_fn(*opt, db_path, &db);
  45. env->ReleaseStringUTFChars(jdb_path, db_path);
  46. if (s.ok()) {
  47. return GET_CPLUSPLUS_POINTER(db);
  48. } else {
  49. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  50. return 0;
  51. }
  52. }
  53. /*
  54. * Class: org_rocksdb_RocksDB
  55. * Method: open
  56. * Signature: (JLjava/lang/String;)J
  57. */
  58. jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(JNIEnv* env, jclass,
  59. jlong jopt_handle,
  60. jstring jdb_path) {
  61. return rocksdb_open_helper(env, jopt_handle, jdb_path,
  62. (ROCKSDB_NAMESPACE::Status(*)(
  63. const ROCKSDB_NAMESPACE::Options&,
  64. const std::string&, ROCKSDB_NAMESPACE::DB**)) &
  65. ROCKSDB_NAMESPACE::DB::Open);
  66. }
  67. /*
  68. * Class: org_rocksdb_RocksDB
  69. * Method: openROnly
  70. * Signature: (JLjava/lang/String;Z)J
  71. */
  72. jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2Z(
  73. JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
  74. jboolean jerror_if_wal_file_exists) {
  75. const bool error_if_wal_file_exists = jerror_if_wal_file_exists == JNI_TRUE;
  76. return rocksdb_open_helper(
  77. env, jopt_handle, jdb_path,
  78. [error_if_wal_file_exists](const ROCKSDB_NAMESPACE::Options& options,
  79. const std::string& db_path,
  80. ROCKSDB_NAMESPACE::DB** db) {
  81. return ROCKSDB_NAMESPACE::DB::OpenForReadOnly(options, db_path, db,
  82. error_if_wal_file_exists);
  83. });
  84. }
  85. jlongArray rocksdb_open_helper(
  86. JNIEnv* env, jlong jopt_handle, jstring jdb_path,
  87. jobjectArray jcolumn_names, jlongArray jcolumn_options,
  88. std::function<ROCKSDB_NAMESPACE::Status(
  89. const ROCKSDB_NAMESPACE::DBOptions&, const std::string&,
  90. const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&,
  91. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>*,
  92. ROCKSDB_NAMESPACE::DB**)>
  93. open_fn) {
  94. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  95. if (db_path == nullptr) {
  96. // exception thrown: OutOfMemoryError
  97. return nullptr;
  98. }
  99. const jsize len_cols = env->GetArrayLength(jcolumn_names);
  100. jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
  101. if (jco == nullptr) {
  102. // exception thrown: OutOfMemoryError
  103. env->ReleaseStringUTFChars(jdb_path, db_path);
  104. return nullptr;
  105. }
  106. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> column_families;
  107. jboolean has_exception = JNI_FALSE;
  108. ROCKSDB_NAMESPACE::JniUtil::byteStrings<std::string>(
  109. env, jcolumn_names,
  110. [](const char* str_data, const size_t str_len) {
  111. return std::string(str_data, str_len);
  112. },
  113. [&jco, &column_families](size_t idx, std::string cf_name) {
  114. ROCKSDB_NAMESPACE::ColumnFamilyOptions* cf_options =
  115. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(jco[idx]);
  116. column_families.push_back(
  117. ROCKSDB_NAMESPACE::ColumnFamilyDescriptor(cf_name, *cf_options));
  118. },
  119. &has_exception);
  120. env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
  121. if (has_exception == JNI_TRUE) {
  122. // exception occurred
  123. env->ReleaseStringUTFChars(jdb_path, db_path);
  124. return nullptr;
  125. }
  126. auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions*>(jopt_handle);
  127. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  128. ROCKSDB_NAMESPACE::DB* db = nullptr;
  129. ROCKSDB_NAMESPACE::Status s =
  130. open_fn(*opt, db_path, column_families, &cf_handles, &db);
  131. // we have now finished with db_path
  132. env->ReleaseStringUTFChars(jdb_path, db_path);
  133. // check if open operation was successful
  134. if (!s.ok()) {
  135. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  136. return nullptr;
  137. }
  138. const jsize resultsLen = 1 + len_cols; // db handle + column family handles
  139. std::unique_ptr<jlong[]> results =
  140. std::unique_ptr<jlong[]>(new jlong[resultsLen]);
  141. results[0] = GET_CPLUSPLUS_POINTER(db);
  142. for (int i = 1; i <= len_cols; i++) {
  143. results[i] = GET_CPLUSPLUS_POINTER(cf_handles[i - 1]);
  144. }
  145. jlongArray jresults = env->NewLongArray(resultsLen);
  146. if (jresults == nullptr) {
  147. // exception thrown: OutOfMemoryError
  148. return nullptr;
  149. }
  150. env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
  151. if (env->ExceptionCheck()) {
  152. // exception thrown: ArrayIndexOutOfBoundsException
  153. env->DeleteLocalRef(jresults);
  154. return nullptr;
  155. }
  156. return jresults;
  157. }
  158. /*
  159. * Class: org_rocksdb_RocksDB
  160. * Method: openROnly
  161. * Signature: (JLjava/lang/String;[[B[JZ)[J
  162. */
  163. jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3JZ(
  164. JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
  165. jobjectArray jcolumn_names, jlongArray jcolumn_options,
  166. jboolean jerror_if_wal_file_exists) {
  167. const bool error_if_wal_file_exists = jerror_if_wal_file_exists == JNI_TRUE;
  168. return rocksdb_open_helper(
  169. env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
  170. [error_if_wal_file_exists](
  171. const ROCKSDB_NAMESPACE::DBOptions& options,
  172. const std::string& db_path,
  173. const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&
  174. column_families,
  175. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>* handles,
  176. ROCKSDB_NAMESPACE::DB** db) {
  177. return ROCKSDB_NAMESPACE::DB::OpenForReadOnly(
  178. options, db_path, column_families, handles, db,
  179. error_if_wal_file_exists);
  180. });
  181. }
  182. /*
  183. * Class: org_rocksdb_RocksDB
  184. * Method: open
  185. * Signature: (JLjava/lang/String;[[B[J)[J
  186. */
  187. jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(
  188. JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
  189. jobjectArray jcolumn_names, jlongArray jcolumn_options) {
  190. return rocksdb_open_helper(
  191. env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
  192. (ROCKSDB_NAMESPACE::Status(*)(
  193. const ROCKSDB_NAMESPACE::DBOptions&, const std::string&,
  194. const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&,
  195. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>*,
  196. ROCKSDB_NAMESPACE::DB**)) &
  197. ROCKSDB_NAMESPACE::DB::Open);
  198. }
  199. /*
  200. * Class: org_rocksdb_RocksDB
  201. * Method: openAsSecondary
  202. * Signature: (JLjava/lang/String;Ljava/lang/String;)J
  203. */
  204. jlong Java_org_rocksdb_RocksDB_openAsSecondary__JLjava_lang_String_2Ljava_lang_String_2(
  205. JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
  206. jstring jsecondary_db_path) {
  207. const char* secondary_db_path =
  208. env->GetStringUTFChars(jsecondary_db_path, nullptr);
  209. if (secondary_db_path == nullptr) {
  210. // exception thrown: OutOfMemoryError
  211. return 0;
  212. }
  213. jlong db_handle = rocksdb_open_helper(
  214. env, jopt_handle, jdb_path,
  215. [secondary_db_path](const ROCKSDB_NAMESPACE::Options& options,
  216. const std::string& db_path,
  217. ROCKSDB_NAMESPACE::DB** db) {
  218. return ROCKSDB_NAMESPACE::DB::OpenAsSecondary(options, db_path,
  219. secondary_db_path, db);
  220. });
  221. // we have now finished with secondary_db_path
  222. env->ReleaseStringUTFChars(jsecondary_db_path, secondary_db_path);
  223. return db_handle;
  224. }
  225. /*
  226. * Class: org_rocksdb_RocksDB
  227. * Method: openAsSecondary
  228. * Signature: (JLjava/lang/String;Ljava/lang/String;[[B[J)[J
  229. */
  230. jlongArray
  231. Java_org_rocksdb_RocksDB_openAsSecondary__JLjava_lang_String_2Ljava_lang_String_2_3_3B_3J(
  232. JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
  233. jstring jsecondary_db_path, jobjectArray jcolumn_names,
  234. jlongArray jcolumn_options) {
  235. const char* secondary_db_path =
  236. env->GetStringUTFChars(jsecondary_db_path, nullptr);
  237. if (secondary_db_path == nullptr) {
  238. // exception thrown: OutOfMemoryError
  239. return nullptr;
  240. }
  241. jlongArray jhandles = rocksdb_open_helper(
  242. env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
  243. [secondary_db_path](
  244. const ROCKSDB_NAMESPACE::DBOptions& options,
  245. const std::string& db_path,
  246. const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&
  247. column_families,
  248. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>* handles,
  249. ROCKSDB_NAMESPACE::DB** db) {
  250. return ROCKSDB_NAMESPACE::DB::OpenAsSecondary(
  251. options, db_path, secondary_db_path, column_families, handles, db);
  252. });
  253. // we have now finished with secondary_db_path
  254. env->ReleaseStringUTFChars(jsecondary_db_path, secondary_db_path);
  255. return jhandles;
  256. }
  257. /*
  258. * Class: org_rocksdb_RocksDB
  259. * Method: disposeInternal
  260. * Signature: (J)V
  261. */
  262. void Java_org_rocksdb_RocksDB_disposeInternalJni(JNIEnv*, jclass,
  263. jlong jhandle) {
  264. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
  265. assert(db != nullptr);
  266. delete db;
  267. }
  268. /*
  269. * Class: org_rocksdb_RocksDB
  270. * Method: closeDatabase
  271. * Signature: (J)V
  272. */
  273. void Java_org_rocksdb_RocksDB_closeDatabase(JNIEnv* env, jclass,
  274. jlong jhandle) {
  275. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
  276. assert(db != nullptr);
  277. ROCKSDB_NAMESPACE::Status s = db->Close();
  278. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  279. }
  280. /*
  281. * Class: org_rocksdb_RocksDB
  282. * Method: listColumnFamilies
  283. * Signature: (JLjava/lang/String;)[[B
  284. */
  285. jobjectArray Java_org_rocksdb_RocksDB_listColumnFamilies(JNIEnv* env, jclass,
  286. jlong jopt_handle,
  287. jstring jdb_path) {
  288. std::vector<std::string> column_family_names;
  289. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  290. if (db_path == nullptr) {
  291. // exception thrown: OutOfMemoryError
  292. return nullptr;
  293. }
  294. auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(jopt_handle);
  295. ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DB::ListColumnFamilies(
  296. *opt, db_path, &column_family_names);
  297. env->ReleaseStringUTFChars(jdb_path, db_path);
  298. jobjectArray jcolumn_family_names =
  299. ROCKSDB_NAMESPACE::JniUtil::stringsBytes(env, column_family_names);
  300. return jcolumn_family_names;
  301. }
  302. /*
  303. * Class: org_rocksdb_RocksDB
  304. * Method: createColumnFamily
  305. * Signature: (J[BIJ)J
  306. */
  307. jlong Java_org_rocksdb_RocksDB_createColumnFamily(JNIEnv* env, jclass,
  308. jlong jhandle,
  309. jbyteArray jcf_name,
  310. jint jcf_name_len,
  311. jlong jcf_options_handle) {
  312. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
  313. jboolean has_exception = JNI_FALSE;
  314. const std::string cf_name =
  315. ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
  316. env, jcf_name, jcf_name_len,
  317. [](const char* str, const size_t len) {
  318. return std::string(str, len);
  319. },
  320. &has_exception);
  321. if (has_exception == JNI_TRUE) {
  322. // exception occurred
  323. return 0;
  324. }
  325. auto* cf_options = reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
  326. jcf_options_handle);
  327. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  328. ROCKSDB_NAMESPACE::Status s =
  329. db->CreateColumnFamily(*cf_options, cf_name, &cf_handle);
  330. if (!s.ok()) {
  331. // error occurred
  332. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  333. return 0;
  334. }
  335. return GET_CPLUSPLUS_POINTER(cf_handle);
  336. }
  337. /*
  338. * Class: org_rocksdb_RocksDB
  339. * Method: createColumnFamilies
  340. * Signature: (JJ[[B)[J
  341. */
  342. jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__JJ_3_3B(
  343. JNIEnv* env, jclass, jlong jhandle, jlong jcf_options_handle,
  344. jobjectArray jcf_names) {
  345. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
  346. auto* cf_options = reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
  347. jcf_options_handle);
  348. jboolean has_exception = JNI_FALSE;
  349. std::vector<std::string> cf_names;
  350. ROCKSDB_NAMESPACE::JniUtil::byteStrings<std::string>(
  351. env, jcf_names,
  352. [](const char* str, const size_t len) { return std::string(str, len); },
  353. [&cf_names](const size_t, std::string str) { cf_names.push_back(str); },
  354. &has_exception);
  355. if (has_exception == JNI_TRUE) {
  356. // exception occurred
  357. return nullptr;
  358. }
  359. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  360. ROCKSDB_NAMESPACE::Status s =
  361. db->CreateColumnFamilies(*cf_options, cf_names, &cf_handles);
  362. if (!s.ok()) {
  363. // error occurred
  364. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  365. return nullptr;
  366. }
  367. jlongArray jcf_handles = ROCKSDB_NAMESPACE::JniUtil::toJPointers<
  368. ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, cf_handles, &has_exception);
  369. if (has_exception == JNI_TRUE) {
  370. // exception occurred
  371. return nullptr;
  372. }
  373. return jcf_handles;
  374. }
  375. /*
  376. * Class: org_rocksdb_RocksDB
  377. * Method: createColumnFamilies
  378. * Signature: (J[J[[B)[J
  379. */
  380. jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__J_3J_3_3B(
  381. JNIEnv* env, jclass, jlong jhandle, jlongArray jcf_options_handles,
  382. jobjectArray jcf_names) {
  383. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
  384. const jsize jlen = env->GetArrayLength(jcf_options_handles);
  385. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> cf_descriptors;
  386. cf_descriptors.reserve(jlen);
  387. jlong* jcf_options_handles_elems =
  388. env->GetLongArrayElements(jcf_options_handles, nullptr);
  389. if (jcf_options_handles_elems == nullptr) {
  390. // exception thrown: OutOfMemoryError
  391. return nullptr;
  392. }
  393. // extract the column family descriptors
  394. jboolean has_exception = JNI_FALSE;
  395. for (jsize i = 0; i < jlen; i++) {
  396. auto* cf_options =
  397. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
  398. jcf_options_handles_elems[i]);
  399. jbyteArray jcf_name =
  400. static_cast<jbyteArray>(env->GetObjectArrayElement(jcf_names, i));
  401. if (env->ExceptionCheck()) {
  402. // exception thrown: ArrayIndexOutOfBoundsException
  403. env->ReleaseLongArrayElements(jcf_options_handles,
  404. jcf_options_handles_elems, JNI_ABORT);
  405. return nullptr;
  406. }
  407. const std::string cf_name =
  408. ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
  409. env, jcf_name,
  410. [](const char* str, const size_t len) {
  411. return std::string(str, len);
  412. },
  413. &has_exception);
  414. if (has_exception == JNI_TRUE) {
  415. // exception occurred
  416. env->DeleteLocalRef(jcf_name);
  417. env->ReleaseLongArrayElements(jcf_options_handles,
  418. jcf_options_handles_elems, JNI_ABORT);
  419. return nullptr;
  420. }
  421. cf_descriptors.push_back(
  422. ROCKSDB_NAMESPACE::ColumnFamilyDescriptor(cf_name, *cf_options));
  423. env->DeleteLocalRef(jcf_name);
  424. }
  425. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  426. ROCKSDB_NAMESPACE::Status s =
  427. db->CreateColumnFamilies(cf_descriptors, &cf_handles);
  428. env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems,
  429. JNI_ABORT);
  430. if (!s.ok()) {
  431. // error occurred
  432. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  433. return nullptr;
  434. }
  435. jlongArray jcf_handles = ROCKSDB_NAMESPACE::JniUtil::toJPointers<
  436. ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, cf_handles, &has_exception);
  437. if (has_exception == JNI_TRUE) {
  438. // exception occurred
  439. return nullptr;
  440. }
  441. return jcf_handles;
  442. }
  443. /*
  444. * Class: org_rocksdb_RocksDB
  445. * Method: createColumnFamilyWithImport
  446. * Signature: (J[BIJJ[J)J
  447. */
  448. jlong Java_org_rocksdb_RocksDB_createColumnFamilyWithImport(
  449. JNIEnv* env, jclass, jlong jdb_handle, jbyteArray jcf_name,
  450. jint jcf_name_len, jlong j_cf_options, jlong j_cf_import_options,
  451. jlongArray j_metadata_handle_array) {
  452. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  453. jboolean has_exception = JNI_FALSE;
  454. const std::string cf_name =
  455. ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
  456. env, jcf_name, jcf_name_len,
  457. [](const char* str, const size_t len) {
  458. return std::string(str, len);
  459. },
  460. &has_exception);
  461. if (has_exception == JNI_TRUE) {
  462. // exception occurred
  463. return 0;
  464. }
  465. auto* cf_options =
  466. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(j_cf_options);
  467. auto* cf_import_options =
  468. reinterpret_cast<ROCKSDB_NAMESPACE::ImportColumnFamilyOptions*>(
  469. j_cf_import_options);
  470. std::vector<const ROCKSDB_NAMESPACE::ExportImportFilesMetaData*> metadatas;
  471. jlong* ptr_metadata_handle_array =
  472. env->GetLongArrayElements(j_metadata_handle_array, nullptr);
  473. if (j_metadata_handle_array == nullptr) {
  474. // exception thrown: OutOfMemoryError
  475. return 0;
  476. }
  477. const jsize array_size = env->GetArrayLength(j_metadata_handle_array);
  478. for (jsize i = 0; i < array_size; ++i) {
  479. const ROCKSDB_NAMESPACE::ExportImportFilesMetaData* metadata_ptr =
  480. reinterpret_cast<ROCKSDB_NAMESPACE::ExportImportFilesMetaData*>(
  481. ptr_metadata_handle_array[i]);
  482. metadatas.push_back(metadata_ptr);
  483. }
  484. env->ReleaseLongArrayElements(j_metadata_handle_array,
  485. ptr_metadata_handle_array, JNI_ABORT);
  486. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle = nullptr;
  487. ROCKSDB_NAMESPACE::Status s = db->CreateColumnFamilyWithImport(
  488. *cf_options, cf_name, *cf_import_options, metadatas, &cf_handle);
  489. if (!s.ok()) {
  490. // error occurred
  491. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  492. return 0;
  493. }
  494. return GET_CPLUSPLUS_POINTER(cf_handle);
  495. }
  496. /*
  497. * Class: org_rocksdb_RocksDB
  498. * Method: dropColumnFamily
  499. * Signature: (JJ)V;
  500. */
  501. void Java_org_rocksdb_RocksDB_dropColumnFamily(JNIEnv* env, jclass,
  502. jlong jdb_handle,
  503. jlong jcf_handle) {
  504. auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  505. auto* cf_handle =
  506. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  507. ROCKSDB_NAMESPACE::Status s = db_handle->DropColumnFamily(cf_handle);
  508. if (!s.ok()) {
  509. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  510. }
  511. }
  512. /*
  513. * Class: org_rocksdb_RocksDB
  514. * Method: dropColumnFamilies
  515. * Signature: (J[J)V
  516. */
  517. void Java_org_rocksdb_RocksDB_dropColumnFamilies(
  518. JNIEnv* env, jclass, jlong jdb_handle, jlongArray jcolumn_family_handles) {
  519. auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  520. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  521. if (jcolumn_family_handles != nullptr) {
  522. const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
  523. jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
  524. if (jcfh == nullptr) {
  525. // exception thrown: OutOfMemoryError
  526. return;
  527. }
  528. for (jsize i = 0; i < len_cols; i++) {
  529. auto* cf_handle =
  530. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
  531. cf_handles.push_back(cf_handle);
  532. }
  533. env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
  534. }
  535. ROCKSDB_NAMESPACE::Status s = db_handle->DropColumnFamilies(cf_handles);
  536. if (!s.ok()) {
  537. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  538. }
  539. }
  540. //////////////////////////////////////////////////////////////////////////////
  541. // ROCKSDB_NAMESPACE::DB::Put
  542. /*
  543. * Class: org_rocksdb_RocksDB
  544. * Method: put
  545. * Signature: (J[BII[BII)V
  546. */
  547. void Java_org_rocksdb_RocksDB_put__J_3BII_3BII(JNIEnv* env, jclass,
  548. jlong jdb_handle,
  549. jbyteArray jkey, jint jkey_off,
  550. jint jkey_len, jbyteArray jval,
  551. jint jval_off, jint jval_len) {
  552. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  553. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  554. ROCKSDB_NAMESPACE::WriteOptions();
  555. try {
  556. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  557. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  558. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  559. env, db->Put(default_write_options, key.slice(), value.slice()));
  560. } catch (ROCKSDB_NAMESPACE::KVException&) {
  561. return;
  562. }
  563. }
  564. /*
  565. * Class: org_rocksdb_RocksDB
  566. * Method: put
  567. * Signature: (J[BII[BIIJ)V
  568. */
  569. void Java_org_rocksdb_RocksDB_put__J_3BII_3BIIJ(JNIEnv* env, jclass,
  570. jlong jdb_handle,
  571. jbyteArray jkey, jint jkey_off,
  572. jint jkey_len, jbyteArray jval,
  573. jint jval_off, jint jval_len,
  574. jlong jcf_handle) {
  575. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  576. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  577. ROCKSDB_NAMESPACE::WriteOptions();
  578. auto* cf_handle =
  579. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  580. if (cf_handle == nullptr) {
  581. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  582. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  583. "Invalid ColumnFamilyHandle."));
  584. return;
  585. }
  586. try {
  587. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  588. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  589. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  590. env,
  591. db->Put(default_write_options, cf_handle, key.slice(), value.slice()));
  592. } catch (ROCKSDB_NAMESPACE::KVException&) {
  593. return;
  594. }
  595. }
  596. /*
  597. * Class: org_rocksdb_RocksDB
  598. * Method: put
  599. * Signature: (JJ[BII[BII)V
  600. */
  601. void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BII(JNIEnv* env, jclass,
  602. jlong jdb_handle,
  603. jlong jwrite_options_handle,
  604. jbyteArray jkey, jint jkey_off,
  605. jint jkey_len, jbyteArray jval,
  606. jint jval_off, jint jval_len) {
  607. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  608. auto* write_options =
  609. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  610. try {
  611. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  612. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  613. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  614. env, db->Put(*write_options, key.slice(), value.slice()));
  615. } catch (ROCKSDB_NAMESPACE::KVException&) {
  616. return;
  617. }
  618. }
  619. /*
  620. * Class: org_rocksdb_RocksDB
  621. * Method: put
  622. * Signature: (JJ[BII[BIIJ)V
  623. */
  624. void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BIIJ(
  625. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options_handle,
  626. jbyteArray jkey, jint jkey_off, jint jkey_len, jbyteArray jval,
  627. jint jval_off, jint jval_len, jlong jcf_handle) {
  628. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  629. auto* write_options =
  630. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  631. auto* cf_handle =
  632. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  633. if (cf_handle == nullptr) {
  634. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  635. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  636. "Invalid ColumnFamilyHandle."));
  637. return;
  638. }
  639. try {
  640. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  641. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  642. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  643. env, db->Put(*write_options, cf_handle, key.slice(), value.slice()));
  644. } catch (ROCKSDB_NAMESPACE::KVException&) {
  645. return;
  646. }
  647. }
  648. /*
  649. * Class: org_rocksdb_RocksDB
  650. * Method: putDirect
  651. * Signature: (JJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIJ)V
  652. */
  653. void Java_org_rocksdb_RocksDB_putDirect(
  654. JNIEnv* env, jclass /*jdb*/, jlong jdb_handle, jlong jwrite_options_handle,
  655. jobject jkey, jint jkey_off, jint jkey_len, jobject jval, jint jval_off,
  656. jint jval_len, jlong jcf_handle) {
  657. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  658. auto* write_options =
  659. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  660. auto* cf_handle =
  661. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  662. auto put = [&env, &db, &cf_handle, &write_options](
  663. ROCKSDB_NAMESPACE::Slice& key,
  664. ROCKSDB_NAMESPACE::Slice& value) {
  665. ROCKSDB_NAMESPACE::Status s;
  666. if (cf_handle == nullptr) {
  667. s = db->Put(*write_options, key, value);
  668. } else {
  669. s = db->Put(*write_options, cf_handle, key, value);
  670. }
  671. if (s.ok()) {
  672. return;
  673. }
  674. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  675. };
  676. ROCKSDB_NAMESPACE::JniUtil::kv_op_direct(put, env, jkey, jkey_off, jkey_len,
  677. jval, jval_off, jval_len);
  678. }
  679. //////////////////////////////////////////////////////////////////////////////
  680. // ROCKSDB_NAMESPACE::DB::Delete()
  681. /**
  682. * @return true if the delete succeeded, false if a Java Exception was thrown
  683. */
  684. bool rocksdb_delete_helper(JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
  685. const ROCKSDB_NAMESPACE::WriteOptions& write_options,
  686. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle,
  687. jbyteArray jkey, jint jkey_off, jint jkey_len) {
  688. jbyte* key = new jbyte[jkey_len];
  689. env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
  690. if (env->ExceptionCheck()) {
  691. // exception thrown: ArrayIndexOutOfBoundsException
  692. delete[] key;
  693. return false;
  694. }
  695. ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
  696. ROCKSDB_NAMESPACE::Status s;
  697. if (cf_handle != nullptr) {
  698. s = db->Delete(write_options, cf_handle, key_slice);
  699. } else {
  700. // backwards compatibility
  701. s = db->Delete(write_options, key_slice);
  702. }
  703. // cleanup
  704. delete[] key;
  705. if (s.ok()) {
  706. return true;
  707. }
  708. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  709. return false;
  710. }
  711. /*
  712. * Class: org_rocksdb_RocksDB
  713. * Method: delete
  714. * Signature: (J[BII)V
  715. */
  716. void Java_org_rocksdb_RocksDB_delete__J_3BII(JNIEnv* env, jclass,
  717. jlong jdb_handle, jbyteArray jkey,
  718. jint jkey_off, jint jkey_len) {
  719. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  720. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  721. ROCKSDB_NAMESPACE::WriteOptions();
  722. rocksdb_delete_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
  723. jkey_len);
  724. }
  725. /*
  726. * Class: org_rocksdb_RocksDB
  727. * Method: delete
  728. * Signature: (J[BIIJ)V
  729. */
  730. void Java_org_rocksdb_RocksDB_delete__J_3BIIJ(JNIEnv* env, jclass,
  731. jlong jdb_handle, jbyteArray jkey,
  732. jint jkey_off, jint jkey_len,
  733. jlong jcf_handle) {
  734. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  735. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  736. ROCKSDB_NAMESPACE::WriteOptions();
  737. auto* cf_handle =
  738. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  739. if (cf_handle != nullptr) {
  740. rocksdb_delete_helper(env, db, default_write_options, cf_handle, jkey,
  741. jkey_off, jkey_len);
  742. } else {
  743. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  744. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  745. "Invalid ColumnFamilyHandle."));
  746. }
  747. }
  748. /*
  749. * Class: org_rocksdb_RocksDB
  750. * Method: delete
  751. * Signature: (JJ[BII)V
  752. */
  753. void Java_org_rocksdb_RocksDB_delete__JJ_3BII(JNIEnv* env, jclass,
  754. jlong jdb_handle,
  755. jlong jwrite_options,
  756. jbyteArray jkey, jint jkey_off,
  757. jint jkey_len) {
  758. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  759. auto* write_options =
  760. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  761. rocksdb_delete_helper(env, db, *write_options, nullptr, jkey, jkey_off,
  762. jkey_len);
  763. }
  764. /*
  765. * Class: org_rocksdb_RocksDB
  766. * Method: delete
  767. * Signature: (JJ[BIIJ)V
  768. */
  769. void Java_org_rocksdb_RocksDB_delete__JJ_3BIIJ(
  770. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options,
  771. jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
  772. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  773. auto* write_options =
  774. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  775. auto* cf_handle =
  776. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  777. if (cf_handle != nullptr) {
  778. rocksdb_delete_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
  779. jkey_len);
  780. } else {
  781. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  782. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  783. "Invalid ColumnFamilyHandle."));
  784. }
  785. }
  786. //////////////////////////////////////////////////////////////////////////////
  787. // ROCKSDB_NAMESPACE::DB::SingleDelete()
  788. /**
  789. * @return true if the single delete succeeded, false if a Java Exception
  790. * was thrown
  791. */
  792. bool rocksdb_single_delete_helper(
  793. JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
  794. const ROCKSDB_NAMESPACE::WriteOptions& write_options,
  795. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle, jbyteArray jkey,
  796. jint jkey_len) {
  797. jbyte* key = new jbyte[jkey_len];
  798. env->GetByteArrayRegion(jkey, 0, jkey_len, key);
  799. if (env->ExceptionCheck()) {
  800. // exception thrown: ArrayIndexOutOfBoundsException
  801. delete[] key;
  802. return false;
  803. }
  804. ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
  805. ROCKSDB_NAMESPACE::Status s;
  806. if (cf_handle != nullptr) {
  807. s = db->SingleDelete(write_options, cf_handle, key_slice);
  808. } else {
  809. // backwards compatibility
  810. s = db->SingleDelete(write_options, key_slice);
  811. }
  812. delete[] key;
  813. if (s.ok()) {
  814. return true;
  815. }
  816. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  817. return false;
  818. }
  819. /*
  820. * Class: org_rocksdb_RocksDB
  821. * Method: singleDelete
  822. * Signature: (J[BI)V
  823. */
  824. void Java_org_rocksdb_RocksDB_singleDelete__J_3BI(JNIEnv* env, jclass,
  825. jlong jdb_handle,
  826. jbyteArray jkey,
  827. jint jkey_len) {
  828. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  829. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  830. ROCKSDB_NAMESPACE::WriteOptions();
  831. rocksdb_single_delete_helper(env, db, default_write_options, nullptr, jkey,
  832. jkey_len);
  833. }
  834. /*
  835. * Class: org_rocksdb_RocksDB
  836. * Method: singleDelete
  837. * Signature: (J[BIJ)V
  838. */
  839. void Java_org_rocksdb_RocksDB_singleDelete__J_3BIJ(JNIEnv* env, jclass,
  840. jlong jdb_handle,
  841. jbyteArray jkey,
  842. jint jkey_len,
  843. jlong jcf_handle) {
  844. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  845. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  846. ROCKSDB_NAMESPACE::WriteOptions();
  847. auto* cf_handle =
  848. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  849. if (cf_handle != nullptr) {
  850. rocksdb_single_delete_helper(env, db, default_write_options, cf_handle,
  851. jkey, jkey_len);
  852. } else {
  853. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  854. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  855. "Invalid ColumnFamilyHandle."));
  856. }
  857. }
  858. /*
  859. * Class: org_rocksdb_RocksDB
  860. * Method: singleDelete
  861. * Signature: (JJ[BIJ)V
  862. */
  863. void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BI(JNIEnv* env, jclass,
  864. jlong jdb_handle,
  865. jlong jwrite_options,
  866. jbyteArray jkey,
  867. jint jkey_len) {
  868. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  869. auto* write_options =
  870. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  871. rocksdb_single_delete_helper(env, db, *write_options, nullptr, jkey,
  872. jkey_len);
  873. }
  874. /*
  875. * Class: org_rocksdb_RocksDB
  876. * Method: singleDelete
  877. * Signature: (JJ[BIJ)V
  878. */
  879. void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BIJ(
  880. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options,
  881. jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
  882. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  883. auto* write_options =
  884. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  885. auto* cf_handle =
  886. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  887. if (cf_handle != nullptr) {
  888. rocksdb_single_delete_helper(env, db, *write_options, cf_handle, jkey,
  889. jkey_len);
  890. } else {
  891. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  892. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  893. "Invalid ColumnFamilyHandle."));
  894. }
  895. }
  896. //////////////////////////////////////////////////////////////////////////////
  897. // ROCKSDB_NAMESPACE::DB::DeleteRange()
  898. /**
  899. * @return true if the delete range succeeded, false if a Java Exception
  900. * was thrown
  901. */
  902. bool rocksdb_delete_range_helper(
  903. JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
  904. const ROCKSDB_NAMESPACE::WriteOptions& write_options,
  905. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle, jbyteArray jbegin_key,
  906. jint jbegin_key_off, jint jbegin_key_len, jbyteArray jend_key,
  907. jint jend_key_off, jint jend_key_len) {
  908. jbyte* begin_key = new jbyte[jbegin_key_len];
  909. env->GetByteArrayRegion(jbegin_key, jbegin_key_off, jbegin_key_len,
  910. begin_key);
  911. if (env->ExceptionCheck()) {
  912. // exception thrown: ArrayIndexOutOfBoundsException
  913. delete[] begin_key;
  914. return false;
  915. }
  916. ROCKSDB_NAMESPACE::Slice begin_key_slice(reinterpret_cast<char*>(begin_key),
  917. jbegin_key_len);
  918. jbyte* end_key = new jbyte[jend_key_len];
  919. env->GetByteArrayRegion(jend_key, jend_key_off, jend_key_len, end_key);
  920. if (env->ExceptionCheck()) {
  921. // exception thrown: ArrayIndexOutOfBoundsException
  922. delete[] begin_key;
  923. delete[] end_key;
  924. return false;
  925. }
  926. ROCKSDB_NAMESPACE::Slice end_key_slice(reinterpret_cast<char*>(end_key),
  927. jend_key_len);
  928. ROCKSDB_NAMESPACE::Status s;
  929. if (cf_handle != nullptr) {
  930. s = db->DeleteRange(write_options, cf_handle, begin_key_slice,
  931. end_key_slice);
  932. } else {
  933. s = db->DeleteRange(write_options, begin_key_slice, end_key_slice);
  934. }
  935. // cleanup
  936. delete[] begin_key;
  937. delete[] end_key;
  938. if (s.ok()) {
  939. return true;
  940. }
  941. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  942. return false;
  943. }
  944. /*
  945. * Class: org_rocksdb_RocksDB
  946. * Method: deleteRange
  947. * Signature: (J[BII[BII)V
  948. */
  949. void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BII(
  950. JNIEnv* env, jclass, jlong jdb_handle, jbyteArray jbegin_key,
  951. jint jbegin_key_off, jint jbegin_key_len, jbyteArray jend_key,
  952. jint jend_key_off, jint jend_key_len) {
  953. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  954. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  955. ROCKSDB_NAMESPACE::WriteOptions();
  956. rocksdb_delete_range_helper(env, db, default_write_options, nullptr,
  957. jbegin_key, jbegin_key_off, jbegin_key_len,
  958. jend_key, jend_key_off, jend_key_len);
  959. }
  960. /*
  961. * Class: org_rocksdb_RocksDB
  962. * Method: deleteRange
  963. * Signature: (J[BII[BIIJ)V
  964. */
  965. void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BIIJ(
  966. JNIEnv* env, jclass, jlong jdb_handle, jbyteArray jbegin_key,
  967. jint jbegin_key_off, jint jbegin_key_len, jbyteArray jend_key,
  968. jint jend_key_off, jint jend_key_len, jlong jcf_handle) {
  969. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  970. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  971. ROCKSDB_NAMESPACE::WriteOptions();
  972. auto* cf_handle =
  973. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  974. if (cf_handle != nullptr) {
  975. rocksdb_delete_range_helper(env, db, default_write_options, cf_handle,
  976. jbegin_key, jbegin_key_off, jbegin_key_len,
  977. jend_key, jend_key_off, jend_key_len);
  978. } else {
  979. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  980. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  981. "Invalid ColumnFamilyHandle."));
  982. }
  983. }
  984. /*
  985. * Class: org_rocksdb_RocksDB
  986. * Method: deleteRange
  987. * Signature: (JJ[BII[BII)V
  988. */
  989. void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BII(
  990. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options,
  991. jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
  992. jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
  993. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  994. auto* write_options =
  995. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  996. rocksdb_delete_range_helper(env, db, *write_options, nullptr, jbegin_key,
  997. jbegin_key_off, jbegin_key_len, jend_key,
  998. jend_key_off, jend_key_len);
  999. }
  1000. /*
  1001. * Class: org_rocksdb_RocksDB
  1002. * Method: deleteRange
  1003. * Signature: (JJ[BII[BIIJ)V
  1004. */
  1005. void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BIIJ(
  1006. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options,
  1007. jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
  1008. jbyteArray jend_key, jint jend_key_off, jint jend_key_len,
  1009. jlong jcf_handle) {
  1010. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1011. auto* write_options =
  1012. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  1013. auto* cf_handle =
  1014. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1015. if (cf_handle != nullptr) {
  1016. rocksdb_delete_range_helper(env, db, *write_options, cf_handle, jbegin_key,
  1017. jbegin_key_off, jbegin_key_len, jend_key,
  1018. jend_key_off, jend_key_len);
  1019. } else {
  1020. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1021. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  1022. "Invalid ColumnFamilyHandle."));
  1023. }
  1024. }
  1025. /*
  1026. * Class: org_rocksdb_RocksDB
  1027. * Method: clipColumnFamily
  1028. * Signature: (JJ[BII[BII)V
  1029. */
  1030. void Java_org_rocksdb_RocksDB_clipColumnFamily(
  1031. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1032. jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
  1033. jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
  1034. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1035. auto* cf_handle =
  1036. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1037. if (cf_handle != nullptr) {
  1038. jbyte* begin_key = new jbyte[jbegin_key_len];
  1039. env->GetByteArrayRegion(jbegin_key, jbegin_key_off, jbegin_key_len,
  1040. begin_key);
  1041. if (env->ExceptionCheck()) {
  1042. // exception thrown: ArrayIndexOutOfBoundsException
  1043. delete[] begin_key;
  1044. return;
  1045. }
  1046. ROCKSDB_NAMESPACE::Slice begin_key_slice(reinterpret_cast<char*>(begin_key),
  1047. jbegin_key_len);
  1048. jbyte* end_key = new jbyte[jend_key_len];
  1049. env->GetByteArrayRegion(jend_key, jend_key_off, jend_key_len, end_key);
  1050. if (env->ExceptionCheck()) {
  1051. // exception thrown: ArrayIndexOutOfBoundsException
  1052. delete[] begin_key;
  1053. delete[] end_key;
  1054. return;
  1055. }
  1056. ROCKSDB_NAMESPACE::Slice end_key_slice(reinterpret_cast<char*>(end_key),
  1057. jend_key_len);
  1058. ROCKSDB_NAMESPACE::Status s =
  1059. db->ClipColumnFamily(cf_handle, begin_key_slice, end_key_slice);
  1060. // cleanup
  1061. delete[] begin_key;
  1062. delete[] end_key;
  1063. if (s.ok()) {
  1064. return;
  1065. }
  1066. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1067. return;
  1068. } else {
  1069. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1070. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  1071. "Invalid ColumnFamilyHandle."));
  1072. }
  1073. }
  1074. /*
  1075. * Class: org_rocksdb_RocksDB
  1076. * Method: getDirect
  1077. * Signature: (JJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIJ)I
  1078. */
  1079. jint Java_org_rocksdb_RocksDB_getDirect(JNIEnv* env, jclass /*jdb*/,
  1080. jlong jdb_handle, jlong jropt_handle,
  1081. jobject jkey, jint jkey_off,
  1082. jint jkey_len, jobject jval,
  1083. jint jval_off, jint jval_len,
  1084. jlong jcf_handle) {
  1085. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1086. auto* ro_opt =
  1087. reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle);
  1088. auto* cf_handle =
  1089. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1090. try {
  1091. ROCKSDB_NAMESPACE::JDirectBufferSlice key(env, jkey, jkey_off, jkey_len);
  1092. ROCKSDB_NAMESPACE::JDirectBufferPinnableSlice value(env, jval, jval_off,
  1093. jval_len);
  1094. ROCKSDB_NAMESPACE::Status s;
  1095. if (cf_handle != nullptr) {
  1096. s = db->Get(
  1097. ro_opt == nullptr ? ROCKSDB_NAMESPACE::ReadOptions() : *ro_opt,
  1098. cf_handle, key.slice(), &value.pinnable_slice());
  1099. } else {
  1100. // backwards compatibility
  1101. s = db->Get(
  1102. ro_opt == nullptr ? ROCKSDB_NAMESPACE::ReadOptions() : *ro_opt,
  1103. db->DefaultColumnFamily(), key.slice(), &value.pinnable_slice());
  1104. }
  1105. ROCKSDB_NAMESPACE::KVException::ThrowOnError(env, s);
  1106. return value.Fetch();
  1107. } catch (ROCKSDB_NAMESPACE::KVException& e) {
  1108. return e.Code();
  1109. }
  1110. }
  1111. //////////////////////////////////////////////////////////////////////////////
  1112. // ROCKSDB_NAMESPACE::DB::Merge
  1113. /*
  1114. * Class: org_rocksdb_RocksDB
  1115. * Method: merge
  1116. * Signature: (J[BII[BII)V
  1117. */
  1118. void Java_org_rocksdb_RocksDB_merge__J_3BII_3BII(JNIEnv* env, jclass,
  1119. jlong jdb_handle,
  1120. jbyteArray jkey, jint jkey_off,
  1121. jint jkey_len, jbyteArray jval,
  1122. jint jval_off, jint jval_len) {
  1123. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1124. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  1125. ROCKSDB_NAMESPACE::WriteOptions();
  1126. try {
  1127. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1128. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  1129. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1130. env, db->Merge(default_write_options, key.slice(), value.slice()));
  1131. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1132. return;
  1133. }
  1134. }
  1135. /*
  1136. * Class: org_rocksdb_RocksDB
  1137. * Method: merge
  1138. * Signature: (J[BII[BIIJ)V
  1139. */
  1140. void Java_org_rocksdb_RocksDB_merge__J_3BII_3BIIJ(
  1141. JNIEnv* env, jclass, jlong jdb_handle, jbyteArray jkey, jint jkey_off,
  1142. jint jkey_len, jbyteArray jval, jint jval_off, jint jval_len,
  1143. jlong jcf_handle) {
  1144. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1145. static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
  1146. ROCKSDB_NAMESPACE::WriteOptions();
  1147. auto* cf_handle =
  1148. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1149. if (cf_handle != nullptr) {
  1150. try {
  1151. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1152. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  1153. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1154. env, db->Merge(default_write_options, cf_handle, key.slice(),
  1155. value.slice()));
  1156. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1157. return;
  1158. }
  1159. } else {
  1160. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1161. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  1162. "Invalid ColumnFamilyHandle."));
  1163. }
  1164. }
  1165. /*
  1166. * Class: org_rocksdb_RocksDB
  1167. * Method: merge
  1168. * Signature: (JJ[BII[BII)V
  1169. */
  1170. void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BII(
  1171. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options_handle,
  1172. jbyteArray jkey, jint jkey_off, jint jkey_len, jbyteArray jval,
  1173. jint jval_off, jint jval_len) {
  1174. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1175. auto* write_options =
  1176. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  1177. try {
  1178. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1179. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  1180. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1181. env, db->Merge(*write_options, key.slice(), value.slice()));
  1182. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1183. return;
  1184. }
  1185. }
  1186. /*
  1187. * Class: org_rocksdb_RocksDB
  1188. * Method: merge
  1189. * Signature: (JJ[BII[BIIJ)V
  1190. */
  1191. void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BIIJ(
  1192. JNIEnv* env, jclass, jlong jdb_handle, jlong jwrite_options_handle,
  1193. jbyteArray jkey, jint jkey_off, jint jkey_len, jbyteArray jval,
  1194. jint jval_off, jint jval_len, jlong jcf_handle) {
  1195. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1196. auto* write_options =
  1197. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  1198. auto* cf_handle =
  1199. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1200. if (cf_handle != nullptr) {
  1201. try {
  1202. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1203. ROCKSDB_NAMESPACE::JByteArraySlice value(env, jval, jval_off, jval_len);
  1204. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1205. env,
  1206. db->Merge(*write_options, cf_handle, key.slice(), value.slice()));
  1207. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1208. return;
  1209. }
  1210. } else {
  1211. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1212. env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
  1213. "Invalid ColumnFamilyHandle."));
  1214. }
  1215. }
  1216. /*
  1217. * Class: org_rocksdb_RocksDB
  1218. * Method: mergeDirect
  1219. * Signature: (JJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIJ)V
  1220. */
  1221. void Java_org_rocksdb_RocksDB_mergeDirect(
  1222. JNIEnv* env, jclass /*jdb*/, jlong jdb_handle, jlong jwrite_options_handle,
  1223. jobject jkey, jint jkey_off, jint jkey_len, jobject jval, jint jval_off,
  1224. jint jval_len, jlong jcf_handle) {
  1225. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1226. auto* write_options =
  1227. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  1228. auto* cf_handle =
  1229. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1230. auto merge = [&env, &db, &cf_handle, &write_options](
  1231. ROCKSDB_NAMESPACE::Slice& key,
  1232. ROCKSDB_NAMESPACE::Slice& value) {
  1233. ROCKSDB_NAMESPACE::Status s;
  1234. if (cf_handle == nullptr) {
  1235. s = db->Merge(*write_options, key, value);
  1236. } else {
  1237. s = db->Merge(*write_options, cf_handle, key, value);
  1238. }
  1239. if (s.ok()) {
  1240. return;
  1241. }
  1242. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1243. };
  1244. ROCKSDB_NAMESPACE::JniUtil::kv_op_direct(merge, env, jkey, jkey_off, jkey_len,
  1245. jval, jval_off, jval_len);
  1246. }
  1247. /*
  1248. * Class: org_rocksdb_RocksDB
  1249. * Method: deleteDirect
  1250. * Signature: (JJLjava/nio/ByteBuffer;IIJ)V
  1251. */
  1252. void Java_org_rocksdb_RocksDB_deleteDirect(JNIEnv* env, jclass /*jdb*/,
  1253. jlong jdb_handle,
  1254. jlong jwrite_options, jobject jkey,
  1255. jint jkey_offset, jint jkey_len,
  1256. jlong jcf_handle) {
  1257. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1258. auto* write_options =
  1259. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
  1260. auto* cf_handle =
  1261. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1262. auto remove = [&env, &db, &write_options,
  1263. &cf_handle](ROCKSDB_NAMESPACE::Slice& key) {
  1264. ROCKSDB_NAMESPACE::Status s;
  1265. if (cf_handle == nullptr) {
  1266. s = db->Delete(*write_options, key);
  1267. } else {
  1268. s = db->Delete(*write_options, cf_handle, key);
  1269. }
  1270. if (s.ok()) {
  1271. return;
  1272. }
  1273. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1274. };
  1275. ROCKSDB_NAMESPACE::JniUtil::k_op_direct(remove, env, jkey, jkey_offset,
  1276. jkey_len);
  1277. }
  1278. //////////////////////////////////////////////////////////////////////////////
  1279. // ROCKSDB_NAMESPACE::DB::Write
  1280. /*
  1281. * Class: org_rocksdb_RocksDB
  1282. * Method: write0
  1283. * Signature: (JJJ)V
  1284. */
  1285. void Java_org_rocksdb_RocksDB_write0(JNIEnv* env, jclass, jlong jdb_handle,
  1286. jlong jwrite_options_handle,
  1287. jlong jwb_handle) {
  1288. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1289. auto* write_options =
  1290. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  1291. auto* wb = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle);
  1292. ROCKSDB_NAMESPACE::Status s = db->Write(*write_options, wb);
  1293. if (!s.ok()) {
  1294. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1295. }
  1296. }
  1297. /*
  1298. * Class: org_rocksdb_RocksDB
  1299. * Method: write1
  1300. * Signature: (JJJ)V
  1301. */
  1302. void Java_org_rocksdb_RocksDB_write1(JNIEnv* env, jclass, jlong jdb_handle,
  1303. jlong jwrite_options_handle,
  1304. jlong jwbwi_handle) {
  1305. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1306. auto* write_options =
  1307. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  1308. auto* wbwi =
  1309. reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatchWithIndex*>(jwbwi_handle);
  1310. auto* wb = wbwi->GetWriteBatch();
  1311. ROCKSDB_NAMESPACE::Status s = db->Write(*write_options, wb);
  1312. if (!s.ok()) {
  1313. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1314. }
  1315. }
  1316. //////////////////////////////////////////////////////////////////////////////
  1317. // ROCKSDB_NAMESPACE::DB::Get
  1318. /*
  1319. * Class: org_rocksdb_RocksDB
  1320. * Method: get
  1321. * Signature: (J[BII)[B
  1322. */
  1323. jbyteArray Java_org_rocksdb_RocksDB_get__J_3BII(JNIEnv* env, jclass,
  1324. jlong jdb_handle,
  1325. jbyteArray jkey, jint jkey_off,
  1326. jint jkey_len) {
  1327. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1328. try {
  1329. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1330. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env);
  1331. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1332. env,
  1333. db->Get(ROCKSDB_NAMESPACE::ReadOptions(), db->DefaultColumnFamily(),
  1334. key.slice(), &value.pinnable_slice()));
  1335. return value.NewByteArray();
  1336. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1337. return nullptr;
  1338. }
  1339. }
  1340. /*
  1341. * Class: org_rocksdb_RocksDB
  1342. * Method: get
  1343. * Signature: (J[BIIJ)[B
  1344. */
  1345. jbyteArray Java_org_rocksdb_RocksDB_get__J_3BIIJ(JNIEnv* env, jclass,
  1346. jlong jdb_handle,
  1347. jbyteArray jkey, jint jkey_off,
  1348. jint jkey_len,
  1349. jlong jcf_handle) {
  1350. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1351. auto cf_handle = ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handleFromJLong(
  1352. env, jcf_handle);
  1353. if (cf_handle == nullptr) {
  1354. return nullptr;
  1355. }
  1356. try {
  1357. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1358. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env);
  1359. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1360. env, db->Get(ROCKSDB_NAMESPACE::ReadOptions(), cf_handle, key.slice(),
  1361. &value.pinnable_slice()));
  1362. return value.NewByteArray();
  1363. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1364. return nullptr;
  1365. }
  1366. }
  1367. /*
  1368. * Class: org_rocksdb_RocksDB
  1369. * Method: get
  1370. * Signature: (JJ[BII)[B
  1371. */
  1372. jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BII(JNIEnv* env, jclass,
  1373. jlong jdb_handle,
  1374. jlong jropt_handle,
  1375. jbyteArray jkey, jint jkey_off,
  1376. jint jkey_len) {
  1377. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1378. try {
  1379. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1380. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env);
  1381. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1382. env,
  1383. db->Get(
  1384. *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle),
  1385. db->DefaultColumnFamily(), key.slice(), &value.pinnable_slice()));
  1386. return value.NewByteArray();
  1387. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1388. return nullptr;
  1389. }
  1390. }
  1391. /*
  1392. * Class: org_rocksdb_RocksDB
  1393. * Method: get
  1394. * Signature: (JJ[BIIJ)[B
  1395. */
  1396. jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BIIJ(
  1397. JNIEnv* env, jclass, jlong jdb_handle, jlong jropt_handle, jbyteArray jkey,
  1398. jint jkey_off, jint jkey_len, jlong jcf_handle) {
  1399. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1400. auto cf_handle = ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handleFromJLong(
  1401. env, jcf_handle);
  1402. if (cf_handle == nullptr) {
  1403. return nullptr;
  1404. }
  1405. try {
  1406. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1407. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env);
  1408. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1409. env, db->Get(*reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
  1410. jropt_handle),
  1411. cf_handle, key.slice(), &value.pinnable_slice()));
  1412. return value.NewByteArray();
  1413. } catch (ROCKSDB_NAMESPACE::KVException&) {
  1414. return nullptr;
  1415. }
  1416. }
  1417. /*
  1418. * Class: org_rocksdb_RocksDB
  1419. * Method: get
  1420. * Signature: (J[BII[BII)I
  1421. */
  1422. jint Java_org_rocksdb_RocksDB_get__J_3BII_3BII(JNIEnv* env, jclass,
  1423. jlong jdb_handle,
  1424. jbyteArray jkey, jint jkey_off,
  1425. jint jkey_len, jbyteArray jval,
  1426. jint jval_off, jint jval_len) {
  1427. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1428. try {
  1429. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1430. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env, jval, jval_off,
  1431. jval_len);
  1432. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1433. env,
  1434. db->Get(ROCKSDB_NAMESPACE::ReadOptions(), db->DefaultColumnFamily(),
  1435. key.slice(), &value.pinnable_slice()));
  1436. return value.Fetch();
  1437. } catch (ROCKSDB_NAMESPACE::KVException& e) {
  1438. return e.Code();
  1439. }
  1440. }
  1441. /*
  1442. * Class: org_rocksdb_RocksDB
  1443. * Method: get
  1444. * Signature: (J[BII[BIIJ)I
  1445. */
  1446. jint Java_org_rocksdb_RocksDB_get__J_3BII_3BIIJ(JNIEnv* env, jclass,
  1447. jlong jdb_handle,
  1448. jbyteArray jkey, jint jkey_off,
  1449. jint jkey_len, jbyteArray jval,
  1450. jint jval_off, jint jval_len,
  1451. jlong jcf_handle) {
  1452. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1453. auto cf_handle = ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handleFromJLong(
  1454. env, jcf_handle);
  1455. if (cf_handle == nullptr) {
  1456. return ROCKSDB_NAMESPACE::KVException::kStatusError;
  1457. }
  1458. try {
  1459. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1460. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env, jval, jval_off,
  1461. jval_len);
  1462. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1463. env, db->Get(ROCKSDB_NAMESPACE::ReadOptions(), cf_handle, key.slice(),
  1464. &value.pinnable_slice()));
  1465. return value.Fetch();
  1466. } catch (ROCKSDB_NAMESPACE::KVException& e) {
  1467. return e.Code();
  1468. }
  1469. }
  1470. /*
  1471. * Class: org_rocksdb_RocksDB
  1472. * Method: get
  1473. * Signature: (JJ[BII[BII)I
  1474. */
  1475. jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BII(JNIEnv* env, jclass,
  1476. jlong jdb_handle,
  1477. jlong jropt_handle,
  1478. jbyteArray jkey, jint jkey_off,
  1479. jint jkey_len, jbyteArray jval,
  1480. jint jval_off, jint jval_len) {
  1481. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1482. try {
  1483. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1484. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env, jval, jval_off,
  1485. jval_len);
  1486. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1487. env,
  1488. db->Get(
  1489. *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle),
  1490. db->DefaultColumnFamily(), key.slice(), &value.pinnable_slice()));
  1491. return value.Fetch();
  1492. } catch (ROCKSDB_NAMESPACE::KVException& e) {
  1493. return e.Code();
  1494. }
  1495. }
  1496. /*
  1497. * Class: org_rocksdb_RocksDB
  1498. * Method: get
  1499. * Signature: (JJ[BII[BIIJ)I
  1500. */
  1501. jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BIIJ(
  1502. JNIEnv* env, jclass, jlong jdb_handle, jlong jropt_handle, jbyteArray jkey,
  1503. jint jkey_off, jint jkey_len, jbyteArray jval, jint jval_off, jint jval_len,
  1504. jlong jcf_handle) {
  1505. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1506. auto cf_handle = ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handleFromJLong(
  1507. env, jcf_handle);
  1508. if (cf_handle == nullptr) {
  1509. return ROCKSDB_NAMESPACE::KVException::kStatusError;
  1510. }
  1511. try {
  1512. ROCKSDB_NAMESPACE::JByteArraySlice key(env, jkey, jkey_off, jkey_len);
  1513. ROCKSDB_NAMESPACE::JByteArrayPinnableSlice value(env, jval, jval_off,
  1514. jval_len);
  1515. ROCKSDB_NAMESPACE::KVException::ThrowOnError(
  1516. env, db->Get(*reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
  1517. jropt_handle),
  1518. cf_handle, key.slice(), &value.pinnable_slice()));
  1519. return value.Fetch();
  1520. } catch (ROCKSDB_NAMESPACE::KVException& e) {
  1521. return e.Code();
  1522. }
  1523. }
  1524. /**
  1525. * cf multi get
  1526. *
  1527. * fill supplied native buffers, or raise JNI
  1528. * exception on a problem
  1529. */
  1530. /*
  1531. * @brief Use the efficient/optimized variant of MultiGet()
  1532. *
  1533. * Class: org_rocksdb_RocksDB
  1534. * Method: multiGet
  1535. * Signature: (J[[B[I[I)[[B
  1536. */
  1537. jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I(
  1538. JNIEnv* env, jclass, jlong jdb_handle, jobjectArray jkeys,
  1539. jintArray jkey_offs, jintArray jkey_lens) {
  1540. ROCKSDB_NAMESPACE::MultiGetJNIKeys keys;
  1541. if (!keys.fromByteArrays(env, jkeys, jkey_offs, jkey_lens)) {
  1542. return nullptr;
  1543. }
  1544. std::vector<ROCKSDB_NAMESPACE::PinnableSlice> values(keys.size());
  1545. std::vector<ROCKSDB_NAMESPACE::Status> statuses(keys.size());
  1546. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1547. db->MultiGet(ROCKSDB_NAMESPACE::ReadOptions(), db->DefaultColumnFamily(),
  1548. keys.size(), keys.data(), values.data(), statuses.data(),
  1549. false /* sorted_input*/);
  1550. return ROCKSDB_NAMESPACE::MultiGetJNIValues::byteArrays(env, values,
  1551. statuses);
  1552. }
  1553. /*
  1554. * @brief Use the efficient/optimized variant of MultiGet()
  1555. *
  1556. * Class: org_rocksdb_RocksDB
  1557. * Method: multiGet
  1558. * Signature: (J[[B[I[I[J)[[B
  1559. */
  1560. jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I_3J(
  1561. JNIEnv* env, jclass, jlong jdb_handle, jobjectArray jkeys,
  1562. jintArray jkey_offs, jintArray jkey_lens,
  1563. jlongArray jcolumn_family_handles) {
  1564. ROCKSDB_NAMESPACE::MultiGetJNIKeys keys;
  1565. if (!keys.fromByteArrays(env, jkeys, jkey_offs, jkey_lens)) return nullptr;
  1566. auto cf_handles =
  1567. ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handlesFromJLongArray(
  1568. env, jcolumn_family_handles);
  1569. if (!cf_handles) return nullptr;
  1570. std::vector<ROCKSDB_NAMESPACE::PinnableSlice> values(keys.size());
  1571. std::vector<ROCKSDB_NAMESPACE::Status> statuses(keys.size());
  1572. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1573. db->MultiGet(ROCKSDB_NAMESPACE::ReadOptions(), keys.size(),
  1574. cf_handles->data(), keys.data(), values.data(), statuses.data(),
  1575. /* sorted_input */ false);
  1576. return ROCKSDB_NAMESPACE::MultiGetJNIValues::byteArrays(env, values,
  1577. statuses);
  1578. }
  1579. /*
  1580. * @brief Use the efficient/optimized variant of MultiGet()
  1581. *
  1582. * Class: org_rocksdb_RocksDB
  1583. * Method: multiGet
  1584. * Signature: (JJ[[B[I[I)[[B
  1585. */
  1586. jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I(
  1587. JNIEnv* env, jclass, jlong jdb_handle, jlong jropt_handle,
  1588. jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) {
  1589. ROCKSDB_NAMESPACE::MultiGetJNIKeys keys;
  1590. if (!keys.fromByteArrays(env, jkeys, jkey_offs, jkey_lens)) {
  1591. return nullptr;
  1592. }
  1593. std::vector<ROCKSDB_NAMESPACE::PinnableSlice> values(keys.size());
  1594. std::vector<ROCKSDB_NAMESPACE::Status> statuses(keys.size());
  1595. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1596. db->MultiGet(*reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle),
  1597. db->DefaultColumnFamily(), keys.size(), keys.data(),
  1598. values.data(), statuses.data(), false /* sorted_input*/);
  1599. return ROCKSDB_NAMESPACE::MultiGetJNIValues::byteArrays(env, values,
  1600. statuses);
  1601. }
  1602. /*
  1603. * @brief Use the efficient/optimized variant of MultiGet()
  1604. *
  1605. * Class: org_rocksdb_RocksDB
  1606. * Method: multiGet
  1607. * Signature: (JJ[[B[I[I[J)[[B
  1608. */
  1609. jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I_3J(
  1610. JNIEnv* env, jclass, jlong jdb_handle, jlong jropt_handle,
  1611. jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
  1612. jlongArray jcolumn_family_handles) {
  1613. ROCKSDB_NAMESPACE::MultiGetJNIKeys keys;
  1614. if (!keys.fromByteArrays(env, jkeys, jkey_offs, jkey_lens)) return nullptr;
  1615. auto cf_handles =
  1616. ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handlesFromJLongArray(
  1617. env, jcolumn_family_handles);
  1618. if (!cf_handles) return nullptr;
  1619. std::vector<ROCKSDB_NAMESPACE::PinnableSlice> values(keys.size());
  1620. std::vector<ROCKSDB_NAMESPACE::Status> statuses(keys.size());
  1621. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1622. db->MultiGet(*reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle),
  1623. keys.size(), cf_handles->data(), keys.data(), values.data(),
  1624. statuses.data(),
  1625. /* sorted_input */ false);
  1626. return ROCKSDB_NAMESPACE::MultiGetJNIValues::byteArrays(env, values,
  1627. statuses);
  1628. }
  1629. /*
  1630. * @brief Use the efficient/optimized variant of MultiGet()
  1631. *
  1632. * Should make use of fast-path multiget (io_uring) on Linux
  1633. *
  1634. * Class: org_rocksdb_RocksDB
  1635. * Method: multiGet
  1636. * Signature:
  1637. * (JJ[J[Ljava/nio/ByteBuffer;[I[I[Ljava/nio/ByteBuffer;[I[Lorg/rocksdb/Status;)V
  1638. */
  1639. void Java_org_rocksdb_RocksDB_multiGet__JJ_3J_3Ljava_nio_ByteBuffer_2_3I_3I_3Ljava_nio_ByteBuffer_2_3I_3Lorg_rocksdb_Status_2(
  1640. JNIEnv* env, jclass, jlong jdb_handle, jlong jropt_handle,
  1641. jlongArray jcolumn_family_handles, jobjectArray jkeys, jintArray jkey_offs,
  1642. jintArray jkey_lens, jobjectArray jvalues, jintArray jvalues_sizes,
  1643. jobjectArray jstatus_objects) {
  1644. ROCKSDB_NAMESPACE::MultiGetJNIKeys keys;
  1645. if (!keys.fromByteBuffers(env, jkeys, jkey_offs, jkey_lens)) {
  1646. // exception thrown
  1647. return;
  1648. }
  1649. auto cf_handles =
  1650. ROCKSDB_NAMESPACE::ColumnFamilyJNIHelpers::handlesFromJLongArray(
  1651. env, jcolumn_family_handles);
  1652. std::vector<ROCKSDB_NAMESPACE::PinnableSlice> values(keys.size());
  1653. std::vector<ROCKSDB_NAMESPACE::Status> statuses(keys.size());
  1654. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1655. auto ro = *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle);
  1656. if (cf_handles->size() == 0) {
  1657. db->MultiGet(ro, db->DefaultColumnFamily(), keys.size(), keys.data(),
  1658. values.data(), statuses.data(), false /* sorted_input*/);
  1659. } else if (cf_handles->size() == 1) {
  1660. db->MultiGet(ro, cf_handles->data()[0], keys.size(), keys.data(),
  1661. values.data(), statuses.data(), false /* sorted_input*/);
  1662. } else {
  1663. db->MultiGet(ro, keys.size(), cf_handles->data(), keys.data(),
  1664. values.data(), statuses.data(),
  1665. /* sorted_input */ false);
  1666. }
  1667. ROCKSDB_NAMESPACE::MultiGetJNIValues::fillByteBuffersAndStatusObjects(
  1668. env, values, statuses, jvalues, jvalues_sizes, jstatus_objects);
  1669. }
  1670. //////////////////////////////////////////////////////////////////////////////
  1671. // ROCKSDB_NAMESPACE::DB::KeyMayExist
  1672. bool key_may_exist_helper(JNIEnv* env, jlong jdb_handle, jlong jcf_handle,
  1673. jlong jread_opts_handle, jbyteArray jkey,
  1674. jint jkey_offset, jint jkey_len, bool* has_exception,
  1675. std::string* value, bool* value_found) {
  1676. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1677. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  1678. if (jcf_handle == 0) {
  1679. cf_handle = db->DefaultColumnFamily();
  1680. } else {
  1681. cf_handle =
  1682. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1683. }
  1684. ROCKSDB_NAMESPACE::ReadOptions read_opts =
  1685. jread_opts_handle == 0
  1686. ? ROCKSDB_NAMESPACE::ReadOptions()
  1687. : *(reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
  1688. jread_opts_handle));
  1689. jbyte* key = new jbyte[jkey_len];
  1690. env->GetByteArrayRegion(jkey, jkey_offset, jkey_len, key);
  1691. if (env->ExceptionCheck()) {
  1692. // exception thrown: ArrayIndexOutOfBoundsException
  1693. delete[] key;
  1694. *has_exception = true;
  1695. return false;
  1696. }
  1697. ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
  1698. const bool exists =
  1699. db->KeyMayExist(read_opts, cf_handle, key_slice, value, value_found);
  1700. // cleanup
  1701. delete[] key;
  1702. return exists;
  1703. }
  1704. bool key_may_exist_direct_helper(JNIEnv* env, jlong jdb_handle,
  1705. jlong jcf_handle, jlong jread_opts_handle,
  1706. jobject jkey, jint jkey_offset, jint jkey_len,
  1707. bool* has_exception, std::string* value,
  1708. bool* value_found) {
  1709. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1710. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  1711. if (jcf_handle == 0) {
  1712. cf_handle = db->DefaultColumnFamily();
  1713. } else {
  1714. cf_handle =
  1715. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1716. }
  1717. ROCKSDB_NAMESPACE::ReadOptions read_opts =
  1718. jread_opts_handle == 0
  1719. ? ROCKSDB_NAMESPACE::ReadOptions()
  1720. : *(reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
  1721. jread_opts_handle));
  1722. char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
  1723. if (key == nullptr) {
  1724. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1725. env,
  1726. "Invalid key argument (argument is not a valid direct ByteBuffer)");
  1727. *has_exception = true;
  1728. return false;
  1729. }
  1730. if (env->GetDirectBufferCapacity(jkey) < (jkey_offset + jkey_len)) {
  1731. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1732. env,
  1733. "Invalid key argument. Capacity is less than requested region (offset "
  1734. "+ length).");
  1735. *has_exception = true;
  1736. return false;
  1737. }
  1738. ROCKSDB_NAMESPACE::Slice key_slice(key, jkey_len);
  1739. const bool exists =
  1740. db->KeyMayExist(read_opts, cf_handle, key_slice, value, value_found);
  1741. return exists;
  1742. }
  1743. jboolean key_exists_helper(JNIEnv* env, jlong jdb_handle, jlong jcf_handle,
  1744. jlong jread_opts_handle, char* key, jint jkey_len) {
  1745. std::string value;
  1746. bool value_found = false;
  1747. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  1748. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  1749. if (jcf_handle == 0) {
  1750. cf_handle = db->DefaultColumnFamily();
  1751. } else {
  1752. cf_handle =
  1753. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  1754. }
  1755. ROCKSDB_NAMESPACE::ReadOptions read_opts =
  1756. jread_opts_handle == 0
  1757. ? ROCKSDB_NAMESPACE::ReadOptions()
  1758. : *(reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
  1759. jread_opts_handle));
  1760. ROCKSDB_NAMESPACE::Slice key_slice(key, jkey_len);
  1761. const bool may_exist =
  1762. db->KeyMayExist(read_opts, cf_handle, key_slice, &value, &value_found);
  1763. if (may_exist) {
  1764. ROCKSDB_NAMESPACE::Status s;
  1765. {
  1766. ROCKSDB_NAMESPACE::PinnableSlice pinnable_val;
  1767. s = db->Get(read_opts, cf_handle, key_slice, &pinnable_val);
  1768. }
  1769. if (s.IsNotFound()) {
  1770. return JNI_FALSE;
  1771. } else if (s.ok()) {
  1772. return JNI_TRUE;
  1773. } else {
  1774. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  1775. return JNI_FALSE;
  1776. }
  1777. } else {
  1778. return JNI_FALSE;
  1779. }
  1780. }
  1781. /*
  1782. * Class: org_rocksdb_RocksDB
  1783. * Method: keyExist
  1784. * Signature: (JJJ[BII)Z
  1785. */
  1786. jboolean Java_org_rocksdb_RocksDB_keyExists(JNIEnv* env, jclass,
  1787. jlong jdb_handle, jlong jcf_handle,
  1788. jlong jread_opts_handle,
  1789. jbyteArray jkey, jint jkey_offset,
  1790. jint jkey_len) {
  1791. jbyte* key = new jbyte[jkey_len];
  1792. env->GetByteArrayRegion(jkey, jkey_offset, jkey_len, key);
  1793. if (env->ExceptionCheck()) {
  1794. // exception thrown: ArrayIndexOutOfBoundsException
  1795. delete[] key;
  1796. return JNI_FALSE;
  1797. } else {
  1798. jboolean key_exists =
  1799. key_exists_helper(env, jdb_handle, jcf_handle, jread_opts_handle,
  1800. reinterpret_cast<char*>(key), jkey_len);
  1801. delete[] key;
  1802. return key_exists;
  1803. }
  1804. }
  1805. /*
  1806. private native boolean keyExistDirect(final long handle, final long
  1807. cfHandle, final long readOptHandle, final ByteBuffer key, final int keyOffset,
  1808. final int keyLength);
  1809. * Class: org_rocksdb_RocksDB
  1810. * Method: keyExistDirect
  1811. * Signature: (JJJLjava/nio/ByteBuffer;II)Z
  1812. */
  1813. jboolean Java_org_rocksdb_RocksDB_keyExistsDirect(
  1814. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1815. jlong jread_opts_handle, jobject jkey, jint jkey_offset, jint jkey_len) {
  1816. char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
  1817. if (key == nullptr) {
  1818. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1819. env,
  1820. "Invalid key argument (argument is not a valid direct ByteBuffer)");
  1821. return JNI_FALSE;
  1822. }
  1823. if (env->GetDirectBufferCapacity(jkey) < (jkey_offset + jkey_len)) {
  1824. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1825. env,
  1826. "Invalid key argument. Capacity is less than requested region (offset "
  1827. "+ length).");
  1828. return JNI_FALSE;
  1829. }
  1830. return key_exists_helper(env, jdb_handle, jcf_handle, jread_opts_handle, key,
  1831. jkey_len);
  1832. }
  1833. /*
  1834. * Class: org_rocksdb_RocksDB
  1835. * Method: keyMayExist
  1836. * Signature: (JJJ[BII)Z
  1837. */
  1838. jboolean Java_org_rocksdb_RocksDB_keyMayExist(
  1839. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1840. jlong jread_opts_handle, jbyteArray jkey, jint jkey_offset, jint jkey_len) {
  1841. bool has_exception = false;
  1842. std::string value;
  1843. bool value_found = false;
  1844. const bool exists = key_may_exist_helper(
  1845. env, jdb_handle, jcf_handle, jread_opts_handle, jkey, jkey_offset,
  1846. jkey_len, &has_exception, &value, &value_found);
  1847. if (has_exception) {
  1848. // java exception already raised
  1849. return false;
  1850. }
  1851. return static_cast<jboolean>(exists);
  1852. }
  1853. /*
  1854. * Class: org_rocksdb_RocksDB
  1855. * Method: keyMayExistDirect
  1856. * Signature: (JJJLjava/nio/ByteBuffer;II)Z
  1857. */
  1858. jboolean Java_org_rocksdb_RocksDB_keyMayExistDirect(
  1859. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1860. jlong jread_opts_handle, jobject jkey, jint jkey_offset, jint jkey_len) {
  1861. bool has_exception = false;
  1862. std::string value;
  1863. bool value_found = false;
  1864. const bool exists = key_may_exist_direct_helper(
  1865. env, jdb_handle, jcf_handle, jread_opts_handle, jkey, jkey_offset,
  1866. jkey_len, &has_exception, &value, &value_found);
  1867. if (has_exception) {
  1868. // java exception already raised
  1869. return false;
  1870. }
  1871. return static_cast<jboolean>(exists);
  1872. }
  1873. /*
  1874. * Class: org_rocksdb_RocksDB
  1875. * Method: keyMayExistDirectFoundValue
  1876. * Signature:
  1877. * (JJJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)[J
  1878. */
  1879. jintArray Java_org_rocksdb_RocksDB_keyMayExistDirectFoundValue(
  1880. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1881. jlong jread_opts_handle, jobject jkey, jint jkey_offset, jint jkey_len,
  1882. jobject jval, jint jval_offset, jint jval_len) {
  1883. char* val_buffer = reinterpret_cast<char*>(env->GetDirectBufferAddress(jval));
  1884. if (val_buffer == nullptr) {
  1885. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1886. env,
  1887. "Invalid value argument (argument is not a valid direct ByteBuffer)");
  1888. return nullptr;
  1889. }
  1890. if (env->GetDirectBufferCapacity(jval) < (jval_offset + jval_len)) {
  1891. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  1892. env,
  1893. "Invalid value argument. Capacity is less than requested region "
  1894. "(offset + length).");
  1895. return nullptr;
  1896. }
  1897. bool has_exception = false;
  1898. std::string cvalue;
  1899. bool value_found = false;
  1900. const bool exists = key_may_exist_direct_helper(
  1901. env, jdb_handle, jcf_handle, jread_opts_handle, jkey, jkey_offset,
  1902. jkey_len, &has_exception, &cvalue, &value_found);
  1903. if (has_exception) {
  1904. // java exception already raised
  1905. return nullptr;
  1906. }
  1907. const jint cvalue_len = static_cast<jint>(cvalue.size());
  1908. const jint length = std::min(jval_len, cvalue_len);
  1909. memcpy(val_buffer + jval_offset, cvalue.c_str(), length);
  1910. // keep consistent with java KeyMayExistEnum.values()
  1911. const int kNotExist = 0;
  1912. const int kExistsWithoutValue = 1;
  1913. const int kExistsWithValue = 2;
  1914. // TODO fix return value/type
  1915. // exists/value_found/neither
  1916. // cvalue_len
  1917. jintArray jresult = env->NewIntArray(2);
  1918. const jint jexists =
  1919. exists ? (value_found ? kExistsWithValue : kExistsWithoutValue)
  1920. : kNotExist;
  1921. env->SetIntArrayRegion(jresult, 0, 1, &jexists);
  1922. if (env->ExceptionCheck()) {
  1923. // exception thrown: ArrayIndexOutOfBoundsException
  1924. env->DeleteLocalRef(jresult);
  1925. return nullptr;
  1926. }
  1927. env->SetIntArrayRegion(jresult, 1, 1, &cvalue_len);
  1928. if (env->ExceptionCheck()) {
  1929. // exception thrown: ArrayIndexOutOfBoundsException
  1930. env->DeleteLocalRef(jresult);
  1931. return nullptr;
  1932. }
  1933. return jresult;
  1934. }
  1935. /*
  1936. * Class: org_rocksdb_RocksDB
  1937. * Method: keyMayExistFoundValue
  1938. * Signature: (JJJ[BII)[[B
  1939. */
  1940. jobjectArray Java_org_rocksdb_RocksDB_keyMayExistFoundValue(
  1941. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  1942. jlong jread_opts_handle, jbyteArray jkey, jint jkey_offset, jint jkey_len) {
  1943. bool has_exception = false;
  1944. std::string value;
  1945. bool value_found = false;
  1946. const bool exists = key_may_exist_helper(
  1947. env, jdb_handle, jcf_handle, jread_opts_handle, jkey, jkey_offset,
  1948. jkey_len, &has_exception, &value, &value_found);
  1949. if (has_exception) {
  1950. // java exception already raised
  1951. return nullptr;
  1952. }
  1953. jbyte result_flags[1];
  1954. if (!exists) {
  1955. result_flags[0] = 0;
  1956. } else if (!value_found) {
  1957. result_flags[0] = 1;
  1958. } else {
  1959. // found
  1960. result_flags[0] = 2;
  1961. }
  1962. jobjectArray jresults = ROCKSDB_NAMESPACE::ByteJni::new2dByteArray(env, 2);
  1963. if (jresults == nullptr) {
  1964. // exception occurred
  1965. return nullptr;
  1966. }
  1967. // prepare the result flag
  1968. jbyteArray jresult_flags = env->NewByteArray(1);
  1969. if (jresult_flags == nullptr) {
  1970. // exception thrown: OutOfMemoryError
  1971. return nullptr;
  1972. }
  1973. env->SetByteArrayRegion(jresult_flags, 0, 1, result_flags);
  1974. if (env->ExceptionCheck()) {
  1975. // exception thrown: ArrayIndexOutOfBoundsException
  1976. env->DeleteLocalRef(jresult_flags);
  1977. return nullptr;
  1978. }
  1979. env->SetObjectArrayElement(jresults, 0, jresult_flags);
  1980. if (env->ExceptionCheck()) {
  1981. // exception thrown: ArrayIndexOutOfBoundsException
  1982. env->DeleteLocalRef(jresult_flags);
  1983. return nullptr;
  1984. }
  1985. env->DeleteLocalRef(jresult_flags);
  1986. if (result_flags[0] == 2) {
  1987. // set the value
  1988. const jsize jvalue_len = static_cast<jsize>(value.size());
  1989. jbyteArray jresult_value = env->NewByteArray(jvalue_len);
  1990. if (jresult_value == nullptr) {
  1991. // exception thrown: OutOfMemoryError
  1992. return nullptr;
  1993. }
  1994. env->SetByteArrayRegion(
  1995. jresult_value, 0, jvalue_len,
  1996. const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.data())));
  1997. if (env->ExceptionCheck()) {
  1998. // exception thrown: ArrayIndexOutOfBoundsException
  1999. env->DeleteLocalRef(jresult_value);
  2000. return nullptr;
  2001. }
  2002. env->SetObjectArrayElement(jresults, 1, jresult_value);
  2003. if (env->ExceptionCheck()) {
  2004. // exception thrown: ArrayIndexOutOfBoundsException
  2005. env->DeleteLocalRef(jresult_value);
  2006. return nullptr;
  2007. }
  2008. env->DeleteLocalRef(jresult_value);
  2009. }
  2010. return jresults;
  2011. }
  2012. /*
  2013. * Class: org_rocksdb_RocksDB
  2014. * Method: iterator
  2015. * Signature: (JJJ)J
  2016. */
  2017. jlong Java_org_rocksdb_RocksDB_iterator(JNIEnv*, jclass, jlong db_handle,
  2018. jlong jcf_handle,
  2019. jlong jread_options_handle) {
  2020. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  2021. auto* cf_handle =
  2022. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2023. auto& read_options =
  2024. *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
  2025. return GET_CPLUSPLUS_POINTER(db->NewIterator(read_options, cf_handle));
  2026. }
  2027. /*
  2028. * Class: org_rocksdb_RocksDB
  2029. * Method: iterators
  2030. * Signature: (J[JJ)[J
  2031. */
  2032. jlongArray Java_org_rocksdb_RocksDB_iterators(JNIEnv* env, jclass,
  2033. jlong db_handle,
  2034. jlongArray jcolumn_family_handles,
  2035. jlong jread_options_handle) {
  2036. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  2037. auto& read_options =
  2038. *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
  2039. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  2040. if (jcolumn_family_handles != nullptr) {
  2041. const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
  2042. jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
  2043. if (jcfh == nullptr) {
  2044. // exception thrown: OutOfMemoryError
  2045. return nullptr;
  2046. }
  2047. for (jsize i = 0; i < len_cols; i++) {
  2048. auto* cf_handle =
  2049. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
  2050. cf_handles.push_back(cf_handle);
  2051. }
  2052. env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
  2053. }
  2054. std::vector<ROCKSDB_NAMESPACE::Iterator*> iterators;
  2055. ROCKSDB_NAMESPACE::Status s =
  2056. db->NewIterators(read_options, cf_handles, &iterators);
  2057. if (s.ok()) {
  2058. jlongArray jLongArray =
  2059. env->NewLongArray(static_cast<jsize>(iterators.size()));
  2060. if (jLongArray == nullptr) {
  2061. // exception thrown: OutOfMemoryError
  2062. return nullptr;
  2063. }
  2064. for (std::vector<ROCKSDB_NAMESPACE::Iterator*>::size_type i = 0;
  2065. i < iterators.size(); i++) {
  2066. env->SetLongArrayRegion(
  2067. jLongArray, static_cast<jsize>(i), 1,
  2068. const_cast<jlong*>(reinterpret_cast<const jlong*>(&iterators[i])));
  2069. if (env->ExceptionCheck()) {
  2070. // exception thrown: ArrayIndexOutOfBoundsException
  2071. env->DeleteLocalRef(jLongArray);
  2072. return nullptr;
  2073. }
  2074. }
  2075. return jLongArray;
  2076. } else {
  2077. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2078. return nullptr;
  2079. }
  2080. }
  2081. /*
  2082. * Method: getSnapshot
  2083. * Signature: (J)J
  2084. */
  2085. jlong Java_org_rocksdb_RocksDB_getSnapshot(JNIEnv*, jclass, jlong db_handle) {
  2086. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  2087. const ROCKSDB_NAMESPACE::Snapshot* snapshot = db->GetSnapshot();
  2088. return GET_CPLUSPLUS_POINTER(snapshot);
  2089. }
  2090. /*
  2091. * Method: releaseSnapshot
  2092. * Signature: (JJ)V
  2093. */
  2094. void Java_org_rocksdb_RocksDB_releaseSnapshot(JNIEnv*, jclass, jlong db_handle,
  2095. jlong snapshot_handle) {
  2096. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  2097. auto* snapshot =
  2098. reinterpret_cast<ROCKSDB_NAMESPACE::Snapshot*>(snapshot_handle);
  2099. db->ReleaseSnapshot(snapshot);
  2100. }
  2101. /*
  2102. * Class: org_rocksdb_RocksDB
  2103. * Method: getProperty
  2104. * Signature: (JJLjava/lang/String;I)Ljava/lang/String;
  2105. */
  2106. jstring Java_org_rocksdb_RocksDB_getProperty(JNIEnv* env, jclass,
  2107. jlong jdb_handle, jlong jcf_handle,
  2108. jstring jproperty,
  2109. jint jproperty_len) {
  2110. const char* property = env->GetStringUTFChars(jproperty, nullptr);
  2111. if (property == nullptr) {
  2112. // exception thrown: OutOfMemoryError
  2113. return nullptr;
  2114. }
  2115. ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
  2116. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2117. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2118. if (jcf_handle == 0) {
  2119. cf_handle = db->DefaultColumnFamily();
  2120. } else {
  2121. cf_handle =
  2122. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2123. }
  2124. std::string property_value;
  2125. bool retCode = db->GetProperty(cf_handle, property_name, &property_value);
  2126. env->ReleaseStringUTFChars(jproperty, property);
  2127. if (retCode) {
  2128. return env->NewStringUTF(property_value.c_str());
  2129. }
  2130. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  2131. env, ROCKSDB_NAMESPACE::Status::NotFound());
  2132. return nullptr;
  2133. }
  2134. /*
  2135. * Class: org_rocksdb_RocksDB
  2136. * Method: getMapProperty
  2137. * Signature: (JJLjava/lang/String;I)Ljava/util/Map;
  2138. */
  2139. jobject Java_org_rocksdb_RocksDB_getMapProperty(JNIEnv* env, jclass,
  2140. jlong jdb_handle,
  2141. jlong jcf_handle,
  2142. jstring jproperty,
  2143. jint jproperty_len) {
  2144. const char* property = env->GetStringUTFChars(jproperty, nullptr);
  2145. if (property == nullptr) {
  2146. // exception thrown: OutOfMemoryError
  2147. return nullptr;
  2148. }
  2149. ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
  2150. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2151. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2152. if (jcf_handle == 0) {
  2153. cf_handle = db->DefaultColumnFamily();
  2154. } else {
  2155. cf_handle =
  2156. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2157. }
  2158. std::map<std::string, std::string> property_value;
  2159. bool retCode = db->GetMapProperty(cf_handle, property_name, &property_value);
  2160. env->ReleaseStringUTFChars(jproperty, property);
  2161. if (retCode) {
  2162. return ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(env, &property_value);
  2163. }
  2164. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  2165. env, ROCKSDB_NAMESPACE::Status::NotFound());
  2166. return nullptr;
  2167. }
  2168. /*
  2169. * Class: org_rocksdb_RocksDB
  2170. * Method: getLongProperty
  2171. * Signature: (JJLjava/lang/String;I)J
  2172. */
  2173. jlong Java_org_rocksdb_RocksDB_getLongProperty(JNIEnv* env, jclass,
  2174. jlong jdb_handle,
  2175. jlong jcf_handle,
  2176. jstring jproperty,
  2177. jint jproperty_len) {
  2178. const char* property = env->GetStringUTFChars(jproperty, nullptr);
  2179. if (property == nullptr) {
  2180. // exception thrown: OutOfMemoryError
  2181. return 0;
  2182. }
  2183. ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
  2184. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2185. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2186. if (jcf_handle == 0) {
  2187. cf_handle = db->DefaultColumnFamily();
  2188. } else {
  2189. cf_handle =
  2190. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2191. }
  2192. uint64_t property_value;
  2193. bool retCode = db->GetIntProperty(cf_handle, property_name, &property_value);
  2194. env->ReleaseStringUTFChars(jproperty, property);
  2195. if (retCode) {
  2196. return property_value;
  2197. }
  2198. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  2199. env, ROCKSDB_NAMESPACE::Status::NotFound());
  2200. return 0;
  2201. }
  2202. /*
  2203. * Class: org_rocksdb_RocksDB
  2204. * Method: resetStats
  2205. * Signature: (J)V
  2206. */
  2207. void Java_org_rocksdb_RocksDB_resetStats(JNIEnv*, jclass, jlong jdb_handle) {
  2208. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2209. db->ResetStats();
  2210. }
  2211. /*
  2212. * Class: org_rocksdb_RocksDB
  2213. * Method: getAggregatedLongProperty
  2214. * Signature: (JLjava/lang/String;I)J
  2215. */
  2216. jlong Java_org_rocksdb_RocksDB_getAggregatedLongProperty(JNIEnv* env, jclass,
  2217. jlong db_handle,
  2218. jstring jproperty,
  2219. jint jproperty_len) {
  2220. const char* property = env->GetStringUTFChars(jproperty, nullptr);
  2221. if (property == nullptr) {
  2222. return 0;
  2223. }
  2224. ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
  2225. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  2226. uint64_t property_value = 0;
  2227. bool retCode = db->GetAggregatedIntProperty(property_name, &property_value);
  2228. env->ReleaseStringUTFChars(jproperty, property);
  2229. if (retCode) {
  2230. return property_value;
  2231. }
  2232. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  2233. env, ROCKSDB_NAMESPACE::Status::NotFound());
  2234. return 0;
  2235. }
  2236. /*
  2237. * Class: org_rocksdb_RocksDB
  2238. * Method: getApproximateSizes
  2239. * Signature: (JJ[JB)[J
  2240. */
  2241. jlongArray Java_org_rocksdb_RocksDB_getApproximateSizes(
  2242. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  2243. jlongArray jrange_slice_handles, jbyte jinclude_flags) {
  2244. const jsize jlen = env->GetArrayLength(jrange_slice_handles);
  2245. const size_t range_count = jlen / 2;
  2246. jlong* jranges = env->GetLongArrayElements(jrange_slice_handles, nullptr);
  2247. if (jranges == nullptr) {
  2248. // exception thrown: OutOfMemoryError
  2249. return nullptr;
  2250. }
  2251. auto ranges = std::unique_ptr<ROCKSDB_NAMESPACE::Range[]>(
  2252. new ROCKSDB_NAMESPACE::Range[range_count]);
  2253. size_t range_offset = 0;
  2254. for (jsize i = 0; i < jlen; ++i) {
  2255. auto* start = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jranges[i]);
  2256. auto* limit = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jranges[++i]);
  2257. ranges.get()[range_offset++] = ROCKSDB_NAMESPACE::Range(*start, *limit);
  2258. }
  2259. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2260. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2261. if (jcf_handle == 0) {
  2262. cf_handle = db->DefaultColumnFamily();
  2263. } else {
  2264. cf_handle =
  2265. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2266. }
  2267. auto sizes = std::unique_ptr<uint64_t[]>(new uint64_t[range_count]);
  2268. ROCKSDB_NAMESPACE::DB::SizeApproximationFlags include_flags =
  2269. ROCKSDB_NAMESPACE::DB::SizeApproximationFlags::NONE;
  2270. if (jinclude_flags & 1) {
  2271. include_flags =
  2272. ROCKSDB_NAMESPACE::DB::SizeApproximationFlags::INCLUDE_MEMTABLES;
  2273. }
  2274. if (jinclude_flags & 2) {
  2275. include_flags =
  2276. (include_flags |
  2277. ROCKSDB_NAMESPACE::DB::SizeApproximationFlags::INCLUDE_FILES);
  2278. }
  2279. db->GetApproximateSizes(cf_handle, ranges.get(),
  2280. static_cast<int>(range_count), sizes.get(),
  2281. include_flags);
  2282. // release LongArrayElements
  2283. env->ReleaseLongArrayElements(jrange_slice_handles, jranges, JNI_ABORT);
  2284. // prepare results
  2285. auto results = std::unique_ptr<jlong[]>(new jlong[range_count]);
  2286. for (size_t i = 0; i < range_count; ++i) {
  2287. results.get()[i] = static_cast<jlong>(sizes.get()[i]);
  2288. }
  2289. const jsize jrange_count = jlen / 2;
  2290. jlongArray jresults = env->NewLongArray(jrange_count);
  2291. if (jresults == nullptr) {
  2292. // exception thrown: OutOfMemoryError
  2293. return nullptr;
  2294. }
  2295. env->SetLongArrayRegion(jresults, 0, jrange_count, results.get());
  2296. if (env->ExceptionCheck()) {
  2297. // exception thrown: ArrayIndexOutOfBoundsException
  2298. env->DeleteLocalRef(jresults);
  2299. return nullptr;
  2300. }
  2301. return jresults;
  2302. }
  2303. /*
  2304. * Class: org_rocksdb_RocksDB
  2305. * Method: getApproximateMemTableStats
  2306. * Signature: (JJJJ)[J
  2307. */
  2308. jlongArray Java_org_rocksdb_RocksDB_getApproximateMemTableStats(
  2309. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle, jlong jstartHandle,
  2310. jlong jlimitHandle) {
  2311. auto* start = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jstartHandle);
  2312. auto* limit = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jlimitHandle);
  2313. const ROCKSDB_NAMESPACE::Range range(*start, *limit);
  2314. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2315. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2316. if (jcf_handle == 0) {
  2317. cf_handle = db->DefaultColumnFamily();
  2318. } else {
  2319. cf_handle =
  2320. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2321. }
  2322. uint64_t count = 0;
  2323. uint64_t sizes = 0;
  2324. db->GetApproximateMemTableStats(cf_handle, range, &count, &sizes);
  2325. // prepare results
  2326. jlong results[2] = {static_cast<jlong>(count), static_cast<jlong>(sizes)};
  2327. jlongArray jsizes = env->NewLongArray(2);
  2328. if (jsizes == nullptr) {
  2329. // exception thrown: OutOfMemoryError
  2330. return nullptr;
  2331. }
  2332. env->SetLongArrayRegion(jsizes, 0, 2, results);
  2333. if (env->ExceptionCheck()) {
  2334. // exception thrown: ArrayIndexOutOfBoundsException
  2335. env->DeleteLocalRef(jsizes);
  2336. return nullptr;
  2337. }
  2338. return jsizes;
  2339. }
  2340. /*
  2341. * Class: org_rocksdb_RocksDB
  2342. * Method: compactRange
  2343. * Signature: (J[BI[BIJJ)V
  2344. */
  2345. void Java_org_rocksdb_RocksDB_compactRange(JNIEnv* env, jclass,
  2346. jlong jdb_handle, jbyteArray jbegin,
  2347. jint jbegin_len, jbyteArray jend,
  2348. jint jend_len,
  2349. jlong jcompact_range_opts_handle,
  2350. jlong jcf_handle) {
  2351. jboolean has_exception = JNI_FALSE;
  2352. std::string str_begin;
  2353. if (jbegin_len > 0) {
  2354. str_begin = ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
  2355. env, jbegin, jbegin_len,
  2356. [](const char* str, const size_t len) { return std::string(str, len); },
  2357. &has_exception);
  2358. if (has_exception == JNI_TRUE) {
  2359. // exception occurred
  2360. return;
  2361. }
  2362. }
  2363. std::string str_end;
  2364. if (jend_len > 0) {
  2365. str_end = ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
  2366. env, jend, jend_len,
  2367. [](const char* str, const size_t len) { return std::string(str, len); },
  2368. &has_exception);
  2369. if (has_exception == JNI_TRUE) {
  2370. // exception occurred
  2371. return;
  2372. }
  2373. }
  2374. ROCKSDB_NAMESPACE::CompactRangeOptions* compact_range_opts = nullptr;
  2375. if (jcompact_range_opts_handle == 0) {
  2376. // NOTE: we DO own the pointer!
  2377. compact_range_opts = new ROCKSDB_NAMESPACE::CompactRangeOptions();
  2378. } else {
  2379. // NOTE: we do NOT own the pointer!
  2380. compact_range_opts =
  2381. reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(
  2382. jcompact_range_opts_handle);
  2383. }
  2384. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2385. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2386. if (jcf_handle == 0) {
  2387. cf_handle = db->DefaultColumnFamily();
  2388. } else {
  2389. cf_handle =
  2390. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2391. }
  2392. ROCKSDB_NAMESPACE::Status s;
  2393. std::unique_ptr<ROCKSDB_NAMESPACE::Slice> begin;
  2394. std::unique_ptr<ROCKSDB_NAMESPACE::Slice> end;
  2395. if (jbegin_len > 0) {
  2396. begin.reset(new ROCKSDB_NAMESPACE::Slice(str_begin));
  2397. }
  2398. if (jend_len > 0) {
  2399. end.reset(new ROCKSDB_NAMESPACE::Slice(str_end));
  2400. }
  2401. s = db->CompactRange(*compact_range_opts, cf_handle, begin.get(), end.get());
  2402. if (jcompact_range_opts_handle == 0) {
  2403. delete compact_range_opts;
  2404. }
  2405. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2406. }
  2407. /*
  2408. * Class: org_rocksdb_RocksDB
  2409. * Method: setOptions
  2410. * Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)V
  2411. */
  2412. void Java_org_rocksdb_RocksDB_setOptions(JNIEnv* env, jclass, jlong jdb_handle,
  2413. jlong jcf_handle, jobjectArray jkeys,
  2414. jobjectArray jvalues) {
  2415. const jsize len = env->GetArrayLength(jkeys);
  2416. assert(len == env->GetArrayLength(jvalues));
  2417. std::unordered_map<std::string, std::string> options_map;
  2418. for (jsize i = 0; i < len; i++) {
  2419. jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
  2420. if (env->ExceptionCheck()) {
  2421. // exception thrown: ArrayIndexOutOfBoundsException
  2422. return;
  2423. }
  2424. jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
  2425. if (env->ExceptionCheck()) {
  2426. // exception thrown: ArrayIndexOutOfBoundsException
  2427. env->DeleteLocalRef(jobj_key);
  2428. return;
  2429. }
  2430. jboolean has_exception = JNI_FALSE;
  2431. std::string s_key = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
  2432. env, reinterpret_cast<jstring>(jobj_key), &has_exception);
  2433. if (has_exception == JNI_TRUE) {
  2434. // exception occurred
  2435. env->DeleteLocalRef(jobj_value);
  2436. env->DeleteLocalRef(jobj_key);
  2437. return;
  2438. }
  2439. std::string s_value = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
  2440. env, reinterpret_cast<jstring>(jobj_value), &has_exception);
  2441. if (has_exception == JNI_TRUE) {
  2442. // exception occurred
  2443. env->DeleteLocalRef(jobj_value);
  2444. env->DeleteLocalRef(jobj_key);
  2445. return;
  2446. }
  2447. options_map[s_key] = s_value;
  2448. env->DeleteLocalRef(jobj_key);
  2449. env->DeleteLocalRef(jobj_value);
  2450. }
  2451. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2452. auto* cf_handle =
  2453. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2454. if (cf_handle == nullptr) {
  2455. cf_handle = db->DefaultColumnFamily();
  2456. }
  2457. auto s = db->SetOptions(cf_handle, options_map);
  2458. if (!s.ok()) {
  2459. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2460. }
  2461. }
  2462. /*
  2463. * Class: org_rocksdb_RocksDB
  2464. * Method: setDBOptions
  2465. * Signature: (J[Ljava/lang/String;[Ljava/lang/String;)V
  2466. */
  2467. void Java_org_rocksdb_RocksDB_setDBOptions(JNIEnv* env, jclass,
  2468. jlong jdb_handle, jobjectArray jkeys,
  2469. jobjectArray jvalues) {
  2470. const jsize len = env->GetArrayLength(jkeys);
  2471. assert(len == env->GetArrayLength(jvalues));
  2472. std::unordered_map<std::string, std::string> options_map;
  2473. for (jsize i = 0; i < len; i++) {
  2474. jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
  2475. if (env->ExceptionCheck()) {
  2476. // exception thrown: ArrayIndexOutOfBoundsException
  2477. return;
  2478. }
  2479. jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
  2480. if (env->ExceptionCheck()) {
  2481. // exception thrown: ArrayIndexOutOfBoundsException
  2482. env->DeleteLocalRef(jobj_key);
  2483. return;
  2484. }
  2485. jboolean has_exception = JNI_FALSE;
  2486. std::string s_key = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
  2487. env, reinterpret_cast<jstring>(jobj_key), &has_exception);
  2488. if (has_exception == JNI_TRUE) {
  2489. // exception occurred
  2490. env->DeleteLocalRef(jobj_value);
  2491. env->DeleteLocalRef(jobj_key);
  2492. return;
  2493. }
  2494. std::string s_value = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
  2495. env, reinterpret_cast<jstring>(jobj_value), &has_exception);
  2496. if (has_exception == JNI_TRUE) {
  2497. // exception occurred
  2498. env->DeleteLocalRef(jobj_value);
  2499. env->DeleteLocalRef(jobj_key);
  2500. return;
  2501. }
  2502. options_map[s_key] = s_value;
  2503. env->DeleteLocalRef(jobj_key);
  2504. env->DeleteLocalRef(jobj_value);
  2505. }
  2506. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2507. auto s = db->SetDBOptions(options_map);
  2508. if (!s.ok()) {
  2509. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2510. }
  2511. }
  2512. /*
  2513. * Class: org_rocksdb_RocksDB
  2514. * Method: getOptions
  2515. * Signature: (JJ)Ljava/lang/String;
  2516. */
  2517. jstring Java_org_rocksdb_RocksDB_getOptions(JNIEnv* env, jclass,
  2518. jlong jdb_handle,
  2519. jlong jcf_handle) {
  2520. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2521. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2522. if (jcf_handle == 0) {
  2523. cf_handle = db->DefaultColumnFamily();
  2524. } else {
  2525. cf_handle =
  2526. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2527. }
  2528. auto options = db->GetOptions(cf_handle);
  2529. std::string options_as_string;
  2530. ROCKSDB_NAMESPACE::Status s =
  2531. GetStringFromColumnFamilyOptions(&options_as_string, options);
  2532. if (!s.ok()) {
  2533. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2534. return nullptr;
  2535. }
  2536. return env->NewStringUTF(options_as_string.c_str());
  2537. }
  2538. /*
  2539. * Class: org_rocksdb_RocksDB
  2540. * Method: getDBOptions
  2541. * Signature: (J)Ljava/lang/String;
  2542. */
  2543. jstring Java_org_rocksdb_RocksDB_getDBOptions(JNIEnv* env, jclass,
  2544. jlong jdb_handle) {
  2545. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2546. auto options = db->GetDBOptions();
  2547. std::string options_as_string;
  2548. ROCKSDB_NAMESPACE::Status s =
  2549. GetStringFromDBOptions(&options_as_string, options);
  2550. if (!s.ok()) {
  2551. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2552. return nullptr;
  2553. }
  2554. return env->NewStringUTF(options_as_string.c_str());
  2555. }
  2556. /*
  2557. * Class: org_rocksdb_RocksDB
  2558. * Method: setPerfLevel
  2559. * Signature: (JB)V
  2560. */
  2561. void Java_org_rocksdb_RocksDB_setPerfLevel(JNIEnv*, jclass, jbyte jperf_level) {
  2562. rocksdb::SetPerfLevel(
  2563. ROCKSDB_NAMESPACE::PerfLevelTypeJni::toCppPerfLevelType(jperf_level));
  2564. }
  2565. /*
  2566. * Class: org_rocksdb_RocksDB
  2567. * Method: getPerfLevel
  2568. * Signature: (J)B
  2569. */
  2570. jbyte Java_org_rocksdb_RocksDB_getPerfLevelNative(JNIEnv*, jclass) {
  2571. return ROCKSDB_NAMESPACE::PerfLevelTypeJni::toJavaPerfLevelType(
  2572. rocksdb::GetPerfLevel());
  2573. }
  2574. /*
  2575. * Class: org_rocksdb_RocksDB
  2576. * Method: getPerfContextNative
  2577. * Signature: ()J
  2578. */
  2579. jlong Java_org_rocksdb_RocksDB_getPerfContextNative(JNIEnv*, jclass) {
  2580. ROCKSDB_NAMESPACE::PerfContext* perf_context = rocksdb::get_perf_context();
  2581. return reinterpret_cast<jlong>(perf_context);
  2582. }
  2583. /*
  2584. * Class: org_rocksdb_RocksDB
  2585. * Method: compactFiles
  2586. * Signature: (JJJ[Ljava/lang/String;IIJ)[Ljava/lang/String;
  2587. */
  2588. jobjectArray Java_org_rocksdb_RocksDB_compactFiles(
  2589. JNIEnv* env, jclass, jlong jdb_handle, jlong jcompaction_opts_handle,
  2590. jlong jcf_handle, jobjectArray jinput_file_names, jint joutput_level,
  2591. jint joutput_path_id, jlong jcompaction_job_info_handle) {
  2592. jboolean has_exception = JNI_FALSE;
  2593. const std::vector<std::string> input_file_names =
  2594. ROCKSDB_NAMESPACE::JniUtil::copyStrings(env, jinput_file_names,
  2595. &has_exception);
  2596. if (has_exception == JNI_TRUE) {
  2597. // exception occurred
  2598. return nullptr;
  2599. }
  2600. auto* compaction_opts =
  2601. reinterpret_cast<ROCKSDB_NAMESPACE::CompactionOptions*>(
  2602. jcompaction_opts_handle);
  2603. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2604. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2605. if (jcf_handle == 0) {
  2606. cf_handle = db->DefaultColumnFamily();
  2607. } else {
  2608. cf_handle =
  2609. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2610. }
  2611. ROCKSDB_NAMESPACE::CompactionJobInfo* compaction_job_info = nullptr;
  2612. if (jcompaction_job_info_handle != 0) {
  2613. compaction_job_info =
  2614. reinterpret_cast<ROCKSDB_NAMESPACE::CompactionJobInfo*>(
  2615. jcompaction_job_info_handle);
  2616. }
  2617. std::vector<std::string> output_file_names;
  2618. auto s = db->CompactFiles(*compaction_opts, cf_handle, input_file_names,
  2619. static_cast<int>(joutput_level),
  2620. static_cast<int>(joutput_path_id),
  2621. &output_file_names, compaction_job_info);
  2622. if (!s.ok()) {
  2623. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2624. return nullptr;
  2625. }
  2626. return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &output_file_names);
  2627. }
  2628. /*
  2629. * Class: org_rocksdb_RocksDB
  2630. * Method: cancelAllBackgroundWork
  2631. * Signature: (JZ)V
  2632. */
  2633. void Java_org_rocksdb_RocksDB_cancelAllBackgroundWork(JNIEnv*, jclass,
  2634. jlong jdb_handle,
  2635. jboolean jwait) {
  2636. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2637. ROCKSDB_NAMESPACE::CancelAllBackgroundWork(db, jwait);
  2638. }
  2639. /*
  2640. * Class: org_rocksdb_RocksDB
  2641. * Method: pauseBackgroundWork
  2642. * Signature: (J)V
  2643. */
  2644. void Java_org_rocksdb_RocksDB_pauseBackgroundWork(JNIEnv* env, jclass,
  2645. jlong jdb_handle) {
  2646. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2647. auto s = db->PauseBackgroundWork();
  2648. if (!s.ok()) {
  2649. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2650. }
  2651. }
  2652. /*
  2653. * Class: org_rocksdb_RocksDB
  2654. * Method: continueBackgroundWork
  2655. * Signature: (J)V
  2656. */
  2657. void Java_org_rocksdb_RocksDB_continueBackgroundWork(JNIEnv* env, jclass,
  2658. jlong jdb_handle) {
  2659. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2660. auto s = db->ContinueBackgroundWork();
  2661. if (!s.ok()) {
  2662. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2663. }
  2664. }
  2665. /*
  2666. * Class: org_rocksdb_RocksDB
  2667. * Method: enableAutoCompaction
  2668. * Signature: (J[J)V
  2669. */
  2670. void Java_org_rocksdb_RocksDB_enableAutoCompaction(JNIEnv* env, jclass,
  2671. jlong jdb_handle,
  2672. jlongArray jcf_handles) {
  2673. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2674. jboolean has_exception = JNI_FALSE;
  2675. const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles =
  2676. ROCKSDB_NAMESPACE::JniUtil::fromJPointers<
  2677. ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, jcf_handles,
  2678. &has_exception);
  2679. if (has_exception == JNI_TRUE) {
  2680. // exception occurred
  2681. return;
  2682. }
  2683. db->EnableAutoCompaction(cf_handles);
  2684. }
  2685. /*
  2686. * Class: org_rocksdb_RocksDB
  2687. * Method: numberLevels
  2688. * Signature: (JJ)I
  2689. */
  2690. jint Java_org_rocksdb_RocksDB_numberLevels(JNIEnv*, jclass, jlong jdb_handle,
  2691. jlong jcf_handle) {
  2692. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2693. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2694. if (jcf_handle == 0) {
  2695. cf_handle = db->DefaultColumnFamily();
  2696. } else {
  2697. cf_handle =
  2698. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2699. }
  2700. return static_cast<jint>(db->NumberLevels(cf_handle));
  2701. }
  2702. /*
  2703. * Class: org_rocksdb_RocksDB
  2704. * Method: maxMemCompactionLevel
  2705. * Signature: (JJ)I
  2706. */
  2707. jint Java_org_rocksdb_RocksDB_maxMemCompactionLevel(JNIEnv*, jclass,
  2708. jlong jdb_handle,
  2709. jlong jcf_handle) {
  2710. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2711. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2712. if (jcf_handle == 0) {
  2713. cf_handle = db->DefaultColumnFamily();
  2714. } else {
  2715. cf_handle =
  2716. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2717. }
  2718. return static_cast<jint>(db->MaxMemCompactionLevel(cf_handle));
  2719. }
  2720. /*
  2721. * Class: org_rocksdb_RocksDB
  2722. * Method: level0StopWriteTrigger
  2723. * Signature: (JJ)I
  2724. */
  2725. jint Java_org_rocksdb_RocksDB_level0StopWriteTrigger(JNIEnv*, jclass,
  2726. jlong jdb_handle,
  2727. jlong jcf_handle) {
  2728. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2729. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2730. if (jcf_handle == 0) {
  2731. cf_handle = db->DefaultColumnFamily();
  2732. } else {
  2733. cf_handle =
  2734. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2735. }
  2736. return static_cast<jint>(db->Level0StopWriteTrigger(cf_handle));
  2737. }
  2738. /*
  2739. * Class: org_rocksdb_RocksDB
  2740. * Method: getName
  2741. * Signature: (J)Ljava/lang/String;
  2742. */
  2743. jstring Java_org_rocksdb_RocksDB_getName(JNIEnv* env, jclass,
  2744. jlong jdb_handle) {
  2745. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2746. std::string name = db->GetName();
  2747. return ROCKSDB_NAMESPACE::JniUtil::toJavaString(env, &name, false);
  2748. }
  2749. /*
  2750. * Class: org_rocksdb_RocksDB
  2751. * Method: getEnv
  2752. * Signature: (J)J
  2753. */
  2754. jlong Java_org_rocksdb_RocksDB_getEnv(JNIEnv*, jclass, jlong jdb_handle) {
  2755. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2756. return GET_CPLUSPLUS_POINTER(db->GetEnv());
  2757. }
  2758. /*
  2759. * Class: org_rocksdb_RocksDB
  2760. * Method: flush
  2761. * Signature: (JJ[J)V
  2762. */
  2763. void Java_org_rocksdb_RocksDB_flush(JNIEnv* env, jclass, jlong jdb_handle,
  2764. jlong jflush_opts_handle,
  2765. jlongArray jcf_handles) {
  2766. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2767. auto* flush_opts =
  2768. reinterpret_cast<ROCKSDB_NAMESPACE::FlushOptions*>(jflush_opts_handle);
  2769. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
  2770. if (jcf_handles == nullptr) {
  2771. cf_handles.push_back(db->DefaultColumnFamily());
  2772. } else {
  2773. jboolean has_exception = JNI_FALSE;
  2774. cf_handles = ROCKSDB_NAMESPACE::JniUtil::fromJPointers<
  2775. ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, jcf_handles,
  2776. &has_exception);
  2777. if (has_exception) {
  2778. // exception occurred
  2779. return;
  2780. }
  2781. }
  2782. auto s = db->Flush(*flush_opts, cf_handles);
  2783. if (!s.ok()) {
  2784. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2785. }
  2786. }
  2787. /*
  2788. * Class: org_rocksdb_RocksDB
  2789. * Method: flushWal
  2790. * Signature: (JZ)V
  2791. */
  2792. void Java_org_rocksdb_RocksDB_flushWal(JNIEnv* env, jclass, jlong jdb_handle,
  2793. jboolean jsync) {
  2794. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2795. auto s = db->FlushWAL(jsync == JNI_TRUE);
  2796. if (!s.ok()) {
  2797. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2798. }
  2799. }
  2800. /*
  2801. * Class: org_rocksdb_RocksDB
  2802. * Method: syncWal
  2803. * Signature: (J)V
  2804. */
  2805. void Java_org_rocksdb_RocksDB_syncWal(JNIEnv* env, jclass, jlong jdb_handle) {
  2806. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2807. auto s = db->SyncWAL();
  2808. if (!s.ok()) {
  2809. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2810. }
  2811. }
  2812. /*
  2813. * Class: org_rocksdb_RocksDB
  2814. * Method: getLatestSequenceNumber
  2815. * Signature: (J)V
  2816. */
  2817. jlong Java_org_rocksdb_RocksDB_getLatestSequenceNumber(JNIEnv*, jclass,
  2818. jlong jdb_handle) {
  2819. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2820. return db->GetLatestSequenceNumber();
  2821. }
  2822. /*
  2823. * Class: org_rocksdb_RocksDB
  2824. * Method: disableFileDeletions
  2825. * Signature: (J)V
  2826. */
  2827. void Java_org_rocksdb_RocksDB_disableFileDeletions(JNIEnv* env, jclass,
  2828. jlong jdb_handle) {
  2829. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2830. ROCKSDB_NAMESPACE::Status s = db->DisableFileDeletions();
  2831. if (!s.ok()) {
  2832. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2833. }
  2834. }
  2835. /*
  2836. * Class: org_rocksdb_RocksDB
  2837. * Method: enableFileDeletions
  2838. * Signature: (JZ)V
  2839. */
  2840. void Java_org_rocksdb_RocksDB_enableFileDeletions(JNIEnv* env, jclass,
  2841. jlong jdb_handle) {
  2842. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2843. ROCKSDB_NAMESPACE::Status s = db->EnableFileDeletions();
  2844. if (!s.ok()) {
  2845. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2846. }
  2847. }
  2848. /*
  2849. * Class: org_rocksdb_RocksDB
  2850. * Method: getLiveFiles
  2851. * Signature: (JZ)[Ljava/lang/String;
  2852. */
  2853. jobjectArray Java_org_rocksdb_RocksDB_getLiveFiles(JNIEnv* env, jclass,
  2854. jlong jdb_handle,
  2855. jboolean jflush_memtable) {
  2856. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2857. std::vector<std::string> live_files;
  2858. uint64_t manifest_file_size = 0;
  2859. auto s = db->GetLiveFiles(live_files, &manifest_file_size,
  2860. jflush_memtable == JNI_TRUE);
  2861. if (!s.ok()) {
  2862. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2863. return nullptr;
  2864. }
  2865. // append the manifest_file_size to the vector
  2866. // for passing back to java
  2867. live_files.push_back(std::to_string(manifest_file_size));
  2868. return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &live_files);
  2869. }
  2870. /*
  2871. * Class: org_rocksdb_RocksDB
  2872. * Method: getSortedWalFiles
  2873. * Signature: (J)[Lorg/rocksdb/LogFile;
  2874. */
  2875. jobjectArray Java_org_rocksdb_RocksDB_getSortedWalFiles(JNIEnv* env, jclass,
  2876. jlong jdb_handle) {
  2877. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2878. std::vector<std::unique_ptr<ROCKSDB_NAMESPACE::LogFile>> sorted_wal_files;
  2879. auto s = db->GetSortedWalFiles(sorted_wal_files);
  2880. if (!s.ok()) {
  2881. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2882. return nullptr;
  2883. }
  2884. // convert to Java type
  2885. const jsize jlen = static_cast<jsize>(sorted_wal_files.size());
  2886. jobjectArray jsorted_wal_files = env->NewObjectArray(
  2887. jlen, ROCKSDB_NAMESPACE::LogFileJni::getJClass(env), nullptr);
  2888. if (jsorted_wal_files == nullptr) {
  2889. // exception thrown: OutOfMemoryError
  2890. return nullptr;
  2891. }
  2892. jsize i = 0;
  2893. for (auto it = sorted_wal_files.begin(); it != sorted_wal_files.end(); ++it) {
  2894. jobject jlog_file =
  2895. ROCKSDB_NAMESPACE::LogFileJni::fromCppLogFile(env, it->get());
  2896. if (jlog_file == nullptr) {
  2897. // exception occurred
  2898. env->DeleteLocalRef(jsorted_wal_files);
  2899. return nullptr;
  2900. }
  2901. env->SetObjectArrayElement(jsorted_wal_files, i++, jlog_file);
  2902. if (env->ExceptionCheck()) {
  2903. // exception occurred
  2904. env->DeleteLocalRef(jlog_file);
  2905. env->DeleteLocalRef(jsorted_wal_files);
  2906. return nullptr;
  2907. }
  2908. env->DeleteLocalRef(jlog_file);
  2909. }
  2910. return jsorted_wal_files;
  2911. }
  2912. /*
  2913. * Class: org_rocksdb_RocksDB
  2914. * Method: getUpdatesSince
  2915. * Signature: (JJ)J
  2916. */
  2917. jlong Java_org_rocksdb_RocksDB_getUpdatesSince(JNIEnv* env, jclass,
  2918. jlong jdb_handle,
  2919. jlong jsequence_number) {
  2920. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2921. ROCKSDB_NAMESPACE::SequenceNumber sequence_number =
  2922. static_cast<ROCKSDB_NAMESPACE::SequenceNumber>(jsequence_number);
  2923. std::unique_ptr<ROCKSDB_NAMESPACE::TransactionLogIterator> iter;
  2924. ROCKSDB_NAMESPACE::Status s = db->GetUpdatesSince(sequence_number, &iter);
  2925. if (s.ok()) {
  2926. return GET_CPLUSPLUS_POINTER(iter.release());
  2927. }
  2928. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  2929. return 0;
  2930. }
  2931. /*
  2932. * Class: org_rocksdb_RocksDB
  2933. * Method: getLiveFilesMetaData
  2934. * Signature: (J)[Lorg/rocksdb/LiveFileMetaData;
  2935. */
  2936. jobjectArray Java_org_rocksdb_RocksDB_getLiveFilesMetaData(JNIEnv* env, jclass,
  2937. jlong jdb_handle) {
  2938. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2939. std::vector<ROCKSDB_NAMESPACE::LiveFileMetaData> live_files_meta_data;
  2940. db->GetLiveFilesMetaData(&live_files_meta_data);
  2941. // convert to Java type
  2942. const jsize jlen = static_cast<jsize>(live_files_meta_data.size());
  2943. jobjectArray jlive_files_meta_data = env->NewObjectArray(
  2944. jlen, ROCKSDB_NAMESPACE::LiveFileMetaDataJni::getJClass(env), nullptr);
  2945. if (jlive_files_meta_data == nullptr) {
  2946. // exception thrown: OutOfMemoryError
  2947. return nullptr;
  2948. }
  2949. jsize i = 0;
  2950. for (auto it = live_files_meta_data.begin(); it != live_files_meta_data.end();
  2951. ++it) {
  2952. jobject jlive_file_meta_data =
  2953. ROCKSDB_NAMESPACE::LiveFileMetaDataJni::fromCppLiveFileMetaData(env,
  2954. &(*it));
  2955. if (jlive_file_meta_data == nullptr) {
  2956. // exception occurred
  2957. env->DeleteLocalRef(jlive_files_meta_data);
  2958. return nullptr;
  2959. }
  2960. env->SetObjectArrayElement(jlive_files_meta_data, i++,
  2961. jlive_file_meta_data);
  2962. if (env->ExceptionCheck()) {
  2963. // exception occurred
  2964. env->DeleteLocalRef(jlive_file_meta_data);
  2965. env->DeleteLocalRef(jlive_files_meta_data);
  2966. return nullptr;
  2967. }
  2968. env->DeleteLocalRef(jlive_file_meta_data);
  2969. }
  2970. return jlive_files_meta_data;
  2971. }
  2972. /*
  2973. * Class: org_rocksdb_RocksDB
  2974. * Method: getColumnFamilyMetaData
  2975. * Signature: (JJ)Lorg/rocksdb/ColumnFamilyMetaData;
  2976. */
  2977. jobject Java_org_rocksdb_RocksDB_getColumnFamilyMetaData(JNIEnv* env, jclass,
  2978. jlong jdb_handle,
  2979. jlong jcf_handle) {
  2980. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  2981. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  2982. if (jcf_handle == 0) {
  2983. cf_handle = db->DefaultColumnFamily();
  2984. } else {
  2985. cf_handle =
  2986. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  2987. }
  2988. ROCKSDB_NAMESPACE::ColumnFamilyMetaData cf_metadata;
  2989. db->GetColumnFamilyMetaData(cf_handle, &cf_metadata);
  2990. return ROCKSDB_NAMESPACE::ColumnFamilyMetaDataJni::
  2991. fromCppColumnFamilyMetaData(env, &cf_metadata);
  2992. }
  2993. /*
  2994. * Class: org_rocksdb_RocksDB
  2995. * Method: ingestExternalFile
  2996. * Signature: (JJ[Ljava/lang/String;IJ)V
  2997. */
  2998. void Java_org_rocksdb_RocksDB_ingestExternalFile(
  2999. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  3000. jobjectArray jfile_path_list, jint jfile_path_list_len,
  3001. jlong jingest_external_file_options_handle) {
  3002. jboolean has_exception = JNI_FALSE;
  3003. std::vector<std::string> file_path_list =
  3004. ROCKSDB_NAMESPACE::JniUtil::copyStrings(
  3005. env, jfile_path_list, jfile_path_list_len, &has_exception);
  3006. if (has_exception == JNI_TRUE) {
  3007. // exception occurred
  3008. return;
  3009. }
  3010. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3011. auto* column_family =
  3012. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3013. auto* ifo = reinterpret_cast<ROCKSDB_NAMESPACE::IngestExternalFileOptions*>(
  3014. jingest_external_file_options_handle);
  3015. ROCKSDB_NAMESPACE::Status s =
  3016. db->IngestExternalFile(column_family, file_path_list, *ifo);
  3017. if (!s.ok()) {
  3018. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3019. }
  3020. }
  3021. /*
  3022. * Class: org_rocksdb_RocksDB
  3023. * Method: verifyChecksum
  3024. * Signature: (J)V
  3025. */
  3026. void Java_org_rocksdb_RocksDB_verifyChecksum(JNIEnv* env, jclass,
  3027. jlong jdb_handle) {
  3028. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3029. auto s = db->VerifyChecksum();
  3030. if (!s.ok()) {
  3031. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3032. }
  3033. }
  3034. /*
  3035. * Class: org_rocksdb_RocksDB
  3036. * Method: getDefaultColumnFamily
  3037. * Signature: (J)J
  3038. */
  3039. jlong Java_org_rocksdb_RocksDB_getDefaultColumnFamily(JNIEnv*, jclass,
  3040. jlong jdb_handle) {
  3041. auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3042. auto* cf_handle = db_handle->DefaultColumnFamily();
  3043. return GET_CPLUSPLUS_POINTER(cf_handle);
  3044. }
  3045. /*
  3046. * Class: org_rocksdb_RocksDB
  3047. * Method: getPropertiesOfAllTables
  3048. * Signature: (JJ)Ljava/util/Map;
  3049. */
  3050. jobject Java_org_rocksdb_RocksDB_getPropertiesOfAllTables(JNIEnv* env, jclass,
  3051. jlong jdb_handle,
  3052. jlong jcf_handle) {
  3053. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3054. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  3055. if (jcf_handle == 0) {
  3056. cf_handle = db->DefaultColumnFamily();
  3057. } else {
  3058. cf_handle =
  3059. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3060. }
  3061. ROCKSDB_NAMESPACE::TablePropertiesCollection table_properties_collection;
  3062. auto s =
  3063. db->GetPropertiesOfAllTables(cf_handle, &table_properties_collection);
  3064. if (!s.ok()) {
  3065. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3066. }
  3067. // convert to Java type
  3068. jobject jhash_map = ROCKSDB_NAMESPACE::HashMapJni::construct(
  3069. env, static_cast<uint32_t>(table_properties_collection.size()));
  3070. if (jhash_map == nullptr) {
  3071. // exception occurred
  3072. return nullptr;
  3073. }
  3074. const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<
  3075. const std::string,
  3076. const std::shared_ptr<const ROCKSDB_NAMESPACE::TableProperties>, jobject,
  3077. jobject>
  3078. fn_map_kv =
  3079. [env](const std::pair<const std::string,
  3080. const std::shared_ptr<
  3081. const ROCKSDB_NAMESPACE::TableProperties>>&
  3082. kv) {
  3083. jstring jkey = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
  3084. env, &(kv.first), false);
  3085. if (env->ExceptionCheck()) {
  3086. // an error occurred
  3087. return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
  3088. }
  3089. jobject jtable_properties =
  3090. ROCKSDB_NAMESPACE::TablePropertiesJni::fromCppTableProperties(
  3091. env, *(kv.second.get()));
  3092. if (jtable_properties == nullptr) {
  3093. // an error occurred
  3094. env->DeleteLocalRef(jkey);
  3095. return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
  3096. }
  3097. return std::unique_ptr<std::pair<jobject, jobject>>(
  3098. new std::pair<jobject, jobject>(
  3099. static_cast<jobject>(jkey),
  3100. static_cast<jobject>(jtable_properties)));
  3101. };
  3102. if (!ROCKSDB_NAMESPACE::HashMapJni::putAll(
  3103. env, jhash_map, table_properties_collection.begin(),
  3104. table_properties_collection.end(), fn_map_kv)) {
  3105. // exception occurred
  3106. return nullptr;
  3107. }
  3108. return jhash_map;
  3109. }
  3110. /*
  3111. * Class: org_rocksdb_RocksDB
  3112. * Method: getPropertiesOfTablesInRange
  3113. * Signature: (JJ[J)Ljava/util/Map;
  3114. */
  3115. jobject Java_org_rocksdb_RocksDB_getPropertiesOfTablesInRange(
  3116. JNIEnv* env, jclass, jlong jdb_handle, jlong jcf_handle,
  3117. jlongArray jrange_slice_handles) {
  3118. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3119. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  3120. if (jcf_handle == 0) {
  3121. cf_handle = db->DefaultColumnFamily();
  3122. } else {
  3123. cf_handle =
  3124. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3125. }
  3126. const jsize jlen = env->GetArrayLength(jrange_slice_handles);
  3127. jlong* jrange_slice_handle =
  3128. env->GetLongArrayElements(jrange_slice_handles, nullptr);
  3129. if (jrange_slice_handle == nullptr) {
  3130. // exception occurred
  3131. return nullptr;
  3132. }
  3133. const size_t ranges_len = static_cast<size_t>(jlen / 2);
  3134. auto ranges = std::unique_ptr<ROCKSDB_NAMESPACE::Range[]>(
  3135. new ROCKSDB_NAMESPACE::Range[ranges_len]);
  3136. for (jsize i = 0, j = 0; i < jlen; ++i) {
  3137. auto* start =
  3138. reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jrange_slice_handle[i]);
  3139. auto* limit =
  3140. reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jrange_slice_handle[++i]);
  3141. ranges[j++] = ROCKSDB_NAMESPACE::Range(*start, *limit);
  3142. }
  3143. ROCKSDB_NAMESPACE::TablePropertiesCollection table_properties_collection;
  3144. auto s = db->GetPropertiesOfTablesInRange(cf_handle, ranges.get(), ranges_len,
  3145. &table_properties_collection);
  3146. if (!s.ok()) {
  3147. // error occurred
  3148. env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle,
  3149. JNI_ABORT);
  3150. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3151. return nullptr;
  3152. }
  3153. // cleanup
  3154. env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle,
  3155. JNI_ABORT);
  3156. return jrange_slice_handles;
  3157. }
  3158. /*
  3159. * Class: org_rocksdb_RocksDB
  3160. * Method: suggestCompactRange
  3161. * Signature: (JJ)[J
  3162. */
  3163. jlongArray Java_org_rocksdb_RocksDB_suggestCompactRange(JNIEnv* env, jclass,
  3164. jlong jdb_handle,
  3165. jlong jcf_handle) {
  3166. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3167. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  3168. if (jcf_handle == 0) {
  3169. cf_handle = db->DefaultColumnFamily();
  3170. } else {
  3171. cf_handle =
  3172. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3173. }
  3174. auto* begin = new ROCKSDB_NAMESPACE::Slice();
  3175. auto* end = new ROCKSDB_NAMESPACE::Slice();
  3176. auto s = db->SuggestCompactRange(cf_handle, begin, end);
  3177. if (!s.ok()) {
  3178. // error occurred
  3179. delete begin;
  3180. delete end;
  3181. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3182. return nullptr;
  3183. }
  3184. jlongArray jslice_handles = env->NewLongArray(2);
  3185. if (jslice_handles == nullptr) {
  3186. // exception thrown: OutOfMemoryError
  3187. delete begin;
  3188. delete end;
  3189. return nullptr;
  3190. }
  3191. jlong slice_handles[2];
  3192. slice_handles[0] = GET_CPLUSPLUS_POINTER(begin);
  3193. slice_handles[1] = GET_CPLUSPLUS_POINTER(end);
  3194. env->SetLongArrayRegion(jslice_handles, 0, 2, slice_handles);
  3195. if (env->ExceptionCheck()) {
  3196. // exception thrown: ArrayIndexOutOfBoundsException
  3197. delete begin;
  3198. delete end;
  3199. env->DeleteLocalRef(jslice_handles);
  3200. return nullptr;
  3201. }
  3202. return jslice_handles;
  3203. }
  3204. /*
  3205. * Class: org_rocksdb_RocksDB
  3206. * Method: promoteL0
  3207. * Signature: (JJI)V
  3208. */
  3209. void Java_org_rocksdb_RocksDB_promoteL0(JNIEnv*, jclass, jlong jdb_handle,
  3210. jlong jcf_handle, jint jtarget_level) {
  3211. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3212. ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
  3213. if (jcf_handle == 0) {
  3214. cf_handle = db->DefaultColumnFamily();
  3215. } else {
  3216. cf_handle =
  3217. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3218. }
  3219. db->PromoteL0(cf_handle, static_cast<int>(jtarget_level));
  3220. }
  3221. /*
  3222. * Class: org_rocksdb_RocksDB
  3223. * Method: startTrace
  3224. * Signature: (JJJ)V
  3225. */
  3226. void Java_org_rocksdb_RocksDB_startTrace(
  3227. JNIEnv* env, jclass, jlong jdb_handle, jlong jmax_trace_file_size,
  3228. jlong jtrace_writer_jnicallback_handle) {
  3229. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3230. ROCKSDB_NAMESPACE::TraceOptions trace_options;
  3231. trace_options.max_trace_file_size =
  3232. static_cast<uint64_t>(jmax_trace_file_size);
  3233. // transfer ownership of trace writer from Java to C++
  3234. auto trace_writer =
  3235. std::unique_ptr<ROCKSDB_NAMESPACE::TraceWriterJniCallback>(
  3236. reinterpret_cast<ROCKSDB_NAMESPACE::TraceWriterJniCallback*>(
  3237. jtrace_writer_jnicallback_handle));
  3238. auto s = db->StartTrace(trace_options, std::move(trace_writer));
  3239. if (!s.ok()) {
  3240. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3241. }
  3242. }
  3243. /*
  3244. * Class: org_rocksdb_RocksDB
  3245. * Method: endTrace
  3246. * Signature: (J)V
  3247. */
  3248. void Java_org_rocksdb_RocksDB_endTrace(JNIEnv* env, jclass, jlong jdb_handle) {
  3249. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3250. auto s = db->EndTrace();
  3251. if (!s.ok()) {
  3252. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3253. }
  3254. }
  3255. /*
  3256. * Class: org_rocksdb_RocksDB
  3257. * Method: tryCatchUpWithPrimary
  3258. * Signature: (J)V
  3259. */
  3260. void Java_org_rocksdb_RocksDB_tryCatchUpWithPrimary(JNIEnv* env, jclass,
  3261. jlong jdb_handle) {
  3262. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3263. auto s = db->TryCatchUpWithPrimary();
  3264. if (!s.ok()) {
  3265. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3266. }
  3267. }
  3268. /*
  3269. * Class: org_rocksdb_RocksDB
  3270. * Method: destroyDB
  3271. * Signature: (Ljava/lang/String;J)V
  3272. */
  3273. void Java_org_rocksdb_RocksDB_destroyDB(JNIEnv* env, jclass, jstring jdb_path,
  3274. jlong joptions_handle) {
  3275. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  3276. if (db_path == nullptr) {
  3277. // exception thrown: OutOfMemoryError
  3278. return;
  3279. }
  3280. auto* options =
  3281. reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(joptions_handle);
  3282. if (options == nullptr) {
  3283. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  3284. env, ROCKSDB_NAMESPACE::Status::InvalidArgument("Invalid Options."));
  3285. }
  3286. ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DestroyDB(db_path, *options);
  3287. env->ReleaseStringUTFChars(jdb_path, db_path);
  3288. if (!s.ok()) {
  3289. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3290. }
  3291. }
  3292. bool get_slice_helper(JNIEnv* env, jobjectArray ranges, jsize index,
  3293. ROCKSDB_NAMESPACE::OptSlice& opt_slice,
  3294. std::vector<std::unique_ptr<jbyte[]>>& ranges_to_free) {
  3295. jobject jArray = env->GetObjectArrayElement(ranges, index);
  3296. if (env->ExceptionCheck()) {
  3297. // exception thrown: ArrayIndexOutOfBoundsException
  3298. return false;
  3299. }
  3300. if (jArray == nullptr) {
  3301. return true;
  3302. }
  3303. jbyteArray jba = reinterpret_cast<jbyteArray>(jArray);
  3304. jsize len_ba = env->GetArrayLength(jba);
  3305. ranges_to_free.push_back(std::unique_ptr<jbyte[]>(new jbyte[len_ba]));
  3306. env->GetByteArrayRegion(jba, 0, len_ba, ranges_to_free.back().get());
  3307. if (env->ExceptionCheck()) {
  3308. // exception thrown: ArrayIndexOutOfBoundsException
  3309. env->DeleteLocalRef(jArray);
  3310. return false;
  3311. }
  3312. env->DeleteLocalRef(jArray);
  3313. opt_slice = ROCKSDB_NAMESPACE::Slice(
  3314. reinterpret_cast<char*>(ranges_to_free.back().get()), len_ba);
  3315. return true;
  3316. }
  3317. /*
  3318. * Class: org_rocksdb_RocksDB
  3319. * Method: deleteFilesInRanges
  3320. * Signature: (JJLjava/util/List;Z)V
  3321. */
  3322. void Java_org_rocksdb_RocksDB_deleteFilesInRanges(JNIEnv* env, jclass /*jdb*/,
  3323. jlong jdb_handle,
  3324. jlong jcf_handle,
  3325. jobjectArray ranges,
  3326. jboolean include_end) {
  3327. jsize length = env->GetArrayLength(ranges);
  3328. std::vector<ROCKSDB_NAMESPACE::RangeOpt> rangesVector;
  3329. std::vector<ROCKSDB_NAMESPACE::OptSlice> slices;
  3330. std::vector<std::unique_ptr<jbyte[]>> ranges_to_free;
  3331. for (jsize i = 0; (i + 1) < length; i += 2) {
  3332. slices.emplace_back();
  3333. if (!get_slice_helper(env, ranges, i, slices.back(), ranges_to_free)) {
  3334. // exception thrown
  3335. return;
  3336. }
  3337. slices.emplace_back();
  3338. if (!get_slice_helper(env, ranges, i + 1, slices.back(), ranges_to_free)) {
  3339. // exception thrown
  3340. return;
  3341. }
  3342. rangesVector.push_back(ROCKSDB_NAMESPACE::RangeOpt(
  3343. slices[slices.size() - 2], slices[slices.size() - 1]));
  3344. }
  3345. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
  3346. auto* column_family =
  3347. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
  3348. ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DeleteFilesInRanges(
  3349. db, column_family == nullptr ? db->DefaultColumnFamily() : column_family,
  3350. rangesVector.data(), rangesVector.size(), include_end);
  3351. if (!s.ok()) {
  3352. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  3353. }
  3354. }
  3355. /*
  3356. * Class: org_rocksdb_RocksDB
  3357. * Method: version
  3358. * Signature: ()I
  3359. */
  3360. jint Java_org_rocksdb_RocksDB_version(JNIEnv*, jclass) {
  3361. uint32_t encodedVersion = (ROCKSDB_MAJOR & 0xff) << 16;
  3362. encodedVersion |= (ROCKSDB_MINOR & 0xff) << 8;
  3363. encodedVersion |= (ROCKSDB_PATCH & 0xff);
  3364. return static_cast<jint>(encodedVersion);
  3365. }