Skip to content

Commit ccfe061

Browse files
committed
Cache modules and functions
1 parent d1e37ad commit ccfe061

1 file changed

Lines changed: 53 additions & 58 deletions

File tree

singlestoredb/mysql/accel.c

Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ typedef struct {
344344
PyObject *Decimal;
345345
PyObject *date;
346346
PyObject *timedelta;
347+
PyObject *time;
347348
PyObject *datetime;
348349
PyObject *loads;
349350
PyObject *field_count;
@@ -361,10 +362,26 @@ typedef struct {
361362
PyObject *x_errno;
362363
PyObject *_result;
363364
PyObject *_read_timeout;
365+
PyObject *_next_seq_id;
366+
PyObject *rows;
364367
} PyStrings;
365368

366369
static PyStrings PyStr = {0};
367370

371+
//
372+
// Cached Python functions
373+
//
374+
typedef struct {
375+
PyObject *json_loads;
376+
PyObject *decimal_Decimal;
377+
PyObject *datetime_date;
378+
PyObject *datetime_time;
379+
PyObject *datetime_timedelta;
380+
PyObject *datetime_datetime;
381+
} PyFunctions;
382+
383+
static PyFunctions PyFunc = {0};
384+
368385
//
369386
// State
370387
//
@@ -375,14 +392,6 @@ typedef struct {
375392
PyObject_HEAD
376393
PyObject *py_conn; // Database connection
377394
PyObject *py_fields; // List of table fields
378-
PyObject *py_decimal_mod; // decimal module
379-
PyObject *py_decimal; // decimal.Decimal
380-
PyObject *py_json_mod; // json module
381-
PyObject *py_json_loads; // json.loads
382-
PyObject *py_datetime_mod; // datetime module
383-
PyObject *py_date; // datetime.date
384-
PyObject *py_timedelta; // datetime.timedelta
385-
PyObject *py_datetime; // datetime.datetime
386395
PyObject *py_rows; // Output object
387396
PyObject *py_rfile; // Socket file I/O
388397
PyObject *py_read; // File I/O read method
@@ -458,19 +467,8 @@ static void State_clear_fields(StateObject *self) {
458467
Py_CLEAR(self->py_read);
459468
Py_CLEAR(self->py_rfile);
460469
Py_CLEAR(self->py_rows);
461-
Py_CLEAR(self->py_json_loads);
462-
Py_CLEAR(self->py_json_mod);
463-
Py_CLEAR(self->py_decimal);
464-
Py_CLEAR(self->py_decimal_mod);
465-
Py_CLEAR(self->py_date);
466-
Py_CLEAR(self->py_timedelta);
467-
Py_CLEAR(self->py_datetime);
468-
Py_CLEAR(self->py_datetime_mod);
469470
Py_CLEAR(self->py_fields);
470471
Py_CLEAR(self->py_conn);
471-
472-
Py_CLEAR(self->py_str._next_seq_id);
473-
Py_CLEAR(self->py_str.rows);
474472
}
475473

476474
static void State_dealloc(StateObject *self) {
@@ -516,34 +514,6 @@ static int State_init(StateObject *self, PyObject *args, PyObject *kwds) {
516514
Py_XDECREF(unbuffered_active);
517515
}
518516

519-
// Create reused strings.
520-
self->py_str._next_seq_id = PyUnicode_FromString("_next_seq_id");
521-
if (!self->py_str._next_seq_id) goto error;
522-
self->py_str.rows = PyUnicode_FromString("rows");
523-
if (!self->py_str.rows) goto error;
524-
525-
// Import decimal module.
526-
self->py_decimal_mod = PyImport_ImportModule("decimal");
527-
if (!self->py_decimal_mod) goto error;
528-
self->py_decimal = PyObject_GetAttr(self->py_decimal_mod, PyStr.Decimal);
529-
if (!self->py_decimal) goto error;
530-
531-
// Import datetime objects
532-
self->py_datetime_mod = PyImport_ImportModule("datetime");
533-
if (!self->py_datetime_mod) goto error;
534-
self->py_date = PyObject_GetAttr(self->py_datetime_mod, PyStr.date);
535-
if (!self->py_date) goto error;
536-
self->py_timedelta = PyObject_GetAttr(self->py_datetime_mod, PyStr.timedelta);
537-
if (!self->py_timedelta) goto error;
538-
self->py_datetime = PyObject_GetAttr(self->py_datetime_mod, PyStr.datetime);
539-
if (!self->py_datetime) goto error;
540-
541-
// Import json module.
542-
self->py_json_mod = PyImport_ImportModule("json");
543-
if (!self->py_json_mod) goto error;
544-
self->py_json_loads = PyObject_GetAttr(self->py_json_mod, PyStr.loads);
545-
if (!self->py_json_loads) goto error;
546-
547517
// Retrieve type codes for each column.
548518
PyObject *py_field_count = PyObject_GetAttr(py_res, PyStr.field_count);
549519
if (!py_field_count) goto error;
@@ -667,7 +637,7 @@ static int State_init(StateObject *self, PyObject *args, PyObject *kwds) {
667637
self->py_read = PyObject_GetAttr(self->py_rfile, PyStr.read);
668638
if (!self->py_read) goto error;
669639

670-
PyObject *py_next_seq_id = PyObject_GetAttr(self->py_conn, self->py_str._next_seq_id);
640+
PyObject *py_next_seq_id = PyObject_GetAttr(self->py_conn, PyStr._next_seq_id);
671641
if (!py_next_seq_id) goto error;
672642
self->next_seq_id = PyLong_AsUnsignedLongLong(py_next_seq_id);
673643
Py_XDECREF(py_next_seq_id);
@@ -702,7 +672,7 @@ static int State_init(StateObject *self, PyObject *args, PyObject *kwds) {
702672
//}
703673
if (!self->py_rows) goto error;
704674

705-
PyObject_SetAttr(py_res, self->py_str.rows, self->py_rows);
675+
PyObject_SetAttr(py_res, PyStr.rows, self->py_rows);
706676
}
707677

708678
exit:
@@ -734,7 +704,7 @@ static int State_reset_batch(
734704
self->py_rows = PyList_New(0);
735705
Py_XDECREF(py_tmp);
736706
if (!self->py_rows) { rc = -1; goto error; }
737-
rc = PyObject_SetAttr(py_res, self->py_str.rows, self->py_rows);
707+
rc = PyObject_SetAttr(py_res, PyStr.rows, self->py_rows);
738708
//}
739709

740710
exit:
@@ -1133,7 +1103,7 @@ static PyObject *PyDate_FromDate(
11331103
}
11341104

11351105
out = PyObject_CallFunctionObjArgs(
1136-
py_state->py_date, py_year, PyInts[month], PyInts[day], NULL
1106+
PyFunc.datetime_date, py_year, PyInts[month], PyInts[day], NULL
11371107
);
11381108

11391109
if (free_year) Py_XDECREF(py_year);
@@ -1177,7 +1147,7 @@ static PyObject *PyDelta_FromDSU(
11771147
}
11781148

11791149
out = PyObject_CallFunctionObjArgs(
1180-
py_state->py_timedelta, py_days, py_seconds, py_microseconds, NULL
1150+
PyFunc.datetime_timedelta, py_days, py_seconds, py_microseconds, NULL
11811151
);
11821152

11831153
if (free_days) Py_XDECREF(py_days);
@@ -1218,7 +1188,7 @@ static PyObject *PyDateTime_FromDateAndTime(
12181188
}
12191189

12201190
out = PyObject_CallFunctionObjArgs(
1221-
py_state->py_datetime, py_year, PyInts[month], PyInts[day],
1191+
PyFunc.datetime_datetime, py_year, PyInts[month], PyInts[day],
12221192
PyInts[hour], PyInts[minute], PyInts[second], py_microsecond, NULL
12231193
);
12241194

@@ -1303,7 +1273,7 @@ static PyObject *read_row_from_packet(
13031273
py_str = PyUnicode_Decode(out, out_l, py_state->encodings[i], "strict");
13041274
if (!py_str) goto error;
13051275

1306-
py_item = PyObject_CallFunctionObjArgs(py_state->py_decimal, py_str, NULL);
1276+
py_item = PyObject_CallFunctionObjArgs(PyFunc.decimal_Decimal, py_str, NULL);
13071277
Py_CLEAR(py_str);
13081278
if (!py_item) goto error;
13091279
break;
@@ -1485,7 +1455,7 @@ static PyObject *read_row_from_packet(
14851455
// Parse JSON string.
14861456
if (py_state->type_codes[i] == MYSQL_TYPE_JSON && py_state->options.parse_json) {
14871457
py_str = py_item;
1488-
py_item = PyObject_CallFunctionObjArgs(py_state->py_json_loads, py_str, NULL);
1458+
py_item = PyObject_CallFunctionObjArgs(PyFunc.json_loads, py_str, NULL);
14891459
Py_CLEAR(py_str);
14901460
if (!py_item) goto error;
14911461
}
@@ -1642,7 +1612,7 @@ static PyObject *read_rowdata_packet(PyObject *self, PyObject *args, PyObject *k
16421612

16431613
py_next_seq_id = PyLong_FromUnsignedLongLong(py_state->next_seq_id);
16441614
if (!py_next_seq_id) goto error;
1645-
PyObject_SetAttr(py_state->py_conn, py_state->py_str._next_seq_id, py_next_seq_id);
1615+
PyObject_SetAttr(py_state->py_conn, PyStr._next_seq_id, py_next_seq_id);
16461616
Py_DECREF(py_next_seq_id);
16471617

16481618
py_out = NULL;
@@ -1651,7 +1621,7 @@ static PyObject *read_rowdata_packet(PyObject *self, PyObject *args, PyObject *k
16511621
if (py_state->is_eof && row_idx == 0) {
16521622
Py_INCREF(Py_None);
16531623
py_out = Py_None;
1654-
PyObject_SetAttr(py_res, py_state->py_str.rows, Py_None);
1624+
PyObject_SetAttr(py_res, PyStr.rows, Py_None);
16551625
PyObject *py_n_rows = PyLong_FromSsize_t(py_state->n_rows);
16561626
PyObject_SetAttr(py_res, PyStr.affected_rows, (py_n_rows) ? py_n_rows : Py_None);
16571627
Py_XDECREF(py_n_rows);
@@ -1721,6 +1691,7 @@ PyMODINIT_FUNC PyInit__singlestoredb_accel(void) {
17211691
PyStr.options = PyUnicode_FromString("options");
17221692
PyStr.Decimal = PyUnicode_FromString("Decimal");
17231693
PyStr.date = PyUnicode_FromString("date");
1694+
PyStr.time = PyUnicode_FromString("time");
17241695
PyStr.timedelta = PyUnicode_FromString("timedelta");
17251696
PyStr.datetime = PyUnicode_FromString("datetime");
17261697
PyStr.loads = PyUnicode_FromString("loads");
@@ -1739,7 +1710,31 @@ PyMODINIT_FUNC PyInit__singlestoredb_accel(void) {
17391710
PyStr.read = PyUnicode_FromString("read");
17401711
PyStr.x_errno = PyUnicode_FromString("errno");
17411712
PyStr._result = PyUnicode_FromString("_result");
1742-
1713+
PyStr._next_seq_id = PyUnicode_FromString("_next_seq_id");
1714+
PyStr.rows = PyUnicode_FromString("rows");
1715+
1716+
PyObject *decimal_mod = PyImport_ImportModule("decimal");
1717+
if (!decimal_mod) goto error;
1718+
PyObject *datetime_mod = PyImport_ImportModule("datetime");
1719+
if (!datetime_mod) goto error;
1720+
PyObject *json_mod = PyImport_ImportModule("json");
1721+
if (!json_mod) goto error;
1722+
1723+
PyFunc.decimal_Decimal = PyObject_GetAttr(decimal_mod, PyStr.Decimal);
1724+
if (!PyFunc.decimal_Decimal) goto error;
1725+
PyFunc.datetime_date = PyObject_GetAttr(datetime_mod, PyStr.date);
1726+
if (!PyFunc.datetime_date) goto error;
1727+
PyFunc.datetime_timedelta = PyObject_GetAttr(datetime_mod, PyStr.timedelta);
1728+
if (!PyFunc.datetime_timedelta) goto error;
1729+
PyFunc.datetime_time = PyObject_GetAttr(datetime_mod, PyStr.time);
1730+
if (!PyFunc.datetime_time) goto error;
1731+
PyFunc.datetime_datetime = PyObject_GetAttr(datetime_mod, PyStr.datetime);
1732+
if (!PyFunc.datetime_datetime) goto error;
1733+
PyFunc.json_loads = PyObject_GetAttr(json_mod, PyStr.loads);
1734+
if (!PyFunc.json_loads) goto error;
17431735

17441736
return PyModule_Create(&_singlestoredb_accelmodule);
1737+
1738+
error:
1739+
return NULL;
17451740
}

0 commit comments

Comments
 (0)