Skip to content

Commit c23abbe

Browse files
authored
Ускоряем рекурсивную операцию ydb schem ls (#2023)
1 parent 4a76801 commit c23abbe

File tree

4 files changed

+37
-20
lines changed

4 files changed

+37
-20
lines changed

ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ void TCommandList::Config(TConfig& config) {
858858
.StoreTrue(&Recursive);
859859
config.Opts->AddCharOption('1', "List one object per line")
860860
.StoreTrue(&FromNewLine);
861+
config.Opts->AddCharOption('m', "Multithread recursive request")
862+
.StoreTrue(&Multithread);
861863
AddFormats(config, { EOutputFormat::Pretty, EOutputFormat::Json });
862864
config.SetFreeArgsMax(1);
863865
SetFreeArgTitle(0, "<path>", "Path to list");
@@ -877,6 +879,7 @@ int TCommandList::Run(TConfig& config) {
877879
ISchemePrinter::TSettings settings = {
878880
Path,
879881
Recursive,
882+
Multithread,
880883
FromNewLine,
881884
FillSettings(NScheme::TListDirectorySettings()),
882885
FillSettings(NTable::TDescribeTableSettings().WithTableStatistics(true))

ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class TCommandList : public TYdbOperationCommand, public TCommandWithPath, publi
102102
bool AdvancedMode = false;
103103
bool Recursive = false;
104104
bool FromNewLine = false;
105+
bool Multithread = false;
105106
};
106107

107108
class TCommandPermissions : public TClientCommandTree {

ydb/public/lib/ydb_cli/common/scheme_printers.cpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ TSchemePrinterBase::TSchemePrinterBase(const TDriver& driver, TSettings&& settin
1515
{}
1616

1717
void TSchemePrinterBase::Print() {
18-
PrintDirectoryRecursive(Settings.Path, "");
18+
PrintDirectoryRecursive(Settings.Path, "").GetValueSync();
1919
}
2020

2121
bool TSchemePrinterBase::IsDirectoryLike(const NScheme::TSchemeEntry& entry) {
@@ -24,30 +24,41 @@ bool TSchemePrinterBase::IsDirectoryLike(const NScheme::TSchemeEntry& entry) {
2424
|| entry.Type == NScheme::ESchemeEntryType::ColumnStore;
2525
}
2626

27-
void TSchemePrinterBase::PrintDirectoryRecursive(const TString& fullPath, const TString& relativePath) {
28-
NScheme::TListDirectoryResult result = SchemeClient.ListDirectory(
27+
NThreading::TFuture<void> TSchemePrinterBase::PrintDirectoryRecursive(const TString& fullPath, const TString& relativePath) {
28+
return SchemeClient.ListDirectory(
2929
fullPath,
3030
Settings.ListDirectorySettings
31-
).GetValueSync();
32-
ThrowOnError(result);
31+
).Apply([this, fullPath, relativePath](const NScheme::TAsyncListDirectoryResult& resultFuture) {
32+
const auto& result = resultFuture.GetValueSync();
33+
ThrowOnError(result);
3334

34-
if (relativePath || IsDirectoryLike(result.GetEntry())) {
35-
PrintDirectory(relativePath, result);
36-
} else {
37-
PrintEntry(relativePath, result.GetEntry());
38-
}
35+
if (relativePath || IsDirectoryLike(result.GetEntry())) {
36+
std::lock_guard g(Lock);
37+
PrintDirectory(relativePath, result);
38+
} else {
39+
std::lock_guard g(Lock);
40+
PrintEntry(relativePath, result.GetEntry());
41+
}
3942

40-
if (Settings.Recursive) {
41-
for (const auto& child : result.GetChildren()) {
42-
TString childRelativePath = relativePath + (relativePath ? "/" : "") + child.Name;
43-
TString childFullPath = fullPath + "/" + child.Name;
44-
if (IsDirectoryLike(child)) {
45-
PrintDirectoryRecursive(childFullPath, childRelativePath);
46-
} else {
47-
PrintEntry(childRelativePath, child);
43+
TVector<NThreading::TFuture<void>> childFutures;
44+
if (Settings.Recursive) {
45+
for (const auto& child : result.GetChildren()) {
46+
TString childRelativePath = relativePath + (relativePath ? "/" : "") + child.Name;
47+
TString childFullPath = fullPath + "/" + child.Name;
48+
if (IsDirectoryLike(child)) {
49+
childFutures.push_back(PrintDirectoryRecursive(childFullPath, childRelativePath));
50+
if (!Settings.Multithread) {
51+
childFutures.back().Wait();
52+
childFutures.back().TryRethrow();
53+
}
54+
} else {
55+
std::lock_guard g(Lock);
56+
PrintEntry(childRelativePath, child);
57+
}
4858
}
4959
}
50-
}
60+
return NThreading::WaitExceptionOrAll(childFutures);
61+
});
5162
}
5263

5364
NTable::TDescribeTableResult TSchemePrinterBase::DescribeTable(const TString& relativePath) {

ydb/public/lib/ydb_cli/common/scheme_printers.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class ISchemePrinter {
1313
struct TSettings {
1414
TString Path;
1515
bool Recursive;
16+
bool Multithread;
1617
bool FromNewLine;
1718
NScheme::TListDirectorySettings ListDirectorySettings;
1819
NTable::TDescribeTableSettings DescribeTableSettings;
@@ -37,13 +38,14 @@ class TSchemePrinterBase : public ISchemePrinter {
3738
NTable::TDescribeTableResult DescribeTable(const TString& relativePath);
3839

3940
private:
40-
void PrintDirectoryRecursive(const TString& fullPath, const TString& relativePath);
41+
NThreading::TFuture<void> PrintDirectoryRecursive(const TString& fullPath, const TString& relativePath);
4142
static bool IsDirectoryLike(const NScheme::TSchemeEntry& entry);
4243

4344
protected:
4445
NTable::TTableClient TableClient;
4546
NScheme::TSchemeClient SchemeClient;
4647
const TSettings Settings;
48+
std::mutex Lock;
4749
};
4850

4951
class TDefaultSchemePrinter : public TSchemePrinterBase {

0 commit comments

Comments
 (0)