🛰️航天仿真算法库 SpaceAST 0.3.1
载入中...
搜索中...
未找到
IdentifierTable.hpp
浏览该文件的文档.
1
20
21#pragma once
22
23#include "AstGlobal.h"
24#include "Identifier.hpp"
25#include <vector>
26#include <mutex>
27#include <algorithm>
28#include <unordered_map> // for std::unordered_map
29#include <memory> // for std::unique_ptr
30#include <new> // for ::operator new
31
32AST_NAMESPACE_BEGIN
33
34// #define _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
35
36
38private:
39 // 使用哈希表存储符号
40 std::unordered_multimap<size_t, std::unique_ptr<Identifier>> table_{};
41#ifdef _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
42 mutable std::mutex mutex_;
43#endif
44
45 // 计算字符串的哈希值(DJB2哈希算法)
46 size_t compute_hash(const char* data, size_t length) const {
47 return Identifier::hash(data, length);
48 }
49
50public:
51 // 查找或创建符号
52 Identifier* intern(const char* data, size_t length) {
53 size_t hash = compute_hash(data, length);
54
55#ifdef _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
56 std::lock_guard<std::mutex> lock(mutex_);
57#endif
58 // 查找现有符号
59 auto range = table_.equal_range(hash);
60 for (auto it = range.first; it != range.second; ++it) {
61 Identifier* sym = it->second.get();
62 if (sym->length() == length &&
63 memcmp(sym->data(), data, length) == 0) {
64 return sym; // 返回现有符号
65 }
66 // ++it;
67 }
68
69 // 创建新符号
70 // 注意:这里必须使用 ::operator new 而非 new char[] 分配。
71 // 符号最终由 std::unique_ptr<Identifier> 释放(即 operator delete),
72 // 用 new char[] 分配会构成 new[]/delete 不匹配的未定义行为,ASan 会报 alloc-dealloc-mismatch。
73 size_t alloc_size = sizeof(Identifier) + length;
74 void* memory = ::operator new(alloc_size);
75 Identifier* sym = new (memory) Identifier(static_cast<uint32_t>(length));
76 memcpy(sym->data(), data, length);
77 sym->data()[length] = '\0';
78
79 table_.emplace(hash, std::unique_ptr<Identifier>(sym));
80 return sym;
81 }
82
83 // 重载版本,接受C字符串
84 Identifier* intern(const char* str) {
85 return intern(str, strlen(str));
86 }
87
88 // 重载版本,接受std::string
89 Identifier* intern(const std::string& str) {
90 return intern(str.c_str(), str.length());
91 }
92
93 // 查找符号(不创建)
94 Identifier* lookup(const char* data, size_t length) const {
95 size_t hash = compute_hash(data, length);
96
97#ifdef _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
98 std::lock_guard<std::mutex> lock(mutex_);
99#endif
100 auto range = table_.equal_range(hash);
101
102 for (auto it = range.first; it != range.second; ++it) {
103 Identifier* sym = it->second.get();
104 if (sym->length() == length &&
105 memcmp(sym->data(), data, length) == 0) {
106 return sym;
107 }
108 }
109
110 return nullptr;
111 }
112
113 // 获取符号数量
114 size_t size() const {
115#ifdef _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
116 std::lock_guard<std::mutex> lock(mutex_);
117#endif
118 return table_.size();
119 }
120
121 // 清理符号表(移除所有符号)
122 void clear() {
123#ifdef _AST_ENABLE_IDENTIFIER_TABLE_MUTEX
124 std::lock_guard<std::mutex> lock(mutex_);
125#endif
126 table_.clear();
127 }
128};
129
130
131AST_NAMESPACE_END
定义 IdentifierTable.hpp:37
标识符类
定义 Identifier.hpp:38