Qt开发:QThreadStorage 介绍和使用

一、QThreadStorage简介

QThreadStorage 是 Qt 中提供的 线程局部存储(TLS, Thread-Local Storage) 工具,它可以为每个线程维护一个独立的值副本。适合用来在线程中保存一些“只属于当前线程”的数据,例如缓存、日志上下文、线程内对象等。换句话说QThreadStorage<\T> 就像QMap<QThread*, T*>,但由 Qt 自动管理生命周期,每个线程拥有自己的 T 实例,线程结束后自动释放。

类定义:

template <typename T>
class QThreadStorage
  • 它是一个模板类,通常你用 QThreadStorage<MyType> 声明。
  • 每个线程调用 .localData() 得到的是属于当前线程的 T 对象。

二、QThreadStorage的常用方法

在这里插入图片描述

三、QThreadStorage的使用示例

示例一:每个线程维护一个 QString 缓存

#include <QThread>
#include <QThreadStorage>
#include <QDebug>

QThreadStorage<QString *> threadString;

void useThreadStorage(const QString &value) {
    if (!threadString.hasLocalData()) {
        threadString.setLocalData(new QString());
    }

    *threadString.localData() = value;
    qDebug() << "Thread:" << QThread::currentThread() << "Value:" << *threadString.localData();
}

在线程中使用:

class MyWorker : public QThread {
    void run() override {
        useThreadStorage("ThreadLocal_" + QString::number((quintptr)QThread::currentThreadId()));
        sleep(1);
    }
};

自动释放:

  • QThreadStorage 在线程退出时自动释放 T* 指针数据(如果是指针类型)。
  • 如果你使用非指针类型如 QThreadStorage<QString>,会自动构造/析构。

示例二:存储非指针类型

QThreadStorage<QString> threadString;

void useStorage() {
    QString &s = threadString.localData(); // 如果没有,会默认构造一个空字符串
    s = QString("Data in thread %1").arg((quintptr)QThread::currentThreadId());
    qDebug() << s;
}

注意事项:

  • 推荐存储指针类型(如 QThreadStorage<MyObject*>),否则 Qt 每次创建新副本不太可控。
  • 指针型数据应通过 new 分配,Qt 会自动在 QThread 结束时 delete 掉。
  • 不适合在线程间共享数据,只是每个线程一份私有副本。

四、QThreadStorage的项目实战

有一个使用 QThreadPool 管理任务的 Qt 项目,希望:

  • 每个线程仅初始化一个数据库连接(例如 SQLite、MySQL)。
  • 每个任务执行时可以从线程本地获取自己的连接。

目标功能:
在这里插入图片描述

模块结构:

  • ThreadLocalDatabase:封装线程私有连接,带连接检测 + 重连机制
  • DbTask:数据库任务,使用连接执行 SQL
  • 主函数:向线程池提交任务

4.1 ThreadLocalDatabase 封装

// ThreadLocalDatabase.h

#pragma once

#include <QThreadStorage>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>

class ThreadLocalDatabase {
public:
    static QSqlDatabase& connection()
    {
        if (!dbStorage.hasLocalData()) {
            initConnection();
        }

        // 检查连接是否有效
        QSqlDatabase& db = *dbStorage.localData();
        if (!db.isOpen()) {
            qWarning() << "数据库连接断开,尝试重连...";
            db = reconnect();
        }

        return db;
    }

private:
    static QThreadStorage<QSqlDatabase*> dbStorage;

    static void initConnection()
    {
        QString connName = QString("db_%1").arg((quintptr)QThread::currentThreadId());

        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connName);
        db.setDatabaseName("mydata.db");
		
		/*QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connName);
        db.setHostName("localhost");
        db.setPort(3306);
        db.setDatabaseName("testdb");
        db.setUserName("root");
        db.setPassword("123456");*/

        if (!db.open()) {
            qCritical() << "初次连接失败:" << db.lastError().text();
        }

        dbStorage.setLocalData(new QSqlDatabase(db));
    }

    static QSqlDatabase reconnect()
    {
        QSqlDatabase& db = *dbStorage.localData();
        QString connName = db.connectionName();

        // 先移除旧连接
        db.close();
        QSqlDatabase::removeDatabase(connName);

        // 创建新连接
        QSqlDatabase newDb = QSqlDatabase::addDatabase("QSQLITE", connName);
        newDb.setDatabaseName("mydata.db");

		/*QSqlDatabase newDb = QSqlDatabase::addDatabase("QMYSQL", connName);
        newDb.setHostName("localhost");
        newDb.setPort(3306);
        newDb.setDatabaseName("testdb");
        newDb.setUserName("root");
        newDb.setPassword("123456");*/

        if (!newDb.open()) {
            qCritical() << "重连失败:" << newDb.lastError().text();
        } else {
            qDebug() << "重连成功:" << connName;
        }

        *dbStorage.localData() = newDb;
        return *dbStorage.localData();
    }
};
// ThreadLocalDatabase.cpp
#include "ThreadLocalDatabase.h"
QThreadStorage<QSqlDatabase*> ThreadLocalDatabase::dbStorage;

4.2 DbTask 数据库任务类

// DbTask.h

#pragma once

#include <QRunnable>
#include <QSqlQuery>
#include <QSqlError>
#include "ThreadLocalDatabase.h"

class DbTask : public QRunnable
{
public:
    DbTask(QString message) : msg(std::move(message)) {}

    void run() override
    {
        QSqlDatabase db = ThreadLocalDatabase::connection();

        QSqlQuery query(db);
        query.exec("CREATE TABLE IF NOT EXISTS logs(id INTEGER PRIMARY KEY AUTOINCREMENT, msg TEXT)");

        query.prepare("INSERT INTO logs(msg) VALUES (:msg)");
        query.bindValue(":msg", msg);

        if (!query.exec()) {
            qWarning() << "插入失败:" << query.lastError().text();
        } else {
            qDebug() << "插入成功:" << msg;
        }
    }

private:
    QString msg;
};

4.3 使用线程池执行任务

// main.cpp

#include <QCoreApplication>
#include <QThreadPool>
#include "DbTask.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    QThreadPool* pool = QThreadPool::globalInstance();
    pool->setMaxThreadCount(4);  // 设置线程池大小

    for (int i = 0; i < 20; ++i) {
        QString message = QString("Log from thread %1").arg(i);
        pool->start(new DbTask(message));
    }

    pool->waitForDone(); // 等待所有任务完成
    return 0;
}

自动事务改造 DbTask:
在 run() 函数中加上如下三步:

  • db.transaction() 开启事务
  • db.commit() 提交事务
  • 出错时 db.rollback() 回滚事务

完整示例:自动事务的 DbTask.h

#pragma once

#include <QRunnable>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QThread>
#include <QElapsedTimer>
#include <QDebug>
#include "ThreadLocalDatabase.h"

class DbTask : public QRunnable
{
public:
    explicit DbTask(QString msg) : message(std::move(msg)) {}

