@@ -758,17 +758,17 @@ long DSDGenWrapper::get_row_count(TableType t) const {
758758
759759// C-linkage trampolines for master-detail tables
760760namespace {
761- struct StoreSalesCtx {
761+ template <typename Row>
762+ struct CallbackState {
762763 std::function<void (const void *)>* cb;
763764 long max_rows;
764765 long emitted;
765766 std::exception_ptr error;
766767};
767768
768- extern " C" void store_sales_trampoline (
769- const struct W_STORE_SALES_TBL * row, void * ctx)
770- {
771- auto * c = static_cast <StoreSalesCtx*>(ctx);
769+ template <typename Row>
770+ static void callback_trampoline_impl (const Row* row, void * ctx) {
771+ auto * c = static_cast <CallbackState<Row>*>(ctx);
772772 if (c->error != nullptr || (c->max_rows > 0 && c->emitted >= c->max_rows )) {
773773 return ;
774774 }
@@ -780,48 +780,22 @@ extern "C" void store_sales_trampoline(
780780 }
781781}
782782
783- struct CatalogSalesCtx {
784- std::function<void (const void *)>* cb;
785- long max_rows;
786- long emitted;
787- std::exception_ptr error;
788- };
783+ extern " C" void store_sales_trampoline (
784+ const struct W_STORE_SALES_TBL * row, void * ctx)
785+ {
786+ callback_trampoline_impl (row, ctx);
787+ }
789788
790789extern " C" void catalog_sales_trampoline (
791790 const struct W_CATALOG_SALES_TBL * row, void * ctx)
792791{
793- auto * c = static_cast <CatalogSalesCtx*>(ctx);
794- if (c->error != nullptr || (c->max_rows > 0 && c->emitted >= c->max_rows )) {
795- return ;
796- }
797- try {
798- (*c->cb )(static_cast <const void *>(row));
799- ++c->emitted ;
800- } catch (...) {
801- c->error = std::current_exception ();
802- }
792+ callback_trampoline_impl (row, ctx);
803793}
804794
805- struct WebSalesCtx {
806- std::function<void (const void *)>* cb;
807- long max_rows;
808- long emitted;
809- std::exception_ptr error;
810- };
811-
812795extern " C" void web_sales_trampoline (
813796 const struct W_WEB_SALES_TBL * row, void * ctx)
814797{
815- auto * c = static_cast <WebSalesCtx*>(ctx);
816- if (c->error != nullptr || (c->max_rows > 0 && c->emitted >= c->max_rows )) {
817- return ;
818- }
819- try {
820- (*c->cb )(static_cast <const void *>(row));
821- ++c->emitted ;
822- } catch (...) {
823- c->error = std::current_exception ();
824- }
798+ callback_trampoline_impl (row, ctx);
825799}
826800
827801template <typename Row>
@@ -834,43 +808,67 @@ struct CallbackGuard {
834808 *ctx_slot = nullptr ;
835809 }
836810};
837- } // anonymous namespace
838811
839- void DSDGenWrapper::generate_store_sales (
812+ template <typename Row>
813+ using MasterDetailCallbackSlot = void (*)(const Row*, void *);
814+
815+ template <typename Row>
816+ static void run_master_detail_generation (
840817 std::function<void (const void * row)> callback,
841- long max_rows)
818+ long max_rows,
819+ ds_key_t n_tickets,
820+ const char* table_name,
821+ bool verbose,
822+ MasterDetailCallbackSlot<Row>* callback_slot,
823+ void** callback_ctx_slot,
824+ MasterDetailCallbackSlot<Row> trampoline,
825+ int (*mk_row)(void *, ds_key_t ))
842826{
843- init_dsdgen ();
827+ CallbackState<Row> ctx{&callback, max_rows, 0L , nullptr };
828+ *callback_slot = trampoline;
829+ *callback_ctx_slot = &ctx;
830+ CallbackGuard<Row> guard{callback_slot, callback_ctx_slot};
844831
845- ds_key_t n_tickets = get_rowcount (TPCDS_STORE_SALES);
846-
847- if (verbose_) {
832+ if (verbose) {
848833 std::fprintf (stderr,
849- " DSDGenWrapper: generating store_sales from %lld tickets\n " ,
834+ " DSDGenWrapper: generating %s from %lld tickets\n " ,
835+ table_name,
850836 static_cast <long long >(n_tickets));
851837 }
852838
853- StoreSalesCtx ctx{&callback, max_rows, 0L , nullptr };
854- g_w_store_sales_callback = store_sales_trampoline;
855- g_w_store_sales_callback_ctx = &ctx;
856- CallbackGuard<W_STORE_SALES_TBL> guard{
857- &g_w_store_sales_callback,
858- &g_w_store_sales_callback_ctx,
859- };
860-
861839 for (ds_key_t i = 1 ; i <= n_tickets; ++i) {
862- if (ctx.error != nullptr || (max_rows > 0 && ctx.emitted >= max_rows)) break ;
863- mk_w_store_sales (nullptr , i);
840+ if (ctx.error != nullptr || (max_rows > 0 && ctx.emitted >= max_rows)) {
841+ break ;
842+ }
843+ mk_row (nullptr , i);
864844 }
865845 if (ctx.error != nullptr ) {
866846 std::rethrow_exception (ctx.error );
867847 }
868848
869- if (verbose_ ) {
849+ if (verbose ) {
870850 std::fprintf (stderr,
871- " DSDGenWrapper: emitted %ld store_sales rows\n " , ctx.emitted );
851+ " DSDGenWrapper: emitted %ld %s rows\n " , ctx.emitted , table_name );
872852 }
873853}
854+ } // anonymous namespace
855+
856+ void DSDGenWrapper::generate_store_sales (
857+ std::function<void (const void * row)> callback,
858+ long max_rows)
859+ {
860+ init_dsdgen ();
861+ run_master_detail_generation<W_STORE_SALES_TBL>(
862+ std::move (callback),
863+ max_rows,
864+ get_rowcount (TPCDS_STORE_SALES),
865+ " store_sales" ,
866+ verbose_,
867+ &g_w_store_sales_callback,
868+ &g_w_store_sales_callback_ctx,
869+ store_sales_trampoline,
870+ mk_w_store_sales);
871+ }
874872
875873// ---------------------------------------------------------------------------
876874// generate_inventory
@@ -909,35 +907,16 @@ void DSDGenWrapper::generate_catalog_sales(
909907 long max_rows)
910908{
911909 init_dsdgen ();
912-
913- ds_key_t n_tickets = get_rowcount (TPCDS_CATALOG_SALES);
914-
915- if (verbose_) {
916- std::fprintf (stderr,
917- " DSDGenWrapper: generating catalog_sales from %lld tickets\n " ,
918- static_cast <long long >(n_tickets));
919- }
920-
921- CatalogSalesCtx ctx{&callback, max_rows, 0L , nullptr };
922- g_w_catalog_sales_callback = catalog_sales_trampoline;
923- g_w_catalog_sales_callback_ctx = &ctx;
924- CallbackGuard<W_CATALOG_SALES_TBL> guard{
910+ run_master_detail_generation<W_CATALOG_SALES_TBL>(
911+ std::move (callback),
912+ max_rows,
913+ get_rowcount (TPCDS_CATALOG_SALES),
914+ " catalog_sales" ,
915+ verbose_,
925916 &g_w_catalog_sales_callback,
926917 &g_w_catalog_sales_callback_ctx,
927- };
928-
929- for (ds_key_t i = 1 ; i <= n_tickets; ++i) {
930- if (ctx.error != nullptr || (max_rows > 0 && ctx.emitted >= max_rows)) break ;
931- mk_w_catalog_sales (nullptr , i);
932- }
933- if (ctx.error != nullptr ) {
934- std::rethrow_exception (ctx.error );
935- }
936-
937- if (verbose_) {
938- std::fprintf (stderr,
939- " DSDGenWrapper: emitted %ld catalog_sales rows\n " , ctx.emitted );
940- }
918+ catalog_sales_trampoline,
919+ mk_w_catalog_sales);
941920}
942921
943922// ---------------------------------------------------------------------------
@@ -949,35 +928,16 @@ void DSDGenWrapper::generate_web_sales(
949928 long max_rows)
950929{
951930 init_dsdgen ();
952-
953- ds_key_t n_tickets = get_rowcount (TPCDS_WEB_SALES);
954-
955- if (verbose_) {
956- std::fprintf (stderr,
957- " DSDGenWrapper: generating web_sales from %lld tickets\n " ,
958- static_cast <long long >(n_tickets));
959- }
960-
961- WebSalesCtx ctx{&callback, max_rows, 0L , nullptr };
962- g_w_web_sales_callback = web_sales_trampoline;
963- g_w_web_sales_callback_ctx = &ctx;
964- CallbackGuard<W_WEB_SALES_TBL> guard{
931+ run_master_detail_generation<W_WEB_SALES_TBL>(
932+ std::move (callback),
933+ max_rows,
934+ get_rowcount (TPCDS_WEB_SALES),
935+ " web_sales" ,
936+ verbose_,
965937 &g_w_web_sales_callback,
966938 &g_w_web_sales_callback_ctx,
967- };
968-
969- for (ds_key_t i = 1 ; i <= n_tickets; ++i) {
970- if (ctx.error != nullptr || (max_rows > 0 && ctx.emitted >= max_rows)) break ;
971- mk_w_web_sales (nullptr , i);
972- }
973- if (ctx.error != nullptr ) {
974- std::rethrow_exception (ctx.error );
975- }
976-
977- if (verbose_) {
978- std::fprintf (stderr,
979- " DSDGenWrapper: emitted %ld web_sales rows\n " , ctx.emitted );
980- }
939+ web_sales_trampoline,
940+ mk_w_web_sales);
981941}
982942
983943// ---------------------------------------------------------------------------
0 commit comments