Skip to content

Commit 6d45335

Browse files
committed
refactor(record): 重构记录打印逻辑
- 优化了记录打印的实现,减少了字符串拷贝和内存使用 - 使用 string_view 替代 string,提高性能 - 重构了 RecordPrinter 类,移除了模板函数 - 优化了输出缓冲区的管理,提高了打印效率
1 parent a6dacde commit 6d45335

5 files changed

Lines changed: 71 additions & 68 deletions

File tree

src/common/config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,7 @@ static constexpr size_t OFFSET_PAGE_START = 0;
6262
static constexpr size_t OFFSET_PAGE_LSN = 0;
6363
static constexpr size_t OFFSET_PAGE_HDR = 4;
6464

65-
static constexpr size_t BATCHSIZE = 1024;
65+
static constexpr size_t BATCHSIZE = 1024;
66+
67+
68+
static constexpr size_t COL_WIDTH = 16;

src/execution/execution_manager.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,35 +218,40 @@ void QlManager::select_from(std::unique_ptr<AbstractExecutor> executorTreeRoot,
218218
// Print records
219219
size_t num_rec = 0;
220220
// 执行query_plan
221-
char buf[32];
221+
char buffer[BUFFER_LENGTH];
222+
int offset = 0;
223+
int size;
222224
for (executorTreeRoot->beginTuple(); !executorTreeRoot->is_end(); executorTreeRoot->nextTuple()) {
223225
auto Tuple = executorTreeRoot->Next();
224-
std::vector<std::string> columns;
225226
const auto &cols = executorTreeRoot->cols();
227+
std::vector<std::string_view> columns;
226228
columns.reserve(cols.size());
227229
for (auto &col : cols) {
228230
char *rec_buf = Tuple->data + col.offset;
229231
switch (col.type) {
230232
case ColType::TYPE_INT:
231-
snprintf(buf, sizeof(buf), "%d", *(int *)rec_buf);
232-
columns.emplace_back(buf);
233+
size = sprintf(buffer + offset, "%d", *(int *)rec_buf);
234+
columns.emplace_back(buffer + offset, size);
235+
offset += size;
233236
break;
234237
case ColType::TYPE_FLOAT:
235-
snprintf(buf, sizeof(buf), "%.6f", *(float *)rec_buf); // 更简洁的浮点表示
236-
columns.emplace_back(buf);
238+
size = sprintf(buffer + offset, "%.6f", *(float *)rec_buf); // 更简洁的浮点表示
239+
columns.emplace_back(buffer + offset, size);
240+
offset += size;
237241
break;
238242
case ColType::TYPE_STRING:
239-
size_t actual_len = strnlen((char *)rec_buf, col.len);
240-
columns.emplace_back((char *)rec_buf, actual_len);
243+
size_t actual_len = strnlen(rec_buf, col.len);
244+
columns.emplace_back(rec_buf, actual_len);
241245
break;
242246
}
243247
}
248+
NXT:;
244249
// print record into buffer
245250
rec_printer.print_record(columns, context);
246251
// print record into file
247252
if (sm_manager.is_output_file_) {
248253
outfile << "|";
249-
for (const std::string &column : columns) {
254+
for (auto column : columns) {
250255
outfile << " " << column << " |";
251256
}
252257
outfile << "\n";

src/record_printer.h

Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -23,84 +23,79 @@ See the Mulan PSL v2 for more details. */
2323
#define RECORD_COUNT_LENGTH 40
2424

2525
class RecordPrinter {
26-
static constexpr size_t COL_WIDTH = 16;
2726
size_t num_cols;
2827

2928
public:
3029
RecordPrinter(size_t num_cols_) : num_cols(num_cols_) { assert(num_cols_ > 0); }
3130

3231
void print_separator(Context *context) const {
32+
int &offset = *(context->offset_);
33+
char *buffer = context->data_send_ + offset;
34+
3335
for (size_t i = 0; i < num_cols; i++) {
34-
constexpr ConstexprString<COL_WIDTH + 2> str('-');
35-
if (context->ellipsis_ == false && *context->offset_ + RECORD_COUNT_LENGTH + str.length() < BUFFER_LENGTH) {
36-
memcpy(context->data_send_ + *(context->offset_), str.c_str(), str.length());
37-
*(context->offset_) = *(context->offset_) + str.length();
36+
if (context->ellipsis_ == false && offset + RECORD_COUNT_LENGTH + COL_WIDTH + 3 < BUFFER_LENGTH) {
37+
buffer[0] = '+';
38+
memset(buffer + 1, '-', COL_WIDTH + 2);
39+
offset += COL_WIDTH + 3;
40+
buffer += COL_WIDTH + 3;
3841
} else {
3942
context->ellipsis_ = true;
4043
}
4144
}
42-
constexpr ConstexprString str("+\n");
43-
if (context->ellipsis_ == false && *context->offset_ + RECORD_COUNT_LENGTH + str.length() < BUFFER_LENGTH) {
44-
memcpy(context->data_send_ + *(context->offset_), str.c_str(), str.length());
45-
*(context->offset_) = *(context->offset_) + str.length();
45+
if (context->ellipsis_ == false && offset + RECORD_COUNT_LENGTH + 2 < BUFFER_LENGTH) {
46+
buffer[0] = '+';
47+
buffer[1] = '\n';
48+
offset += 2;
4649
} else {
4750
context->ellipsis_ = true;
4851
}
4952
}
5053

51-
template <typename StringType>
52-
void print_record(const std::vector<StringType> &rec_str, Context *context) const {
53-
assert(rec_str.size() == num_cols);
54-
if constexpr (std::is_same_v<StringType, std::string>) {
55-
for (const auto &col : rec_str) {
56-
std::stringstream ss;
57-
if (col.size() > COL_WIDTH) {
58-
ss << "| " << std::setw(COL_WIDTH) << std::string_view(col).substr(0, COL_WIDTH - 3) << "..."
59-
<< " ";
60-
} else {
61-
ss << "| " << std::setw(COL_WIDTH) << col << " ";
62-
}
63-
if (context->ellipsis_ == false &&
64-
*context->offset_ + RECORD_COUNT_LENGTH + ss.str().length() < BUFFER_LENGTH) {
65-
memcpy(context->data_send_ + *(context->offset_), ss.str().c_str(), ss.str().length());
66-
*(context->offset_) = *(context->offset_) + ss.str().length();
67-
} else {
68-
context->ellipsis_ = true;
69-
}
54+
void print_record(const std::vector<std::string_view> &rec_str, Context *context) const {
55+
int &offset = *(context->offset_);
56+
char *buffer = context->data_send_ + offset;
57+
58+
for (auto col : rec_str) {
59+
if (context->ellipsis_) return;
60+
if (offset + RECORD_COUNT_LENGTH + COL_WIDTH + 3 >= BUFFER_LENGTH) {
61+
context->ellipsis_ = true;
62+
break;
7063
}
71-
} else if constexpr (std::is_same_v<StringType, std::string_view>) {
72-
for (auto col : rec_str) {
73-
std::stringstream ss;
74-
if (col.size() > COL_WIDTH) {
75-
ss << "| " << std::setw(COL_WIDTH) << col.substr(0, COL_WIDTH - 3) << "..." << " ";
76-
} else {
77-
ss << "| " << std::setw(COL_WIDTH) << col << " ";
78-
}
79-
if (context->ellipsis_ == false &&
80-
*context->offset_ + RECORD_COUNT_LENGTH + ss.str().length() < BUFFER_LENGTH) {
81-
memcpy(context->data_send_ + *(context->offset_), ss.str().c_str(), ss.str().length());
82-
*(context->offset_) = *(context->offset_) + ss.str().length();
83-
} else {
84-
context->ellipsis_ = true;
85-
}
64+
strcpy(buffer, "| ");
65+
if (col.size() > COL_WIDTH) {
66+
memcpy(buffer + 2, col.data(), COL_WIDTH - 3);
67+
strcpy(buffer, "... ");
68+
} else {
69+
memset(buffer + 2, ' ', COL_WIDTH - col.size());
70+
memcpy(buffer + 2 + COL_WIDTH - col.size(), col.data(), col.size());
71+
buffer[COL_WIDTH + 2] = ' ';
8672
}
87-
} else {
88-
std::cerr << "unsupported type: " << typeid(StringType).name() << std::endl;
73+
74+
buffer += COL_WIDTH + 3;
75+
offset += COL_WIDTH + 3;
8976
}
90-
constexpr ConstexprString str("|\n");
91-
if (context->ellipsis_ == false && *context->offset_ + RECORD_COUNT_LENGTH + str.length() < BUFFER_LENGTH) {
92-
memcpy(context->data_send_ + *(context->offset_), str.c_str(), str.length());
93-
*(context->offset_) = *(context->offset_) + str.length();
77+
78+
if (context->ellipsis_ == false && offset + RECORD_COUNT_LENGTH + 2 < BUFFER_LENGTH) {
79+
buffer[0] = '|';
80+
buffer[1] = '\n';
81+
offset += 2;
82+
} else {
83+
context->ellipsis_ = true;
9484
}
9585
}
9686

9787
static void print_record_count(size_t num_rec, Context *context) {
98-
std::string str;
99-
if (context->ellipsis_ == true) {
100-
str = "... ...\n";
88+
int &offset = *(context->offset_);
89+
char *buffer = context->data_send_ + offset;
90+
91+
if (context->ellipsis_) {
92+
sprintf(buffer, "... ...\n");
93+
94+
buffer += 8;
95+
offset += 8;
10196
}
102-
str += "Total record(s): " + std::to_string(num_rec) + '\n';
103-
memcpy(context->data_send_ + *(context->offset_), str.c_str(), str.length());
104-
*(context->offset_) = *(context->offset_) + str.length();
97+
98+
size_t size = sprintf(buffer, "Total record(s): %ld\n", num_rec);
99+
offset += size;
105100
}
106101
};

src/storage/page_guard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class BasicPageGuard {
5151
friend class WritePageGuard;
5252
friend class BufferPoolInstance;
5353

54-
[[maybe_unused]] BufferPoolInstance *bpi_{nullptr};
54+
BufferPoolInstance *bpi_{nullptr};
5555
Page *page_{nullptr};
5656
bool is_dirty_{false};
5757
};

src/system/sm_manager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,15 @@ void SmManager::show_index(std::string tab_name, Context* context) {
289289
void SmManager::desc_table(std::string tab_name, Context* context) {
290290
TabMeta& tab = db_.get_table(tab_name);
291291

292-
std::vector<std::string> captions = {"Field", "Type", "Index"};
292+
std::vector<std::string_view> captions = {"Field", "Type", "Index"};
293293
RecordPrinter printer(captions.size());
294294
// Print header
295295
printer.print_separator(context);
296296
printer.print_record(captions, context);
297297
printer.print_separator(context);
298298
// Print fields
299299
for (auto& col : tab.cols) {
300-
std::vector<std::string> field_info = {col.name, coltype2str(col.type), col.index ? "YES" : "NO"};
300+
std::vector<std::string_view> field_info = {col.name, coltype2str(col.type), col.index ? "YES" : "NO"};
301301
printer.print_record(field_info, context);
302302
}
303303
// Print footer

0 commit comments

Comments
 (0)