LAPTOP-SNT8I5JK\Boounion
2025-09-11 27dcc9508096cc4096d732a521b630852c7b063b
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -619,12 +619,42 @@
    }
    // ==================== 2) DB 当前页(两阶段构建,处理单向 buddy) ====================
    const int rawLimit = PAGE_SIZE + 1;
    const int rawOffset = PAGE_SIZE * (m_nCurPage - 1);
#if USE_FAKE_DB_DEMO
    auto page = _make_page_fake(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
    auto page = _make_page_fake(m_filters, rawLimit, rawOffset);
#else
    auto& db = GlassLogDb::Instance();
    auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
    auto pageFull = db.queryPaged(m_filters, rawLimit, rawOffset);
#endif
    // 如果多出一条,看看它是否是“本页最后一条”的 buddy
    std::optional<decltype(pageFull.items)::value_type> lookahead; // 预读记录(若与最后一条配对)
    auto iEquals = [](const std::string& a, const std::string& b) {
#ifdef _WIN32
        return _stricmp(a.c_str(), b.c_str()) == 0;
#else
        return strcasecmp(a.c_str(), b.c_str()) == 0;
#endif
    };
    if (pageFull.items.size() == rawLimit) {
        const auto& last = pageFull.items[PAGE_SIZE - 1];
        const auto& extra = pageFull.items[PAGE_SIZE];
        bool pair =
            (!last.buddyId.empty() && iEquals(last.buddyId, extra.classId)) ||
            (!extra.buddyId.empty() && iEquals(extra.buddyId, last.classId));
        if (pair) {
            lookahead = extra;           // 把预读保存下来,稍后补成子行
        }
        // 无论是否配对,列表都缩回 PAGE_SIZE 条(预读不算入本页数据集)
        pageFull.items.pop_back();
    }
    // 之后正常按 page 构建
    auto& page = pageFull; // 为了复用你原有变量名
    // 建索引:classId -> index
    std::unordered_map<std::string, size_t> idxById;
@@ -643,6 +673,8 @@
    // -------- Phase 1: 先处理“有 buddyId 的记录”(能配就配;单向也配) ----------
    for (size_t i = 0; i < page.items.size(); ++i) {
        const auto& r = page.items[i];
        AfxMessageBox(r.pretty.c_str());
        if (consumed.count(r.classId)) continue;
        if (r.buddyId.empty()) continue;