Skip to content

Commit d100e5e

Browse files
committed
ocesql.c: use pool of sql variables instead of recreating each time
This drops the amount memory allocation/free to the maximum amount of binding variables used. A run of 8 seconds doing 5000 DB operations previously had 1,945,796 allocations via new_sql_var() and is now down to 426, reducing instructions and cycles executed in the test case by 20% as well.
1 parent ce04b89 commit d100e5e

File tree

1 file changed

+45
-16
lines changed

1 file changed

+45
-16
lines changed

dblib/ocesql.c

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (C) 2015, 2022 Tokyo System House Co.,Ltd.
33
* Copyright (C) 2022-2024 Simon Sobisch
44
*
@@ -71,13 +71,13 @@ static SQLVARLIST *_sql_var_lists = NULL;
7171
static SQLVARLIST *_sql_var_lists_last = NULL;
7272
static SQLVARLIST *_sql_res_var_lists = NULL;
7373
static SQLVARLIST *_sql_res_var_lists_last = NULL;
74+
static SQLVARLIST *_pool_sql_var_list = NULL; // Pool of SQLVARLIST items
7475
static int _var_lists_length = 0;
7576
static int _res_var_lists_length = 0;
7677
static int _occurs_length = 0;
7778
static int _occurs_iter = 0;
7879
static int _occurs_is_parent = 0;
7980

80-
8181
static void sqlca_initialize(struct sqlca_t *);
8282

8383
/* sql var list */
@@ -491,7 +491,7 @@ _ocesqlConnectMain(struct sqlca_t *st, char *name, char *user, char *passwd, cha
491491
int connlen = 0;
492492

493493
LOG("dbname = %s\n",name);
494-
LOG("user = %s\n",user);
494+
LOG("user = %s\n",user);
495495
LOG("password = %s\n",passwd);
496496
LOG("connname = %s\n",conndbname);
497497

@@ -2366,9 +2366,17 @@ reset_sql_var_list(void){
23662366
* <Outline>
23672367
* 埋め込みSQLリスト生成
23682368
*/
2369-
static inline SQLVARLIST *
2370-
new_sql_var_list(void){
2371-
return (SQLVARLIST *)calloc(1, sizeof(SQLVARLIST));
2369+
2370+
static inline SQLVARLIST *new_sql_var_list(void) {
2371+
SQLVARLIST *new_item;
2372+
if (_pool_sql_var_list != NULL) {
2373+
new_item = _pool_sql_var_list;
2374+
_pool_sql_var_list = _pool_sql_var_list->next;
2375+
new_item->next = NULL; // Initialize the item
2376+
} else {
2377+
new_item = (SQLVARLIST *)calloc(1, sizeof(SQLVARLIST));
2378+
}
2379+
return new_item;
23722380
}
23732381

23742382
/*
@@ -3261,7 +3269,7 @@ set_varchar_length(int len, char *dest){
32613269
for(i=0; i<OCDB_VARCHAR_HEADER_BYTE; i++){
32623270
c = 0xf & (len >> (i*4));
32633271
dest[OCDB_VARCHAR_HEADER_BYTE-i-1] =
3264-
(c>9) ? (c+'A'-10) : (c+'0');
3272+
(c>9) ? (c+'A'-10) : (c+'0');
32653273
}
32663274
}
32673275
return;
@@ -3286,17 +3294,38 @@ static void show_sql_var_list(SQLVARLIST *p){
32863294
* <Input>
32873295
* @SQLVARLIST *
32883296
*/
3289-
static void
3290-
clear_sql_var_list(SQLVARLIST *p){
3291-
if(p != NULL){
3292-
clear_sql_var_list(p->next);
3293-
if(p->sv.data)
3294-
free(p->sv.data);
3295-
if(p->sv.realdata)
3296-
free(p->sv.realdata);
3297-
free(p);
3297+
static void clear_sql_var_list(SQLVARLIST *p) {
3298+
if (p == NULL)
3299+
return; // Nothing to clear
3300+
3301+
SQLVARLIST *temp = p;
3302+
SQLVARLIST *last_item = NULL;
3303+
while (temp != NULL) {
3304+
SQLVARLIST *next = temp->next;
3305+
if (temp->sv.data)
3306+
free(temp->sv.data);
3307+
if (temp->sv.realdata)
3308+
free(temp->sv.realdata);
3309+
// Initialize the item before returning it to the pool
3310+
memset(&temp->sv, 0, sizeof(SQLVAR));
3311+
last_item = temp;
3312+
temp = next;
3313+
}
3314+
// Return the entire list to the pool
3315+
last_item->next = _pool_sql_var_list;
3316+
_pool_sql_var_list = p;
3317+
}
3318+
3319+
#if 0
3320+
/* free memory, this shoulkd be called at program exit, currently unused */
3321+
static void cleanup_sql_var_pool(void) {
3322+
while (_pool_sql_var_list != NULL) {
3323+
SQLVARLIST *next = _pool_sql_var_list->next;
3324+
free(_pool_sql_var_list);
3325+
_pool_sql_var_list = next;
32983326
}
32993327
}
3328+
#endif
33003329

33013330
static void
33023331
_ocesqlReleaseConnection(int status, void *arg){

0 commit comments

Comments
 (0)