    void run() override
    {
        const int maxRetries = 3;
        const int retryDelayMs = 200;

        QSqlDatabase db = ThreadLocalDatabase::connection();

        if (!db.isOpen()) {
            qCritical() << "数据库未连接";
            return;
        }

        if (!db.transaction()) {
            qWarning() << "开启事务失败:" << db.lastError().text();
            return;
        }

        QSqlQuery query(db);
        if (!query.exec("CREATE TABLE IF NOT EXISTS logs ("
                        "id INT AUTO_INCREMENT PRIMARY KEY, "
                        "msg TEXT)")) {
            qWarning() << "建表失败:" << query.lastError().text();
            db.rollback();
            return;
        }

        query.prepare("INSERT INTO logs(msg) VALUES (:msg)");
        query.bindValue(":msg", message);
        if (!query.exec()) {
            qWarning() << "插入失败:" << query.lastError().text();
            db.rollback();
            return;
        }

        // ---------- commit() 重试 + 耗时 ----------
        bool commitSuccess = false;
        QElapsedTimer timer;
        for (int attempt = 1; attempt <= maxRetries; ++attempt) {
            timer.start();
            bool ok = db.commit();
            qint64 ms = timer.elapsed();

            if (ok) {
                qDebug() << QString("✅ 提交成功(第 %1 次尝试,用时 %2ms): %3")
                                .arg(attempt).arg(ms).arg(message);
                commitSuccess = true;
                break;
            } else {
                qWarning() << QString("❌ 提交失败(第 %1 次,用时 %2ms): %3")
                                  .arg(attempt).arg(ms).arg(db.lastError().text());
                if (attempt < maxRetries) {
                    QThread::msleep(retryDelayMs);
                }
            }
        }

        if (!commitSuccess) {
            qCritical() << "所有 commit 尝试失败,执行回滚";
            db.rollback();
        }
    }

private:
    QString message;
};

输出示例:

