@@ -86,6 +86,8 @@ class JVM {
86
86
return instance_;
87
87
}
88
88
89
+ static void destroyInstance () { instance_ = nullptr ; }
90
+
89
91
// Get JNI environment for the current thread.
90
92
// You souldn't pass this obect between threads. It should be deallocated
91
93
// in the same thread it was requrested in. It shouldn't outlive JVM object.
@@ -167,13 +169,9 @@ std::shared_ptr<JVM> JVM::instance_;
167
169
168
170
} // namespace
169
171
170
- class CalciteJNI ::Impl {
172
+ class CalciteJNI {
171
173
public:
172
- Impl (SchemaProviderPtr schema_provider,
173
- ConfigPtr config,
174
- const std::string& udf_filename,
175
- size_t calcite_max_mem_mb)
176
- : schema_provider_(schema_provider), config_(config) {
174
+ CalciteJNI (const std::string& udf_filename, size_t calcite_max_mem_mb) {
177
175
// Initialize JVM.
178
176
jvm_ = JVM::getInstance (calcite_max_mem_mb);
179
177
auto env = jvm_->getEnv ();
@@ -192,15 +190,19 @@ class CalciteJNI::Impl {
192
190
findHashMap (env.get ());
193
191
}
194
192
195
- ~Impl () {
193
+ ~CalciteJNI () {
196
194
auto env = jvm_->getEnv ();
197
195
for (auto obj : global_refs_) {
198
196
env->DeleteGlobalRef (obj);
199
197
}
198
+
199
+ JVM::destroyInstance ();
200
200
}
201
201
202
202
std::string process (const std::string& db_name,
203
203
const std::string& sql_string,
204
+ SchemaProviderPtr schema_provider,
205
+ ConfigPtr config,
204
206
const std::vector<FilterPushDownInfo>& filter_push_down_info,
205
207
const bool legacy_syntax,
206
208
const bool is_explain,
@@ -226,10 +228,10 @@ class CalciteJNI::Impl {
226
228
env->NewObject (optimization_opts_cls_,
227
229
optimization_opts_ctor_,
228
230
(jboolean)is_view_optimize,
229
- (jboolean)config_ ->exec .watchdog .enable ,
231
+ (jboolean)config ->exec .watchdog .enable ,
230
232
arg_filter_push_down_info);
231
233
jobject arg_restriction = nullptr ;
232
- auto schema_json = schema_to_json (schema_provider_ );
234
+ auto schema_json = schema_to_json (schema_provider );
233
235
jstring arg_schema = env->NewStringUTF (schema_json.c_str ());
234
236
235
237
jobject java_res = env->CallObjectMethod (handler_obj_,
@@ -516,9 +518,6 @@ class CalciteJNI::Impl {
516
518
extension_fn_cls_, extension_fn_udf_ctor_, name_arg, args_arg, ret_arg);
517
519
}
518
520
519
- SchemaProviderPtr schema_provider_;
520
- ConfigPtr config_;
521
-
522
521
// com.mapd.parser.server.CalciteServerHandler instance and methods.
523
522
jobject handler_obj_;
524
523
jmethodID handler_process_;
@@ -564,41 +563,137 @@ class CalciteJNI::Impl {
564
563
std::shared_ptr<JVM> jvm_;
565
564
};
566
565
567
- CalciteJNI::CalciteJNI (SchemaProviderPtr schema_provider,
568
- ConfigPtr config,
569
- const std::string& udf_filename,
570
- size_t calcite_max_mem_mb) {
571
- impl_ =
572
- std::make_unique<Impl>(schema_provider, config, udf_filename, calcite_max_mem_mb);
566
+ CalciteMgr::~CalciteMgr () {
567
+ {
568
+ std::lock_guard<decltype (queue_mutex_)> lock (queue_mutex_);
569
+ should_exit_ = true ;
570
+ }
571
+ worker_cv_.notify_all ();
572
+ worker_.join ();
573
573
}
574
574
575
- CalciteJNI::~CalciteJNI () {}
576
-
577
- std::string CalciteJNI::process (
575
+ std::string CalciteMgr::process (
578
576
const std::string& db_name,
579
577
const std::string& sql_string,
578
+ SchemaProviderPtr schema_provider,
579
+ ConfigPtr config,
580
580
const std::vector<FilterPushDownInfo>& filter_push_down_info,
581
581
const bool legacy_syntax,
582
582
const bool is_explain,
583
583
const bool is_view_optimize) {
584
- return impl_->process (db_name,
585
- sql_string,
586
- filter_push_down_info,
587
- legacy_syntax,
588
- is_explain,
589
- is_view_optimize);
584
+ auto task = Task ([&db_name,
585
+ &sql_string,
586
+ &filter_push_down_info,
587
+ schema_provider,
588
+ config,
589
+ legacy_syntax,
590
+ is_explain,
591
+ is_view_optimize](CalciteJNI* calcite_jni) {
592
+ CHECK (calcite_jni);
593
+ return calcite_jni->process (db_name,
594
+ sql_string,
595
+ schema_provider,
596
+ config,
597
+ filter_push_down_info,
598
+ legacy_syntax,
599
+ is_explain,
600
+ is_view_optimize);
601
+ });
602
+ auto result = task.get_future ();
603
+ submitTaskToQueue (std::move (task));
604
+
605
+ result.wait ();
606
+ return result.get ();
590
607
}
591
608
592
- std::string CalciteJNI::getExtensionFunctionWhitelist () {
593
- return impl_->getExtensionFunctionWhitelist ();
609
+ std::string CalciteMgr::getExtensionFunctionWhitelist () {
610
+ auto task = Task ([](CalciteJNI* calcite_jni) {
611
+ CHECK (calcite_jni);
612
+ return calcite_jni->getExtensionFunctionWhitelist ();
613
+ });
614
+
615
+ auto result = task.get_future ();
616
+ submitTaskToQueue (std::move (task));
617
+
618
+ result.wait ();
619
+ return result.get ();
594
620
}
595
- std::string CalciteJNI::getUserDefinedFunctionWhitelist () {
596
- return impl_->getUserDefinedFunctionWhitelist ();
621
+
622
+ std::string CalciteMgr::getUserDefinedFunctionWhitelist () {
623
+ auto task = Task ([](CalciteJNI* calcite_jni) {
624
+ CHECK (calcite_jni);
625
+ return calcite_jni->getUserDefinedFunctionWhitelist ();
626
+ });
627
+
628
+ auto result = task.get_future ();
629
+ submitTaskToQueue (std::move (task));
630
+
631
+ result.wait ();
632
+ return result.get ();
597
633
}
598
- std::string CalciteJNI::getRuntimeExtensionFunctionWhitelist () {
599
- return impl_->getRuntimeExtensionFunctionWhitelist ();
634
+
635
+ std::string CalciteMgr::getRuntimeExtensionFunctionWhitelist () {
636
+ auto task = Task ([](CalciteJNI* calcite_jni) {
637
+ CHECK (calcite_jni);
638
+ return calcite_jni->getRuntimeExtensionFunctionWhitelist ();
639
+ });
640
+
641
+ auto result = task.get_future ();
642
+ submitTaskToQueue (std::move (task));
643
+
644
+ result.wait ();
645
+ return result.get ();
600
646
}
601
- void CalciteJNI::setRuntimeExtensionFunctions (const std::vector<ExtensionFunction>& udfs,
647
+
648
+ void CalciteMgr::setRuntimeExtensionFunctions (const std::vector<ExtensionFunction>& udfs,
602
649
bool is_runtime) {
603
- return impl_->setRuntimeExtensionFunctions (udfs, is_runtime);
650
+ auto task = Task ([&udfs, is_runtime](CalciteJNI* calcite_jni) {
651
+ CHECK (calcite_jni);
652
+ calcite_jni->setRuntimeExtensionFunctions (udfs, is_runtime);
653
+ return " " ; // all tasks return strings
654
+ });
655
+
656
+ auto result = task.get_future ();
657
+ submitTaskToQueue (std::move (task));
658
+
659
+ result.wait ();
604
660
}
661
+
662
+ CalciteMgr::CalciteMgr (const std::string& udf_filename, size_t calcite_max_mem_mb) {
663
+ // todo: should register an exit handler for ctrl + c
664
+ worker_ = std::thread (&CalciteMgr::worker, this , udf_filename, calcite_max_mem_mb);
665
+ }
666
+
667
+ void CalciteMgr::worker (const std::string& udf_filename, size_t calcite_max_mem_mb) {
668
+ auto calcite_jni = std::make_unique<CalciteJNI>(udf_filename, calcite_max_mem_mb);
669
+
670
+ std::unique_lock<std::mutex> lock (queue_mutex_);
671
+ while (true ) {
672
+ worker_cv_.wait (lock, [this ] { return !queue_.empty () || should_exit_; });
673
+ if (should_exit_) {
674
+ return ;
675
+ }
676
+
677
+ if (!queue_.empty ()) {
678
+ auto task = std::move (queue_.front ());
679
+ queue_.pop ();
680
+
681
+ lock.unlock ();
682
+ task (calcite_jni.get ());
683
+
684
+ lock.lock ();
685
+ }
686
+ }
687
+ }
688
+
689
+ void CalciteMgr::submitTaskToQueue (Task&& task) {
690
+ std::unique_lock<decltype (queue_mutex_)> lock (queue_mutex_);
691
+
692
+ queue_.push (std::move (task));
693
+
694
+ lock.unlock ();
695
+ worker_cv_.notify_all ();
696
+ }
697
+
698
+ std::once_flag CalciteMgr::instance_init_flag_;
699
+ std::unique_ptr<CalciteMgr> CalciteMgr::instance_;
0 commit comments