#pragma once #include #include #include #include #include #include #include #include "tool.h" #include "BZStruct.h" class OrderBookParser { public: OrderBookParser() { // 初始化缓存,最大缓存100个订单簿数据 m_orderCache.setMaxCost(100); } bool parse(const char* data, int size, OrderBookData& output) { // 创建Response消息并解析 google::protobuf::Arena arena; auto* response = new Qot_UpdateOrderBook::Response; if (!response->ParseFromArray(data, size)) { return false; } // 检查响应状态 (0表示成功) if (response->rettype() != 0) { arena.Reset(); return false; } // 检查是否存在有效数据 if (!response->has_s2c()) { arena.Reset(); return true; } const auto& s2c = response->s2c(); output.clear(); output.name = QString(s2c.name().c_str()); output.code = QString(s2c.security().code().c_str()); output.askTime = QString(s2c.svrrecvtimeask().c_str()); output.bidTime = QString(s2c.svrrecvtimebid().c_str()); // 处理买盘订单簿 (bids) if (s2c.orderbookbidlist_size() > 0) { parseOrderBookList(s2c.orderbookbidlist(), output.bids); } // 处理卖盘订单簿 (asks) if (s2c.orderbookasklist_size() > 0) { parseOrderBookList(s2c.orderbookasklist(), output.asks); } // 数据预处理优化 if (!validateOrderData(*response)) { arena.Reset(); return false; } // 压缩数据以减少内存占用 compressOrderData(output); // 去重处理 removeDuplicateOrders(output); arena.Reset(); // 重置内存池供下次使用 return true; } // 添加数据有效性检查 bool validateOrderData(const Qot_UpdateOrderBook::Response &stRsp) { if (!stRsp.has_s2c()) { return false; } const auto& s2c = stRsp.s2c(); // 检查基本字段 if (s2c.security().code().empty() || s2c.name().empty()) { return false; } // 检查时间戳有效性 if (s2c.svrrecvtimeask().empty() && s2c.svrrecvtimebid().empty()) { return false; } // 检查价格和数量合理性 auto validatePriceVolume = [](const google::protobuf::RepeatedPtrField& list) { for (const auto& item : list) { if (item.price() <= 0 || item.volume() < 0) { return false; } for (const auto& detail : item.detaillist()) { if (detail.orderid() < 0 || detail.volume() < 0) { return false; } } } return true; }; if (!validatePriceVolume(s2c.orderbookbidlist()) || !validatePriceVolume(s2c.orderbookasklist())) { return false; } return true; } // 添加数据去重机制 void removeDuplicateOrders(OrderBookData& data) { auto removeDuplicates = [](QVector& entries) { QSet seenPrices; QVector uniqueEntries; uniqueEntries.reserve(entries.size()); for (const auto& entry : entries) { QString priceKey = QString::number(entry.price, 'f', 4); if (!seenPrices.contains(priceKey)) { seenPrices.insert(priceKey); uniqueEntries.append(entry); } } entries = std::move(uniqueEntries); }; removeDuplicates(data.bids); removeDuplicates(data.asks); } // 添加数据压缩,减少内存占用 void compressOrderData(OrderBookData& data) { // 压缩字符串数据 data.name = data.name.simplified(); data.code = data.code.simplified(); data.askTime = data.askTime.simplified(); data.bidTime = data.bidTime.simplified(); // 移除空明细的订单条目 auto compressEntries = [](QVector& entries) { QVector compressed; compressed.reserve(entries.size()); for (auto& entry : entries) { if (entry.isValid() && !entry.details.isEmpty()) { // 压缩明细数据 - 移除volume为0的明细 QVector validDetails; validDetails.reserve(entry.details.size()); for (const auto& detail : entry.details) { if (detail.volume > 0 && detail.orderId > 0) { validDetails.append(detail); } } if (!validDetails.isEmpty()) { entry.details = std::move(validDetails); compressed.append(entry); } } } entries = std::move(compressed); }; compressEntries(data.bids); compressEntries(data.asks); } private: QCache m_orderCache; void parseOrderBookList( const google::protobuf::RepeatedPtrField& pbList, QVector& output) { output.clear(); const int itemCount = pbList.size(); if (itemCount == 0) return; // 预分配输出内存 output.reserve(itemCount); // 第一遍:计算最大明细数量 int maxDetails = 0; for (int i = 0; i < itemCount; ++i) { maxDetails = std::max(maxDetails, pbList.Get(i).detaillist_size()); } // 第二遍:填充数据(使用局部缓冲区) for (int i = 0; i < itemCount; ++i) { const auto& pb_item = pbList.Get(i); const int detailCount = pb_item.detaillist_size(); // 为当前条目创建独立的明细缓冲区 QVector detailsBuffer; detailsBuffer.reserve(detailCount); // 按实际需求预分配 // 安全解析明细 try { for (int j = 0; j < detailCount; ++j) { const auto& pb_detail = pb_item.detaillist(j); OrderDetail detail; detail.orderId = pb_detail.orderid(); detail.volume = pb_detail.volume(); detailsBuffer.append(detail); } } catch (const std::exception& e) { detailsBuffer.clear(); // 清除非法数据 } // 构造 OrderBookEntry(直接移动缓冲区) OrderBookEntry item; item.price = pb_item.price(); item.volume = pb_item.volume(); item.orderCount = pb_item.oredercount(); item.details = detailCount > 0 ? std::move(detailsBuffer) : QVector{}; output.append(item); } } };