diff options
author | Олег <150132506+iddqdex@users.noreply.github.com> | 2025-02-17 23:07:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-17 23:07:24 +0300 |
commit | c25b7ee30559ef027fbc049354af1debffb6c1c6 (patch) | |
tree | e2fa5e5998a40015332039c052c3d7579b0ddd7b | |
parent | f2c5cc1f5fc1783483441f751c8998ce19f8f948 (diff) | |
download | ydb-c25b7ee30559ef027fbc049354af1debffb6c1c6.tar.gz |
fix memory leaks (#14712)
-rw-r--r-- | ydb/apps/ydb/CHANGELOG.md | 1 | ||||
-rw-r--r-- | ydb/library/benchmarks/gen/tpcds-dbgen/w_customer.c | 4 | ||||
-rw-r--r-- | ydb/library/benchmarks/gen/tpcds-dbgen/w_inventory.c | 1 | ||||
-rw-r--r-- | ydb/library/benchmarks/gen/tpcds-dbgen/w_store.c | 9 | ||||
-rw-r--r-- | ydb/library/workload/tpcds/dg_catalog_sales.cpp | 12 | ||||
-rw-r--r-- | ydb/library/workload/tpcds/dg_store_sales.cpp | 11 | ||||
-rw-r--r-- | ydb/library/workload/tpcds/driver.cpp | 151 |
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(¤t_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) { |