aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorОлег <150132506+iddqdex@users.noreply.github.com>2025-02-17 23:07:24 +0300
committerGitHub <noreply@github.com>2025-02-17 23:07:24 +0300
commitc25b7ee30559ef027fbc049354af1debffb6c1c6 (patch)
treee2fa5e5998a40015332039c052c3d7579b0ddd7b
parentf2c5cc1f5fc1783483441f751c8998ce19f8f948 (diff)
downloadydb-c25b7ee30559ef027fbc049354af1debffb6c1c6.tar.gz
fix memory leaks (#14712)
-rw-r--r--ydb/apps/ydb/CHANGELOG.md1
-rw-r--r--ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c4
-rw-r--r--ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c1
-rw-r--r--ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c9
-rw-r--r--ydb/library/workload/tpcds/dg_catalog_sales.cpp12
-rw-r--r--ydb/library/workload/tpcds/dg_store_sales.cpp11
-rw-r--r--ydb/library/workload/tpcds/driver.cpp151
7 files changed, 103 insertions, 86 deletions
diff --git a/ydb/apps/ydb/CHANGELOG.md b/ydb/apps/ydb/CHANGELOG.md
index 02a24b7207..c18314cbce 100644
--- a/ydb/apps/ydb/CHANGELOG.md
+++ b/ydb/apps/ydb/CHANGELOG.md
@@ -1,3 +1,4 @@
+* Fixed memory leak in tpcds generator.
* Include external data sources and external tables in local backups (`ydb tools dump` and `ydb tools restore`). Both scheme objects are backed up as YQL creation queries saved in the `create_external_data_source.sql` and `create_external_table.sql` files respectively, which can be executed to recreate the original scheme objects.
* Fixed a bug where `ydb auth get-token` command tried to authenticate twice: while listing andpoints and while executing actual token request.
* Fixed a bug where `ydb import file csv` command was saving progress even if a batch upload had been failed.
diff --git a/ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c b/ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c
index 3d2fe4d492..a0df071878 100644
--- a/ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c
+++ b/ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c
@@ -90,7 +90,9 @@ mk_w_customer (void * row, ds_key_t index)
if (!bInit)
{
- nBaseDate = dttoj (strtodate (DATE_MINIMUM));
+ date_t* minDate = strtodate (DATE_MINIMUM);
+ nBaseDate = dttoj (minDate);
+ free(minDate);
strtodt(&dtBirthMax, "1992-12-31");
strtodt(&dtBirthMin, "1924-01-01");
strtodt(&dtToday, TODAYS_DATE);
diff --git a/ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c b/ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c
index f81aedc64e..0a592e776f 100644
--- a/ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c
+++ b/ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c
@@ -90,6 +90,7 @@ mk_w_inventory(void *pDest, ds_key_t index)
base_date = strtodate (DATE_MINIMUM);
jDate = base_date->julian;
set_dow(base_date);
+ free(base_date);
/* Make exceptions to the 1-rng-call-per-row rule */
bInit = 1;
}
diff --git a/ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c b/ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c
index 507afb5e6a..074dd5cc26 100644
--- a/ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c
+++ b/ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c
@@ -81,7 +81,7 @@ mk_w_store (void* row, ds_key_t index)
nDaysOpen,
nMin,
nMax;
- static date_t *tDate;
+ static date_t tDate;
static decimal_t min_rev_growth,
max_rev_growth,
dMinTaxPercentage,
@@ -101,7 +101,9 @@ if (!bInit)
{
nHierarchyTotal = (int) get_rowcount (DIVISIONS);
nHierarchyTotal *= (int) get_rowcount (COMPANY);
- tDate = strtodate (DATE_MINIMUM);
+ date_t* minDate = strtodate (DATE_MINIMUM);
+ tDate = *minDate;
+ free (minDate);
strtodec (&min_rev_growth, STORE_MIN_REV_GROWTH);
strtodec (&max_rev_growth, STORE_MAX_REV_GROWTH);
strtodec (&dRevMin, "1.00");
@@ -111,6 +113,7 @@ if (!bInit)
/* columns that should be dynamic */
r->rec_end_date_id = -1;
+ bInit = 1;
}
nullSet(&pT->kNullBitMap, W_STORE_NULLS);
@@ -139,7 +142,7 @@ if (!bInit)
genrand_integer (NULL, DIST_UNIFORM, STORE_MIN_DAYS_OPEN, STORE_MAX_DAYS_OPEN, 0,
W_STORE_CLOSED_DATE_ID);
if (nPercentage < STORE_CLOSED_PCT)
- r->closed_date_id = tDate->julian + nDaysOpen;
+ r->closed_date_id = tDate.julian + nDaysOpen;
else
r->closed_date_id = -1;
changeSCD(SCD_KEY, &r->closed_date_id, &rOldValues->closed_date_id, &nFieldChangeFlags, bFirstRecord);
diff --git a/ydb/library/workload/tpcds/dg_catalog_sales.cpp b/ydb/library/workload/tpcds/dg_catalog_sales.cpp
index 3780a82acc..e9432f61d7 100644
--- a/ydb/library/workload/tpcds/dg_catalog_sales.cpp
+++ b/ydb/library/workload/tpcds/dg_catalog_sales.cpp
@@ -21,11 +21,9 @@ class TCatalogSalesGenerator {
public:
void MakeMaster(ds_key_t index) {
int giftPct;
- static bool init = false;
- if (!init) {
+ if (!ItemPermutation) {
Date = skipDays(CATALOG_SALES, &NewDateIndex);
ItemPermutation = makePermutation(NULL, (ItemCount = (int)getIDCount(ITEM)), CS_PERMUTE);
- init = true;
}
while (index > NewDateIndex) {
@@ -91,10 +89,16 @@ public:
writerSales.RegisterRow();
}
+ ~TCatalogSalesGenerator() {
+ if (ItemPermutation) {
+ free(ItemPermutation);
+ }
+ }
+
private:
int TicketItemBase = 1;
int ItemCount;
- int* ItemPermutation;
+ int* ItemPermutation = nullptr;
ds_key_t NewDateIndex = 0;
ds_key_t Date;
};
diff --git a/ydb/library/workload/tpcds/dg_store_sales.cpp b/ydb/library/workload/tpcds/dg_store_sales.cpp
index 372cccd001..98fe5097f6 100644
--- a/ydb/library/workload/tpcds/dg_store_sales.cpp
+++ b/ydb/library/workload/tpcds/dg_store_sales.cpp
@@ -20,11 +20,9 @@ namespace NYdbWorkload {
class TStoreSalesGenerator {
public:
void MakeMaster(ds_key_t index) {
- static bool init = false;
- if (!init) {
+ if (!ItemPermutation) {
Date = skipDays(STORE_SALES, &NewDateIndex);
ItemPermutation = makePermutation(NULL, ItemCount = (int)getIDCount(ITEM), SS_PERMUTATION);
- init = true;
}
while (index > NewDateIndex) {
@@ -65,10 +63,15 @@ public:
writerSales.RegisterRow();
}
+ ~TStoreSalesGenerator() {
+ if (ItemPermutation) {
+ free(ItemPermutation);
+ }
+ }
private:
int ItemCount;
int ItemIndex;
- int* ItemPermutation;
+ int* ItemPermutation = nullptr;
ds_key_t NewDateIndex = 0;
ds_key_t Date;
};
diff --git a/ydb/library/workload/tpcds/driver.cpp b/ydb/library/workload/tpcds/driver.cpp
index 38375b00da..dba8932455 100644
--- a/ydb/library/workload/tpcds/driver.cpp
+++ b/ydb/library/workload/tpcds/driver.cpp
@@ -18,63 +18,85 @@ extern "C" {
#define FL_LOADED 0x01
-extern "C" int di_compare(const void *op1, const void *op2) {
- d_idx_t *ie1 = (d_idx_t *)op1,
- *ie2 = (d_idx_t *)op2;
-
- return strcasecmp(ie1->name, ie2->name);
-}
+struct TDist: public dist_t {
+ TVector<int> TypeVector;
+ TVector<int> WeightSets;
+ TVector<int*> WeightSetIndex;
+ TVector<int> Maximums;
+ TVector<int> ValueSets;
+ TVector<int*> ValueSetIndex;
+ TString Strings;
+ TString Names;
+};
-int load_dist(d_idx_t *di) {
- int res = 0;
- int32_t temp;
+struct TDIdx: public d_idx_t {
+ explicit TDIdx(IInputStream& mi) {
+ memset(this, 0, sizeof(d_idx_t));
+ mi.Read(name, D_NAME_LEN);
+ name[D_NAME_LEN] = '\0';
+ index = ReadInt(mi);
+ offset = ReadInt(mi);
+ str_space = ReadInt(mi);
+ length = ReadInt(mi);
+ w_width = ReadInt(mi);
+ v_width = ReadInt(mi);
+ name_space = ReadInt(mi);
+ dist = nullptr;
+ }
- if (di->flags != FL_LOADED) {
+ void Load() {
+ dist = &Dist;
auto resource = NResource::Find("tpcds.idx");
TStringInput mi(resource);
- mi.Skip(di->offset);
- di->dist = (dist_t *)malloc(sizeof(struct DIST_T));
- auto d = di->dist;
- d->type_vector = (int *)malloc(sizeof(int32_t) * di->v_width);
- for (int i = 0; i < di->v_width; i++) {
- mi.Read(&temp, sizeof(int32_t));
- d->type_vector[i] = ntohl(temp);
+ mi.Skip(offset);
+ Dist.TypeVector.resize(v_width);
+ Dist.type_vector = Dist.TypeVector.data();
+ for (int i = 0; i < v_width; i++) {
+ Dist.TypeVector[i] = ReadInt(mi);
}
-
- d->weight_sets = (int **)malloc(sizeof(int *) * di->w_width);
- d->maximums = (int *)malloc(sizeof(int32_t) * di->w_width);
- for (int i = 0; i < di->w_width; i++) {
- *(d->weight_sets + i) = (int *)malloc(di->length * sizeof(int32_t));
- d->maximums[i] = 0;
- for (int j = 0; j < di->length; j++) {
- mi.Read(&temp, sizeof(int32_t));
- *(*(d->weight_sets + i) + j) = ntohl(temp);
- d->maximums[i] += d->weight_sets[i][j];
- d->weight_sets[i][j] = d->maximums[i];
+ Dist.WeightSetIndex.resize(w_width);
+ Dist.WeightSets.resize(w_width * length);
+ Dist.weight_sets = Dist.WeightSetIndex.data();
+ Dist.Maximums.resize(w_width);
+ Dist.maximums = Dist.Maximums.data();
+ for (int i = 0; i < w_width; i++) {
+ Dist.Maximums[i] = 0;
+ Dist.WeightSetIndex[i] = Dist.WeightSets.data() + i * length;
+ for (int j = 0; j < length; j++) {
+ Dist.maximums[i] += ReadInt(mi);
+ Dist.weight_sets[i][j] = Dist.maximums[i];
}
}
-
- d->value_sets = (int **)malloc(sizeof(int *) * di->v_width);
- MALLOC_CHECK(d->value_sets);
- for (int i = 0; i < di->v_width; i++) {
- *(d->value_sets + i) = (int *)malloc(di->length * sizeof(int32_t));
- for (int j = 0; j < di->length; j++) {
- mi.Read(&temp, sizeof(int32_t));
- *(*(d->value_sets + i) + j) = ntohl(temp);
+
+ Dist.ValueSetIndex.resize(v_width);
+ Dist.ValueSets.resize(v_width * length);
+ Dist.value_sets = Dist.ValueSetIndex.data();
+ for (int i = 0; i < v_width; i++) {
+ Dist.ValueSetIndex[i] = Dist.ValueSets.data() + i * length;
+ for (int j = 0; j < length; j++) {
+ Dist.value_sets[i][j] = ReadInt(mi);
}
}
- if (di->name_space) {
- d->names = (char *)malloc(di->name_space);
- mi.Read(d->names, di->name_space * sizeof(char));
+ if (name_space) {
+ Dist.Names.resize(name_space);
+ Dist.names = Dist.Names.begin();
+ mi.Read(Dist.names, name_space * sizeof(char));
}
- d->strings = (char *)malloc(sizeof(char) * di->str_space);
- mi.Read(d->strings, di->str_space * sizeof(char));
- di->flags = FL_LOADED;
+ Dist.Strings.resize(str_space);
+ Dist.strings = Dist.Strings.begin();
+ mi.Read(Dist.strings, str_space * sizeof(char));
+ flags = FL_LOADED;
}
- return(res);
-}
+
+ static inline int ReadInt(IInputStream& mi) {
+ int temp;
+ mi.Read(&temp, sizeof(int32_t));
+ return ntohl(temp);
+ };
+ TDist Dist;
+};
class TDists {
@@ -85,44 +107,25 @@ public:
memcpy(&temp, resource.data(), sizeof(int32_t));
int entry_count = ntohl(temp);
TMemoryInput mi(resource.end() - entry_count * IDX_SIZE, entry_count * IDX_SIZE);
- Idxs.resize(entry_count);
- for (auto& current_idx: Idxs) {
- memset(&current_idx, 0, sizeof(d_idx_t));
- mi.Read(current_idx.name, D_NAME_LEN);
- current_idx.name[D_NAME_LEN] = '\0';
- mi.Read(&temp, sizeof(int32_t));
- current_idx.index = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.offset = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.str_space = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.length = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.w_width = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.v_width = ntohl(temp);
- mi.Read(&temp, sizeof(int32_t));
- current_idx.name_space = ntohl(temp);
- current_idx.dist = NULL;
+ for (auto i = 0; i < entry_count; ++i) {
+ TDIdx current_idx(mi);
+ TString name(current_idx.name);
+ name.to_lower();
+ Idxs.emplace(name, std::move(current_idx));
}
- qsort(Idxs.begin(), entry_count, sizeof(d_idx_t), di_compare);
}
- d_idx_t* operator[](char* name) {
- d_idx_t key;
- strcpy(key.name, name);
- auto id = (d_idx_t *)bsearch(&key, Idxs.begin(), Idxs.size(), sizeof(d_idx_t), di_compare);
- if (id != NULL) {
- if (id->flags != FL_LOADED) {
- load_dist(id);
- }
+ d_idx_t* operator[](TString name) {
+ name.to_lower();
+ auto id = MapFindPtr(Idxs, name);
+ if (id != NULL && id->flags != FL_LOADED) {
+ id->Load();
}
return id;
}
private:
- TVector<d_idx_t> Idxs;
+ TMap<TString, TDIdx> Idxs;
};
extern "C" d_idx_t* find_dist(char *name) {