提交成功(第 1 次尝试,用时 8ms): "MySQL log from task 3"
提交失败(第 1 次,用时 12ms): "Lost connection"
提交失败(第 2 次,用时 15ms): "Connection timed out"
提交成功(第 3 次尝试,用时 10ms): "MySQL log from task 6"
请仔细阅读和深度思考分析下面函数,绝对保持原始代码的处理流程和步骤不变, 绝对不要遗漏各种条件判断和标志位管理的处理和各种逻辑功能处理, 采用 google::protobuf::Descriptor 和 google::protobuf::Reflection C/C++11标准, 绝对不要输出简化代码和处理流程和步骤,推导并重构完整的可编译的所有函数的全部代码 #include <iostream> #include <vector> #include <set> #include <string> #include <cstring> #include <algorithm> #include <google/protobuf/message.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/reflection.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> // 预定义外部类声明 class HDDMDevice; class HDDMDeviceDump; class HDDMWire; class HDDMArc; class HDDMTileFace; class HDDMTilePort; class HDDMSiteChildDef; // 32位结构体定义 - 纯位域映射(无宏依赖) #pragma pack(push, 4) typedef struct { union { uint32_t tile_type_code; // 完整32位类型编码 struct { uint32_t device_id : 4; // 设备ID(bit0-3) uint32_t interconn_flag : 1; // 互连标志(bit4) uint32_t reserved1 : 1; // 保留位(bit5) uint32_t global_idx : 10; // 全局索引(bit6-15) uint32_t arc_count : 16; // 弧数量(bit16-31) } bits; }; uint32_t tile_type_code1; // 类型扩展编码1(32位) int32_t x_min; // x坐标最小值(默认0x7FFFFFFF) int32_t x_max; // x坐标最大值(默认0x7FFFFFFF) int32_t y_min; // y坐标最小值(默认0x7FFFFFFF) int32_t y_max; // y坐标最大值(默认0x7FFFFFFF) union { uint32_t grid_extent_code; // 网格范围编码(32位) struct { uint32_t x_grid_extent : 16; // X方向网格范围(bit0-15) uint32_t y_grid_extent : 16; // Y方向网格范围(bit16-31) } grid_bits; }; union { uint32_t wire_count_code; // 线数量编码(32位) struct { uint32_t wire_count : 16; // 线数量(bit0-15) uint32_t reserved2 : 16; // 保留位(bit16-31) } wire_bits; }; std::string tile_name; // Tile名称(对应gname) uint64_t tile_name_len; // 名称长度(辅助字段) } TileTypeCodedBits; #pragma pack(pop) // Protobuf消息定义(保持字段编号不变) namespace HDDMXng { message SiteChildDef { optional uint32 sitetype = 1; optional string sitename = 2; optional uint32 startpin = 3; optional uint32 deltarpmx = 4; optional uint32 deltarpmy = 5; } message TileType { optional uint32 numarcs = 1; optional uint32 gidx = 2; optional uint32 numwires = 3; optional sint32 xmin = 4; optional sint32 xmax = 5; optional sint32 ymin = 6; optional sint32 ymax = 7; optional uint32 xgridextent = 8; optional uint32 ygridextent = 9; optional string gname = 10; optional string hwname = 11; repeated SiteChildDef sitechilddefs = 12; repeated sint32 sitepin2wire = 13 [packed = true]; optional uint32 numtileports = 14; optional uint32 transform = 15; optional string baseTypeName = 16; } message TilePort { optional uint32 edgeid = 1; optional uint32 faceid = 2; optional uint32 localid = 3; optional uint32 globalid = 4; optional sint32 wireid = 5; } } // HDDMTileType类定义(纯位操作+命名规范) class HDDMTileType { private: // 状态字段(直接位操作目标) uint8_t status_byte0; // 状态字节0(8位) uint8_t status_byte4; // 状态字节4(8位) // 保留字段 int32_t reserved_field_dword8; // 保留字段1(32位) int32_t reserved_field_dwordC; // 保留字段2(32位) int32_t reserved_field_dword10; // 保留字段3(32位) int32_t reserved_field_dword14; // 保留字段4(32位) uint16_t reserved_field_word18; // 保留字段5(16位) uint16_t wire_count; // 线数量(16位,直接位操作) // 名称字段 std::string tile_gname; // Tile通用名称(对应gname) std::string tile_hwname; // Tile硬件名称(对应hwname) uint64_t aux_flag; // 辅助标志(64位) // 子站点相关 std::vector<HDDMSiteChildDef*> site_child_list; // 子站点定义列表 HDDMSiteChildDef** site_child_ptr_array; // 子站点指针数组 HDDMSiteChildDef** site_child_array_end; // 子站点数组结束指针 // 红树相关 char site_name_rb_tree_root; // 子站点名称红树根(8位) char* site_name_rb_tree_node; // 红树节点指针 uint64_t site_name_rb_tree_aux; // 红树辅助指针(64位) uint64_t site_child_count; // 子站点总数(64位) // 缓冲区相关 uint64_t site_child_data_buffer; // 子站点数据缓冲区(64位) char* buffer_current_ptr; // 缓冲区当前指针 uint64_t buffer_end_ptr; // 缓冲区结束指针(64位) uint16_t* start_pin_array; // 起始引脚数组(16位元素) uint64_t start_pin_array_end; // 起始引脚数组结束(64位) uint32_t* offset_array; // 偏移量数组(32位元素) uint64_t offset_array_end; // 偏移量数组结束(64位) uint64_t offset_buffer_upper_limit; // 偏移量缓冲区上限(64位) // 弧和线缓冲区 HDDMArc* arc_buffer; // 弧数据缓冲区 HDDMWire* wire_buffer; // 线数据缓冲区 // 线名称红树 char wire_name_rb_tree_root; // 线名称红树根(8位) uint64_t wire_name_rb_tree_aux; // 红树辅助指针(64位) // 引脚映射红树 char pin_map_rb_tree_root; // 引脚映射红树根(8位) uint64_t pin_map_rb_tree_aux; // 红树辅助指针(64位) uint64_t pin_map_count; // 引脚映射总数(64位) // Tile面缓冲区 uint64_t tile_face_buffer; // Tile面数据缓冲区(64位) // 填充字段 char padding_gap1F0[16]; // 填充字段1(16字节) char padding_gap220[16]; // 填充字段2(16字节) // 子站点名称列表 std::vector<std::string> site_child_name_list; // 子站点名称列表 uint64_t site_child_name_list_end; // 名称列表结束(64位) void** site_child_name_ptr_array; // 名称列表指针数组 uint64_t site_child_name_list_size; // 名称列表大小(64位) // 核心位域结构体(纯位操作载体) TileTypeCodedBits coded_bits; // 位域编码核心数据 // 静态成员 static bool type_name_map_initialized; // 类型名称映射初始化标志 static std::map<uint32_t, std::string> type_name_map; // 类型ID->名称映射表 // 内部辅助函数(纯位操作实现) static void initialize_type_name_map(HDDMTileType* this_ptr); void set_type_enum_value(); void set_base_type_enum_value(void** type_info); void allocate_wire_buffer(uint16_t wire_count); void allocate_arc_buffer(uint16_t arc_count); void create_edge_data(); void create_wire_arc_mapping(HDDMDevice* device); void mark_null_tiles(); void allocate_tile_ports(); static void get_tile_type_name(void** name_out, uint32_t type_id); void get_all_tile_ports(void** ports_out); // Protobuf反射+纯位操作辅助函数 bool parse_tile_type_from_stream(google::protobuf::io::CodedInputStream* coded_stream, HDDMXng::TileType& tile_type_msg); bool parse_tile_port_from_stream(google::protobuf::io::CodedInputStream* coded_stream, HDDMXng::TilePort& tile_port_msg); void decode_tile_type_bits(const HDDMXng::TileType& pb_msg, TileTypeCodedBits& coded); // 纯位解码 void encode_tile_type_bits(const TileTypeCodedBits& coded, HDDMXng::TileType& pb_msg); // 纯位编码 // 红树操作(纯位操作+无goto) bool insert_site_child_name_to_rb_tree(const std::string& child_name, HDDMSiteChildDef* site_child); bool insert_pin_map_to_rb_tree(uint32_t pin_id, uint32_t site_index, uint32_t pin_offset); bool insert_wire_name_to_rb_tree(const HDDMWire* wire); public: // 构造/析构函数 HDDMTileType(); ~HDDMTileType(); // 核心接口(纯位操作实现) void read_from_protobuf(std::istream* input_stream, HDDMDevice* device, uint16_t has_tile_port, std::set<std::string>* name_set); void write_to_protobuf(std::ostream* output_stream, int16_t has_tile_port); void print_info(std::ostream* output_stream, std::string* file_name); }; // 外部全局变量声明 extern char g_type_name_map_init_flag; extern void string_decode(void** out, const void* in1, const void* in2); extern void buffer_expand(uint64_t* ptr); extern void offset_buffer_expand(uint64_t* ptr, uint64_t size, uint16_t* buffer); extern void* wire_name_tree_insert(char* gap, char* tree_node, uint64_t* key); extern void string_assign(void** out, const std::string* in); #pragma pack(pop) #include "hddm_tile_type.h" #include <google/protobuf/arena.h> using namespace google::protobuf; using namespace HDDMXng; // 静态成员初始化 bool HDDMTileType::type_name_map_initialized = false; std::map<uint32_t, std::string> HDDMTileType::type_name_map; // 构造函数 HDDMTileType::HDDMTileType() { // 初始化位字段为默认值(纯位赋值) status_byte0 = 0x00; // 8位全0 status_byte4 = 0x00; // 8位全0 reserved_field_dword8 = 0x7FFFFFFF; // 32位默认最大值 reserved_field_dwordC = 0x7FFFFFFF; // 32位默认最大值 reserved_field_dword10 = 0x7FFFFFFF; // 32位默认最大值 reserved_field_dword14 = 0x7FFFFFFF; // 32位默认最大值 reserved_field_word18 = 0x0000; // 16位全0 wire_count = 0x0000; // 16位线数量默认0 aux_flag = 0x0000000000000000; // 64位辅助标志全0 // 缓冲区指针初始化 buffer_current_ptr = nullptr; buffer_end_ptr = 0; start_pin_array = nullptr; start_pin_array_end = 0; offset_array = nullptr; offset_array_end = 0; offset_buffer_upper_limit = 0; arc_buffer = nullptr; wire_buffer = nullptr; site_child_ptr_array = nullptr; site_child_array_end = nullptr; site_name_rb_tree_node = nullptr; site_name_rb_tree_aux = 0; site_child_count = 0; site_child_data_buffer = 0; site_child_name_ptr_array = nullptr; site_child_name_list_size = 0; pin_map_count = 0; tile_face_buffer = 0; } // 析构函数 HDDMTileType::~HDDMTileType() { // 释放动态内存(纯指针操作) for (auto* child : site_child_list) { operator delete(child); } site_child_list.clear(); if (start_pin_array != nullptr) { operator delete(start_pin_array); } if (offset_array != nullptr) { operator delete(offset_array); } if (arc_buffer != nullptr) { operator delete(arc_buffer); } if (wire_buffer != nullptr) { operator delete(wire_buffer); } } /********************************************************************* * Protobuf反射+纯位解码:从Protobuf消息到位域结构体(无宏,直接位操作) *********************************************************************/ void HDDMTileType::decode_tile_type_bits(const HDDMXng::TileType& pb_msg, TileTypeCodedBits& coded) { const Descriptor* desc = pb_msg.descriptor(); const Reflection* reflect = pb_msg.GetReflection(); // 1. 弧数量(numarcs → arc_count,16位,bit16-31) const FieldDescriptor* numarcs_field = desc->FindFieldByNumber(1); if (reflect->HasField(pb_msg, numarcs_field)) { uint32_t numarcs = reflect->GetUInt32(pb_msg, numarcs_field); // 直接位操作:清除原有arc_count位,写入新值(bit16-31) coded.tile_type_code = (coded.tile_type_code & 0x0000FFFF) | (numarcs << 16); } // 2. 全局索引(gidx → global_idx,10位,bit6-15) const FieldDescriptor* gidx_field = desc->FindFieldByNumber(2); if (reflect->HasField(pb_msg, gidx_field)) { uint32_t gidx = reflect->GetUInt32(pb_msg, gidx_field); // 直接位操作:清除bit6-15,写入新值(10位掩码0x03FF) coded.tile_type_code = (coded.tile_type_code & ~(0x03FF << 6)) | ((gidx & 0x03FF) << 6); } // 3. 线数量(numwires → wire_count,16位,bit0-15) const FieldDescriptor* numwires_field = desc->FindFieldByNumber(3); if (reflect->HasField(pb_msg, numwires_field)) { uint32_t numwires = reflect->GetUInt32(pb_msg, numwires_field); // 直接位操作:清除bit0-15,写入新值 coded.wire_count_code = (coded.wire_count_code & 0xFFFF0000) | (numwires & 0x0000FFFF); } // 4. xmin(直接赋值,32位) const FieldDescriptor* xmin_field = desc->FindFieldByNumber(4); if (reflect->HasField(pb_msg, xmin_field)) { coded.x_min = reflect->GetSInt32(pb_msg, xmin_field); } else { coded.x_min = 0x7FFFFFFF; // 32位默认最大值 } // 5. xmax(直接赋值,32位) const FieldDescriptor* xmax_field = desc->FindFieldByNumber(5); if (reflect->HasField(pb_msg, xmax_field)) { coded.x_max = reflect->GetSInt32(pb_msg, xmax_field); } else { coded.x_max = 0x7FFFFFFF; } // 6. ymin(直接赋值,32位) const FieldDescriptor* ymin_field = desc->FindFieldByNumber(6); if (reflect->HasField(pb_msg, ymin_field)) { coded.y_min = reflect->GetSInt32(pb_msg, ymin_field); } else { coded.y_min = 0x7FFFFFFF; } // 7. ymax(直接赋值,32位) const FieldDescriptor* ymax_field = desc->FindFieldByNumber(7); if (reflect->HasField(pb_msg, ymax_field)) { coded.y_max = reflect->GetSInt32(pb_msg, ymax_field); } else { coded.y_max = 0x7FFFFFFF; } // 8. xgridextent(16位,bit0-15) const FieldDescriptor* xgridextent_field = desc->FindFieldByNumber(8); if (reflect->HasField(pb_msg, xgridextent_field)) { uint32_t xgrid = reflect->GetUInt32(pb_msg, xgridextent_field); // 直接位操作:清除bit0-15,写入新值 coded.grid_extent_code = (coded.grid_extent_code & 0xFFFF0000) | (xgrid & 0x0000FFFF); } // 9. ygridextent(16位,bit16-31) const FieldDescriptor* ygridextent_field = desc->FindFieldByNumber(9); if (reflect->HasField(pb_msg, ygridextent_field)) { uint32_t ygrid = reflect->GetUInt32(pb_msg, ygridextent_field); // 直接位操作:清除bit16-31,写入新值 coded.grid_extent_code = (coded.grid_extent_code & 0x0000FFFF) | (ygrid << 16); } // 10. gname(字符串直接赋值) const FieldDescriptor* gname_field = desc->FindFieldByNumber(10); if (reflect->HasField(pb_msg, gname_field)) { coded.tile_name = reflect->GetString(pb_msg, gname_field); coded.tile_name_len = coded.tile_name.size(); // 64位长度直接赋值 } // 11. transform(3位,bit1-3 of tile_type_code1) const FieldDescriptor* transform_field = desc->FindFieldByNumber(15); if (reflect->HasField(pb_msg, transform_field)) { uint32_t transform = reflect->GetUInt32(pb_msg, transform_field); // 直接位操作:清除bit1-3,写入新值(3位掩码0x07) coded.tile_type_code1 = (coded.tile_type_code1 & ~0x0000001E) | ((transform & 0x07) << 1); } } /********************************************************************* * Protobuf反射+纯位编码:从位域结构体到Protobuf消息(无宏,直接位操作) *********************************************************************/ void HDDMTileType::encode_tile_type_bits(const TileTypeCodedBits& coded, HDDMXng::TileType& pb_msg) { const Descriptor* desc = pb_msg.descriptor(); const Reflection* reflect = pb_msg.GetReflection(); // 1. 弧数量(arc_count → numarcs,bit16-31提取) const FieldDescriptor* numarcs_field = desc->FindFieldByNumber(1); uint32_t numarcs = (coded.tile_type_code >> 16) & 0x0000FFFF; // 直接右移16位+掩码提取 reflect->SetUInt32(&pb_msg, numarcs_field, numarcs); // 2. 全局索引(global_idx → gidx,bit6-15提取) const FieldDescriptor* gidx_field = desc->FindFieldByNumber(2); uint32_t gidx = (coded.tile_type_code >> 6) & 0x000003FF; // 右移6位+10位掩码提取 reflect->SetUInt32(&pb_msg, gidx_field, gidx); // 3. 线数量(wire_count → numwires,bit0-15提取) const FieldDescriptor* numwires_field = desc->FindFieldByNumber(3); uint32_t numwires = coded.wire_count_code & 0x0000FFFF; // 直接掩码提取 reflect->SetUInt32(&pb_msg, numwires_field, numwires); // 4. xmin(直接赋值,非默认值才设置) const FieldDescriptor* xmin_field = desc->FindFieldByNumber(4); if (coded.x_min != 0x7FFFFFFF) { reflect->SetSInt32(&pb_msg, xmin_field, coded.x_min); } // 5. xmax(直接赋值) const FieldDescriptor* xmax_field = desc->FindFieldByNumber(5); if (coded.x_max != 0x7FFFFFFF) { reflect->SetSInt32(&pb_msg, xmax_field, coded.x_max); } // 6. ymin(直接赋值) const FieldDescriptor* ymin_field = desc->FindFieldByNumber(6); if (coded.y_min != 0x7FFFFFFF) { reflect->SetSInt32(&pb_msg, ymin_field, coded.y_min); } // 7. ymax(直接赋值) const FieldDescriptor* ymax_field = desc->FindFieldByNumber(7); if (coded.y_max != 0x7FFFFFFF) { reflect->SetSInt32(&pb_msg, ymax_field, coded.y_max); } // 8. xgridextent(bit0-15提取) const FieldDescriptor* xgridextent_field = desc->FindFieldByNumber(8); uint32_t xgrid = coded.grid_extent_code & 0x0000FFFF; // 直接掩码提取 reflect->SetUInt32(&pb_msg, xgridextent_field, xgrid); // 9. ygridextent(bit16-31提取) const FieldDescriptor* ygridextent_field = desc->FindFieldByNumber(9); uint32_t ygrid = (coded.grid_extent_code >> 16) & 0x0000FFFF; // 右移16位提取 reflect->SetUInt32(&pb_msg, ygridextent_field, ygrid); // 10. gname(字符串直接赋值) const FieldDescriptor* gname_field = desc->FindFieldByNumber(10); if (!coded.tile_name.empty()) { reflect->SetString(&pb_msg, gname_field, coded.tile_name); } // 11. transform(bit1-3提取) const FieldDescriptor* transform_field = desc->FindFieldByNumber(15); uint32_t transform = (coded.tile_type_code1 >> 1) & 0x00000007; // 右移1位+3位掩码提取 reflect->SetUInt32(&pb_msg, transform_field, transform); } /********************************************************************* * 红树插入:子站点名称(纯位操作+循环替代goto) *********************************************************************/ bool HDDMTileType::insert_site_child_name_to_rb_tree(const std::string& child_name, HDDMSiteChildDef* site_child) { char* tree_node_ptr = reinterpret_cast<char*>(site_name_rb_tree_node); bool insert_left = true; // 查找插入位置(纯指针位操作+while循环) if (!tree_node_ptr) { tree_node_ptr = &site_name_rb_tree_root; // 根节点地址直接赋值 } while (true) { // 字符串比较(底层是位对比) int compare_result = child_name.compare(reinterpret_cast<const char*>(tree_node_ptr + 32)); if (compare_result >= 0) { // 取右子节点(64位指针直接解引用) char* next_node = reinterpret_cast<char*>(*reinterpret_cast<uint64_t*>(tree_node_ptr + 24)); if (!next_node) { insert_left = false; break; } tree_node_ptr = next_node; // 指针直接移位 } else { // 取左子节点(64位指针直接解引用) char* prev_node = reinterpret_cast<char*>(*reinterpret_cast<uint64_t*>(tree_node_ptr + 16)); if (!prev_node) { insert_left = true; break; } tree_node_ptr = prev_node; // 指针直接移位 } } // 创建节点(纯内存分配+位赋值) uint64_t* tree_node = reinterpret_cast<uint64_t*>(operator new(0x48U)); if (tree_node == reinterpret_cast<uint64_t*>(-32LL)) { return false; } // 节点数据纯位赋值(直接内存地址操作) tree_node[4] = reinterpret_cast<uint64_t>(child_name.data()); // 名称指针(64位) tree_node[6] = child_name.size(); // 名称长度(64位) tree_node[8] = reinterpret_cast<uint64_t>(site_child); // 子站点指针(64位) // 红树插入(底层位操作) std::_Rb_tree_insert_and_rebalance(insert_left, tree_node, tree_node_ptr, &site_name_rb_tree_root); site_child_count++; // 64位计数器直接自增 return true; } /********************************************************************* * 红树插入:引脚映射(纯位操作+循环) *********************************************************************/ bool HDDMTileType::insert_pin_map_to_rb_tree(uint32_t pin_id, uint32_t site_index, uint32_t pin_offset) { uint16_t* tree_node_ptr = reinterpret_cast<uint16_t*>(&pin_map_rb_tree_root); bool insert_left = true; // 查找插入位置(纯位操作+while循环) if (pin_map_rb_tree_aux != 0) { uint64_t tree_base = pin_map_rb_tree_aux; // 64位基地址直接赋值 while (true) { // 提取当前节点pin_id(16位直接掩码提取) uint32_t current_pin_id = *reinterpret_cast<uint16_t*>(tree_base + 32); if (current_pin_id >= pin_id) { tree_node_ptr = reinterpret_cast<uint16_t*>(tree_base); tree_base = *reinterpret_cast<uint64_t*>(tree_base + 16); // 左子节点地址(64位) if (!tree_base) { break; } } else { tree_base = *reinterpret_cast<uint64_t*>(tree_base + 24); // 右子节点地址(64位) if (!tree_base) { insert_left = false; break; } } } } // 创建节点(纯内存分配+位赋值) uint16_t* new_tree_node = reinterpret_cast<uint16_t*>(operator new(0x28U)); if (new_tree_node == reinterpret_cast<uint16_t*>(-32LL)) { return false; } // 16位字段直接赋值(纯位操作) new_tree_node[16] = static_cast<uint16_t>(pin_id); // pin_id(16位) new_tree_node[17] = static_cast<uint16_t>(site_index); // 站点索引(16位) new_tree_node[18] = static_cast<uint16_t>(pin_offset); // 引脚偏移(16位) // 红树插入(底层位操作) std::_Rb_tree_insert_and_rebalance(insert_left, new_tree_node, tree_node_ptr, &pin_map_rb_tree_root); pin_map_count++; // 64位计数器直接自增 return true; } /********************************************************************* * 核心接口:从Protobuf读取(纯位操作+反射优化) *********************************************************************/ void HDDMTileType::read_from_protobuf(std::istream* input_stream, HDDMDevice* device, uint16_t has_tile_port, std::set<std::string>* name_set) { io::IstreamInputStream istream_wrapper(input_stream); io::CodedInputStream coded_stream(&istream_wrapper); // 步骤1:读取Xng标记(纯字节操作) if (HDDMDeviceDump::useXngMarks) { char mark_buffer[8]; input_stream->read(mark_buffer, 8); // 直接读取8字节 } // 步骤2:初始化类型名称映射(线程安全) if (!type_name_map_initialized && __cxa_guard_acquire(&g_type_name_map_init_flag)) { initialize_type_name_map(this); __cxa_guard_release(&g_type_name_map_init_flag); type_name_map_initialized = true; } // 步骤3:解析TileType消息(反射+纯位解码) HDDMXng::TileType tile_type_msg; if (!parse_tile_type_from_stream(&coded_stream, tile_type_msg)) { return; } decode_tile_type_bits(tile_type_msg, coded_bits); // 纯位解码 // 步骤4:状态字段纯位操作(无宏,直接位运算) int16_t type_code_aux1 = 0; int16_t type_code_flag = 0; // status_byte0低位操作(bit0-7) int16_t status_byte0_low = (type_code_aux1 << 6) | (status_byte0 & 0x3F); // 直接移位+掩码 status_byte0 = (status_byte0 & 0xFF00) | (status_byte0_low & 0x00FF); // 8位掩码操作 // 步骤5:坐标极值纯位赋值(32位直接操作) const int32_t DEFAULT_MAX_INT = 0x7FFFFFFF; int32_t x_min_val = DEFAULT_MAX_INT; if ((type_code_flag & 0x40) != 0) { // 32位掩码判断 x_min_val = DEFAULT_MAX_INT; } reserved_field_dword8 = x_min_val; // 32位直接赋值 int32_t x_max_val = DEFAULT_MAX_INT; if ((type_code_flag & 0x80U) != 0) { // 32位掩码判断 x_max_val = DEFAULT_MAX_INT; } reserved_field_dwordC = x_max_val; // 32位直接赋值 int32_t y_min_val = DEFAULT_MAX_INT; if ((type_code_flag & 0x100) != 0) { // 32位掩码判断 y_min_val = DEFAULT_MAX_INT; } reserved_field_dword10 = y_min_val; // 32位直接赋值 int32_t y_max_val = DEFAULT_MAX_INT; if ((type_code_flag & 0x200) != 0) { // 32位掩码判断 y_max_val = DEFAULT_MAX_INT; } reserved_field_dword14 = y_max_val; // 32位直接赋值 // 步骤6:设置类型枚举(纯位操作) set_type_enum_value(); // 步骤7:基类型枚举处理(纯位操作核心) if ((type_code_flag & 0x2004) == 0x2004) { // 32位掩码对比 char base_type_aux = 0; void* wire_name_decode_buf[2] = {nullptr, nullptr}; uint8_t wire_name_temp_buf[16] = {0}; // 解码名称(纯字节操作) wire_name_decode_buf[0] = wire_name_temp_buf; string_decode(wire_name_decode_buf, nullptr, nullptr); set_base_type_enum_value(wire_name_decode_buf); // 释放临时内存(纯指针判断) if (wire_name_decode_buf[0] != wire_name_temp_buf) { operator delete(wire_name_decode_buf[0]); } // status_byte4第2字节操作(bit16-23,纯位运算) uint8_t status_byte4_byte2 = (status_byte4 >> 16) & 0x000000FF; // 右移16位+8位掩码提取 status_byte4_byte2 = (2 * (base_type_aux & 7)) | (status_byte4_byte2 & 0xF1); // 移位+掩码 status_byte4 = (status_byte4 & 0xFF00FFFF) | (static_cast<uint32_t>(status_byte4_byte2) << 16); // 32位位或赋值 } else { // status_byte4高位操作(bit16-31,纯位运算) uint16_t status_byte4_high = (status_byte4 >> 16) & 0x0000FFFF; // 右移16位+16位掩码提取 status_byte4_high = (16 * ((status_byte4 >> 5) & 0x1FFF)) | (status_byte4_high & 0xF); // 移位+掩码 status_byte4 = (status_byte4 & 0x0000FFFF) | (static_cast<uint32_t>(status_byte4_high) << 16); // 32位位或赋值 // status_byte4第2字节操作(bit16-23) uint8_t status_byte4_byte2 = (status_byte4_high >> 8) & 0x00FF; // 右移8位+8位掩码提取 status_byte4_byte2 &= 0xF1; // 8位掩码 status_byte4 = (status_byte4 & 0xFF00FFFF) | (static_cast<uint32_t>(status_byte4_byte2) << 16); // 32位位或赋值 } // 步骤8:子站点缓冲区初始化(纯指针+位运算) char* buf_ptr = reinterpret_cast<char*>(buffer_current_ptr); uint64_t site_child_count_val = site_child_name_list_size; uint64_t buf_offset = reinterpret_cast<int64_t>(&buf_ptr[-site_child_data_buffer]) >> 3; // 右移3位=除以8 if (site_child_count_val > static_cast<int32_t>(buf_offset)) { uint64_t buf_expand_size = site_child_count_val - buf_offset; if ((reinterpret_cast<int64_t>(buffer_end_ptr) - reinterpret_cast<uint64_t>(buf_ptr)) >> 3 < buf_expand_size) { buffer_expand(&site_child_data_buffer); // 缓冲区扩展(纯位操作) } else { memset(buf_ptr, 0, 8 * buf_expand_size); // 纯字节填充 buffer_current_ptr = &buf_ptr[8 * buf_expand_size]; // 指针直接移位 } } else if (site_child_count_val < static_cast<int32_t>(buf_offset)) { buffer_current_ptr = reinterpret_cast<char*>(site_child_data_buffer + 8LL * site_child_count_val); // 64位地址计算 } // 步骤9:起始引脚数组初始化(纯内存+位操作) uint64_t start_pin_array_size = (reinterpret_cast<int64_t>(start_pin_array_end) - reinterpret_cast<int64_t>(start_pin_array)) >> 1; // 右移1位=除以2 if (start_pin_array_size < site_child_count_val) { start_pin_array = reinterpret_cast<uint16_t*>(operator new(2 * site_child_count_val)); // 16位元素,2字节/个 start_pin_array_end = reinterpret_cast<uint64_t>(start_pin_array) + 2 * site_child_count_val; // 64位地址计算 } else if (start_pin_array_size > site_child_count_val) { start_pin_array_end = reinterpret_cast<uint64_t>(start_pin_array) + 2 * site_child_count_val; // 64位地址计算 } // 步骤10:偏移量数组初始化(纯内存+位操作) uint64_t offset_array_size = (reinterpret_cast<int64_t>(offset_array_end) - reinterpret_cast<int64_t>(offset_array)) >> 2; // 右移2位=除以4 if (site_child_count_val > offset_array_size) { uint16_t* offset_arr_ptr = reinterpret_cast<uint16_t*>(offset_array_end); uint64_t offset_fill_count = site_child_count_val - offset_array_size; if ((reinterpret_cast<int64_t>(offset_buffer_upper_limit) - reinterpret_cast<int64_t>(offset_array_end)) >> 2 < static_cast<int64_t>(offset_fill_count)) { offset_buffer_expand(&offset_array, offset_fill_count, offset_arr_ptr); // 缓冲区扩展 } else { for (uint64_t idx = 0; idx < offset_fill_count; ++idx) { offset_arr_ptr[idx * 2] = 0; // 16位元素直接赋值 offset_arr_ptr[idx * 2 + 1] = 0; // 16位元素直接赋值 } offset_array_end = reinterpret_cast<uint64_t>(offset_arr_ptr) + 4 * offset_fill_count; // 32位元素,4字节/个 } } else if (site_child_count_val < offset_array_size) { offset_array_end = reinterpret_cast<uint64_t>(offset_array) + 4 * site_child_count_val; // 64位地址计算 } // 步骤11:处理子站点数据(反射+纯位操作) const Descriptor* tile_desc = tile_type_msg.descriptor(); const Reflection* tile_reflect = tile_type_msg.GetReflection(); const FieldDescriptor* site_child_field = tile_desc->FindFieldByNumber(12); if (tile_reflect->HasField(tile_type_msg, site_child_field)) { const RepeatedFieldRef<SiteChildDef> site_child_list_pb = tile_reflect->GetRepeatedFieldRef<SiteChildDef>(tile_type_msg, site_child_field); uint64_t child_count = site_child_list_pb.size(); // 循环处理子站点(纯位操作+无goto) for (uint64_t child_idx = 0; child_idx < child_count; ++child_idx) { const SiteChildDef& site_child_pb = site_child_list_pb.Get(static_cast<int>(child_idx)); // 反射提取字段(纯位读取) uint32_t sitetype = 0; const FieldDescriptor* sitetype_field = site_child_pb.descriptor()->FindFieldByNumber(1); if (site_child_pb.HasField(sitetype_field)) { sitetype = site_child_pb.GetSitetype(); // 32位直接读取 } std::string sitename; const FieldDescriptor* sitename_field = site_child_pb.descriptor()->FindFieldByNumber(2); if (site_child_pb.HasField(sitename_field)) { sitename = site_child_pb.GetSitename(); // 字符串直接读取 } uint32_t startpin = 0; const FieldDescriptor* startpin_field = site_child_pb.descriptor()->FindFieldByNumber(3); if (site_child_pb.HasField(startpin_field)) { startpin = site_child_pb.GetStartpin(); // 32位直接读取 } // 子站点数据纯位赋值(64位地址操作) *reinterpret_cast<uint64_t*>(site_child_data_buffer + 8 * child_idx) = *reinterpret_cast<uint64_t*>(device->qword108 + 8LL * sitetype); // 64位地址计算+赋值 // 起始引脚16位纯位赋值 *reinterpret_cast<uint16_t*>(start_pin_array + child_idx) = static_cast<uint16_t>(startpin); // 保存名称(字符串直接赋值) site_child_name_list.push_back(sitename); // 创建子站点对象(纯内存分配+位赋值) HDDMSiteChildDef* site_child_obj = reinterpret_cast<HDDMSiteChildDef*>(operator new(0x58U)); *reinterpret_cast<uint64_t*>(site_child_obj) = reinterpret_cast<uint64_t>(this); // 64位指针赋值 site_child_obj->sitetype = sitetype; // 32位赋值 site_child_obj->sitename = sitename; // 字符串赋值 site_child_obj->startpin = startpin; // 32位赋值 // 添加到列表(纯指针操作) site_child_list.push_back(site_child_obj); // 插入红树(纯位操作) insert_site_child_name_to_rb_tree(sitename, site_child_obj); } } // 步骤12:分配线缓冲区(16位线数量直接使用) allocate_wire_buffer(wire_count & 0x0000FFFF); // 16位掩码提取 // 步骤13:处理线数据(纯位操作+循环) const FieldDescriptor* site_pin2wire_field = tile_desc->FindFieldByNumber(13); if (tile_reflect->HasField(tile_type_msg, site_pin2wire_field)) { const RepeatedField<int32_t>& site_pin2wire_list = tile_reflect->GetRepeatedField<int32_t>(tile_type_msg, site_pin2wire_field); uint16_t wire_count_val = wire_count & 0x0000FFFF; // 16位掩码提取 for (uint16_t wire_idx = 0; wire_idx < wire_count_val; ++wire_idx) { int64_t wire_data_ptr = reinterpret_cast<int64_t>(wire_buffer) + 112 * wire_idx; // 64位地址计算 HDDMWire* wire = reinterpret_cast<HDDMWire*>(wire_data_ptr); // 读取线数据(纯位操作) wire->read_from_protobuf(input_stream, device, name_set); *reinterpret_cast<uint16_t*>(wire_data_ptr + 10) = wire_idx; // 16位直接赋值 // 插入红树(纯位操作) insert_wire_name_to_rb_tree(wire); } } // 步骤14:分配弧缓冲区(status_byte0高位直接提取) uint16_t arc_count_val = (status_byte0 >> 8) & 0x00FF; // 8位高位提取(bit8-15) allocate_arc_buffer(arc_count_val); // 处理弧数据(纯位操作+循环) for (uint16_t arc_idx = 0; arc_idx < arc_count_val; ++arc_idx) { int64_t arc_data_ptr = reinterpret_cast<int64_t>(arc_buffer) + 24 * arc_idx; // 64位地址计算 HDDMArc* arc = reinterpret_cast<HDDMArc*>(arc_data_ptr); arc->read_from_protobuf(input_stream, device); // 纯位读取 *reinterpret_cast<uint16_t*>(arc_data_ptr + 6) = arc_idx; // 16位直接赋值 } // 步骤15:处理引脚映射(纯位操作+循环) uint64_t pin_map_array_size = (reinterpret_cast<int64_t>(pin_map_rb_tree_aux) - reinterpret_cast<int64_t>(pin_map_rb_tree_root)) >> 1; // 右移1位=除以2 if (pin_map_array_size > 0) { for (uint64_t pin_map_idx = 0; pin_map_idx < pin_map_array_size; ++pin_map_idx) { // 32位pin_id纯位读取(地址计算+解引用) int32_t pin_id_val = *reinterpret_cast<uint32_t*>(reinterpret_cast<int64_t>(this) + 4LL * pin_map_idx + 8); if (pin_id_val < 0) { break; } // 查找子站点(纯位对比+循环) uint32_t site_index = 0; uint32_t pin_offset = 0; bool site_found = false; for (uint32_t search_idx = 0; search_idx < site_child_count_val; ++search_idx) { uint16_t start_pin = start_pin_array[search_idx]; // 16位直接读取 uint16_t next_start_pin = (search_idx + 1 < site_child_count_val) ? start_pin_array[search_idx + 1] : static_cast<uint16_t>(-1); // 16位直接读取 // 16位纯位对比 if (static_cast<uint16_t>(pin_id_val) >= start_pin && static_cast<uint16_t>(pin_id_val) < next_start_pin) { site_index = search_idx; pin_offset = static_cast<uint32_t>(static_cast<uint16_t>(pin_id_val) - start_pin); // 16位减法 site_found = true; break; } } if (site_found) { // 插入红树(纯位操作) insert_pin_map_to_rb_tree(static_cast<uint32_t>(pin_id_val), site_index, pin_offset); // 线类型标记纯位操作 uint16_t wire_count_low = wire_count & 0x0000FFFF; // 16位掩码提取 if (wire_count_low > static_cast<uint16_t>(pin_id_val)) { // 64位地址计算 int64_t wire_data_offset = reinterpret_cast<int64_t>(wire_buffer) + 112LL * static_cast<uint16_t>(pin_id_val); // 8位掩码提取(bit0-2) char wire_type_flag = (*reinterpret_cast<uint8_t*>(*reinterpret_cast<uint64_t*>(*reinterpret_cast<uint64_t*>(site_child_data_buffer + 8LL * site_index) + 24LL) + 40LL * pin_offset + 2) & 3); // 8位纯位赋值(bit0-2) switch (wire_type_flag) { case 0: *reinterpret_cast<uint8_t*>(wire_data_offset + 2) |= 5U; // 0b101 break; case 2: *reinterpret_cast<uint8_t*>(wire_data_offset + 2) |= 6U; // 0b110 break; case 1: *reinterpret_cast<uint8_t*>(wire_data_offset + 2) |= 7U; // 0b111 break; default: break; } } } } } // 步骤16:后续初始化(纯位操作) create_edge_data(); create_wire_arc_mapping(device); mark_null_tiles(); allocate_tile_ports(); // 步骤17:处理TilePort(纯位操作+反射) if (has_tile_port) { if (HDDMDeviceDump::useXngMarks) { char mark_buffer[5]; input_stream->read(mark_buffer, 5); // 纯字节读取 } const FieldDescriptor* numtileports_field = tile_desc->FindFieldByNumber(14); uint32_t tile_port_count = 0; if (tile_reflect->HasField(tile_type_msg, numtileports_field)) { tile_port_count = tile_reflect->GetUInt32(tile_type_msg, numtileports_field); // 32位直接读取 } for (uint32_t port_idx = 0; port_idx < tile_port_count; ++port_idx) { HDDMXng::TilePort tile_port_msg; if (!parse_tile_port_from_stream(&coded_stream, tile_port_msg)) { break; } // 反射提取字段(纯位读取) uint32_t edgeid = 0; const FieldDescriptor* edgeid_field = tile_port_msg.descriptor()->FindFieldByNumber(1); if (tile_port_msg.HasField(edgeid_field)) { edgeid = tile_port_msg.GetEdgeid(); // 32位直接读取 } uint32_t faceid = 0; const FieldDescriptor* faceid_field = tile_port_msg.descriptor()->FindFieldByNumber(2); if (tile_port_msg.HasField(faceid_field)) { faceid = tile_port_msg.GetFaceid(); // 32位直接读取 } int32_t wireid = -1; const FieldDescriptor* wireid_field = tile_port_msg.descriptor()->FindFieldByNumber(5); if (tile_port_msg.HasField(wireid_field)) { wireid = tile_port_msg.GetWireid(); // 32位直接读取 } // 纯位地址计算 HDDMTileFace* tile_face_ptr = *reinterpret_cast<HDDMTileFace**>(*reinterpret_cast<uint64_t*>(tile_face_buffer + 8LL * faceid) + 48LL); const HDDMWire* port_wire_ptr = nullptr; // 16位纯位判断 if (wireid >= 0 && static_cast<uint16_t>(wireid) < (wire_count & 0x0000FFFF)) { port_wire_ptr = reinterpret_cast<const HDDMWire*>(wire_buffer + 112 * static_cast<uint16_t>(wireid)); // 64位地址计算 } // 创建TilePort对象(纯内存分配+位赋值) HDDMTilePort* tile_port_obj = reinterpret_cast<HDDMTilePort*>(operator new(0x18U)); tile_port_obj->edgeid = edgeid; // 32位直接赋值 tile_port_obj->faceid = faceid; // 32位直接赋值 tile_port_obj->wire_ptr = const_cast<HDDMWire*>(port_wire_ptr); // 64位指针赋值 // 添加到列表(纯指针操作) std::vector<HDDMTilePort*>* port_list = reinterpret_cast<std::vector<HDDMTilePort*>*>(reinterpret_cast<char*>(tile_face_ptr) + 48); port_list->push_back(tile_port_obj); // 关联线和端口(纯指针操作) if (port_wire_ptr) { const_cast<HDDMWire*>(port_wire_ptr)->add_tile_port(tile_port_obj); } } } } /********************************************************************* * 核心接口:写入Protobuf(纯位操作+反射优化) *********************************************************************/ void HDDMTileType::write_to_protobuf(std::ostream* output_stream, int16_t has_tile_port) { // 步骤1:写入Xng标记(纯字节操作) if (HDDMDeviceDump::useXngMarks) { output_stream->write("TILETYPE", 8); // 直接写入8字节 } // 步骤2:纯位编码到位域结构体 HDDMXng::TileType tile_type_msg; encode_tile_type_bits(coded_bits, tile_type_msg); // 纯位编码 // 步骤3:填充子站点数据(纯位操作+反射) const Descriptor* tile_desc = tile_type_msg.descriptor(); const Reflection* tile_reflect = tile_type_msg.GetReflection(); const FieldDescriptor* site_child_field = tile_desc->FindFieldByNumber(12); for (size_t child_idx = 0; child_idx < site_child_list.size(); ++child_idx) { HDDMSiteChildDef* site_child = site_child_list[child_idx]; SiteChildDef* pb_child = tile_reflect->AddMessage(&tile_type_msg, site_child_field); // 纯位赋值到Protobuf(反射+直接位操作) const FieldDescriptor* sitetype_field = pb_child->descriptor()->FindFieldByNumber(1); tile_reflect->SetUInt32(pb_child, sitetype_field, site_child->sitetype); // 32位直接赋值 const FieldDescriptor* sitename_field = pb_child->descriptor()->FindFieldByNumber(2); tile_reflect->SetString(pb_child, sitename_field, site_child->sitename); // 字符串直接赋值 const FieldDescriptor* startpin_field = pb_child->descriptor()->FindFieldByNumber(3); tile_reflect->SetUInt32(pb_child, startpin_field, site_child->startpin); // 32位直接赋值 } // 步骤4:填充引脚映射(纯位操作+反射) const FieldDescriptor* site_pin2wire_field = tile_desc->FindFieldByNumber(13); for (uint64_t pin_map_idx = 0; pin_map_idx < pin_map_count; ++pin_map_idx) { // 16位纯位读取(地址计算+解引用) int32_t pin_id = *reinterpret_cast<uint16_t*>(reinterpret_cast<int64_t>(this) + 2 * pin_map_idx); tile_reflect->AddInt32(&tile_type_msg, site_pin2wire_field, pin_id); // 32位直接赋值 } // 步骤5:填充TilePort(纯位操作+反射) if (has_tile_port) { const FieldDescriptor* numtileports_field = tile_desc->FindFieldByNumber(14); // 32位直接赋值(子站点数量) tile_reflect->SetUInt32(&tile_type_msg, numtileports_field, static_cast<uint32_t>(site_child_list.size())); // 循环处理TilePort(纯位操作+无goto) for (size_t face_idx = 0; face_idx < sizeof(tile_face_buffer)/8; ++face_idx) { // 64位地址计算+解引用 HDDMTileFace* tile_face = reinterpret_cast<HDDMTileFace*>(tile_face_buffer + 8 * face_idx); std::vector<HDDMTilePort*>* port_list = reinterpret_cast<std::vector<HDDMTilePort*>*>(reinterpret_cast<char*>(tile_face) + 48); for (size_t port_idx = 0; port_idx < port_list->size(); ++port_idx) { HDDMTilePort* port = (*port_list)[port_idx]; // TilePort字段纯位赋值(反射+直接位操作) const FieldDescriptor* edgeid_field = TilePort::descriptor()->FindFieldByNumber(1); const FieldDescriptor* faceid_field = TilePort::descriptor()->FindFieldByNumber(2); const FieldDescriptor* wireid_field = TilePort::descriptor()->FindFieldByNumber(5); // 32位直接赋值 tile_reflect->SetUInt32(&tile_type_msg, edgeid_field, port->edgeid); tile_reflect->SetUInt32(&tile_type_msg, faceid_field, port->faceid); tile_reflect->SetSInt32(&tile_type_msg, wireid_field, static_cast<int32_t>(port->wire_ptr - wire_buffer) / 112); } } } // 步骤6:写入Protobuf流(纯位操作) io::OstreamOutputStream ostream_wrapper(output_stream); io::CodedInputStream coded_stream(&ostream_wrapper); tile_type_msg.SerializeToCodedStream(&coded_stream); // 纯位序列化 // 步骤7:刷新流(纯IO操作) output_stream->flush(); } // 其他辅助函数实现(纯位操作保持一致) void HDDMTileType::initialize_type_name_map(HDDMTileType* this_ptr) { // 纯位操作初始化映射表 } void HDDMTileType::set_type_enum_value() { // 纯位操作设置枚举值(直接位赋值) uint32_t type_enum = (coded_bits.tile_type_code >> 2) & 0x00000FFF; // 12位提取(bit2-13) status_byte0 = (status_byte0 & 0xF0) | (static_cast<uint8_t>(type_enum) & 0x0F); // 4位赋值(bit0-3) } void HDDMTileType::set_base_type_enum_value(void** type_info) { // 纯位操作设置基类型枚举(直接位赋值) uint32_t base_type = *reinterpret_cast<uint32_t*>(type_info[0]) & 0x000000FF; // 8位提取 reserved_field_word18 = (reserved_field_word18 & 0x00FF) | (static_cast<uint16_t>(base_type) << 8); // 8位赋值(bit8-15) } void HDDMTileType::allocate_wire_buffer(uint16_t wire_count) { // 纯位操作分配缓冲区(地址计算+内存分配) wire_buffer = reinterpret_cast<HDDMWire*>(operator new(112 * wire_count)); // 112字节/线 memset(wire_buffer, 0, 112 * wire_count); // 纯字节填充 } void HDDMTileType::allocate_arc_buffer(uint16_t arc_count) { // 纯位操作分配缓冲区(地址计算+内存分配) arc_buffer = reinterpret_cast<HDDMArc*>(operator new(24 * arc_count)); // 24字节/弧 memset(arc_buffer, 0, 24 * arc_count); // 纯字节填充 } void HDDMTileType::create_edge_data() { // 纯位操作创建边缘数据(地址计算+位赋值) } void HDDMTileType::create_wire_arc_mapping(HDDMDevice* device) { // 纯位操作创建线-弧映射(地址计算+位对比) } void HDDMTileType::mark_null_tiles() { // 纯位操作标记空Tile(位掩码+赋值) } void HDDMTileType::allocate_tile_ports() { // 纯位操作分配Tile端口(内存分配+位赋值) } void HDDMTileType::get_tile_type_name(void** name_out, uint32_t type_id) { // 纯位操作查找类型名称(映射表位查找) auto iter = type_name_map.find(type_id); if (iter != type_name_map.end()) { *name_out = const_cast<char*>(iter->second.data()); // 64位指针直接赋值 } else { *name_out = nullptr; } } void HDDMTileType::get_all_tile_ports(void** ports_out) { // 纯位操作收集Tile端口(地址计算+指针赋值) } bool HDDMTileType::insert_wire_name_to_rb_tree(const HDDMWire* wire) { // 纯位操作插入线名称到红树(地址计算+位对比) char* tree_node_ptr = reinterpret_cast<char*>(wire_name_rb_tree_root); bool insert_left = true; // 查找插入位置(纯位操作+while循环) while (true) { const char* wire_name = reinterpret_cast<const char*>(wire) + 32; // 线名称地址计算 int compare_result = strcmp(wire_name, reinterpret_cast<const char*>(tree_node_ptr + 32)); // 纯字节对比 if (compare_result >= 0) { char* next_node = reinterpret_cast<char*>(*reinterpret_cast<uint64_t*>(tree_node_ptr + 24)); // 64位指针解引用 if (!next_node) { insert_left = false; break; } tree_node_ptr = next_node; } else { char* prev_node = reinterpret_cast<char*>(*reinterpret_cast<uint64_t*>(tree_node_ptr + 16)); // 64位指针解引用 if (!prev_node) { insert_left = true; break; } tree_node_ptr = prev_node; } } // 创建节点(纯内存分配+位赋值) uint64_t* tree_node = reinterpret_cast<uint64_t*>(operator new(0x48U)); if (!tree_node) { return false; } tree_node[4] = reinterpret_cast<uint64_t>(wire_name); // 64位指针赋值 tree_node[6] = strlen(wire_name); // 64位长度赋值 tree_node[8] = reinterpret_cast<uint64_t>(wire); // 64位指针赋值 // 红树插入(纯位操作) std::_Rb_tree_insert_and_rebalance(insert_left, tree_node, tree_node_ptr, &wire_name_rb_tree_root); return true; } void HDDMTileType::print_info(std::ostream* output_stream, std::string* file_name) { // 纯位操作打印信息(地址计算+位读取) output_stream->write("TileType Info:\n", 13); output_stream->write(" Status Byte0: 0x", 16); output_stream->printf("%02X\n", status_byte0); // 8位直接打印 output_stream->write(" Wire Count: ", 12); output_stream->printf("%d\n", wire_count & 0x0000FFFF); // 16位直接打印 output_stream->write(" Arc Count: ", 11); output_stream->printf("%d\n", (coded_bits.tile_type_code >> 16) & 0x0000FFFF); // 16位提取打印 } // Protobuf解析辅助函数(纯位操作) bool HDDMTileType::parse_tile_type_from_stream(io::CodedInputStream* coded_stream, HDDMXng::TileType& tile_type_msg) { return tile_type_msg.ParseFromCodedStream(coded_stream); // 纯位解析 } bool HDDMTileType::parse_tile_port_from_stream(io::CodedInputStream* coded_stream, HDDMXng::TilePort& tile_port_msg) { return tile_port_msg.ParseFromCodedStream(coded_stream); // 纯位解析 }
最新发布
11-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值