hikyuu 2.7.3__py3-none-win_amd64.whl → 2.7.5__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. hikyuu/__init__.py +3 -1
  2. hikyuu/__init__.pyi +14 -13
  3. hikyuu/analysis/__init__.pyi +1 -0
  4. hikyuu/analysis/analysis.pyi +2 -1
  5. hikyuu/core.pyi +3 -2
  6. hikyuu/cpp/core310.pyd +0 -0
  7. hikyuu/cpp/core310.pyi +80 -46
  8. hikyuu/cpp/core311.pyd +0 -0
  9. hikyuu/cpp/core311.pyi +80 -46
  10. hikyuu/cpp/core312.pyd +0 -0
  11. hikyuu/cpp/core312.pyi +80 -46
  12. hikyuu/cpp/core313.pyd +0 -0
  13. hikyuu/cpp/core313.pyi +80 -46
  14. hikyuu/cpp/hikyuu.dll +0 -0
  15. hikyuu/cpp/hikyuu.lib +0 -0
  16. hikyuu/cpp/mimalloc-redirect.dll +0 -0
  17. hikyuu/cpp/mimalloc.dll +0 -0
  18. hikyuu/data/clickhouse_upgrade/0002.sql +9 -0
  19. hikyuu/data/common_mysql.py +1 -1
  20. hikyuu/data/em_block_to_mysql.py +16 -4
  21. hikyuu/data/em_block_to_sqlite.py +16 -4
  22. hikyuu/data/hku_config_template.py +1 -1
  23. hikyuu/data/mysql_upgrade/0030.sql +3 -0
  24. hikyuu/data/pytdx_to_h5.py +2 -2
  25. hikyuu/data/pytdx_to_mysql.py +5 -5
  26. hikyuu/data/sqlite_upgrade/0030.sql +5 -0
  27. hikyuu/draw/__init__.pyi +1 -1
  28. hikyuu/draw/drawplot/__init__.pyi +1 -1
  29. hikyuu/draw/drawplot/bokeh_draw.pyi +7 -6
  30. hikyuu/draw/drawplot/echarts_draw.pyi +7 -6
  31. hikyuu/draw/drawplot/matplotlib_draw.py +19 -11
  32. hikyuu/draw/drawplot/matplotlib_draw.pyi +7 -6
  33. hikyuu/examples/notebook/001-overview.ipynb +112 -78
  34. hikyuu/examples/notebook/004-IndicatorOverview.ipynb +52 -65
  35. hikyuu/examples/notebook/006-TradeManager.ipynb +402 -291
  36. hikyuu/examples/notebook/008-Pickle.ipynb +25 -17
  37. hikyuu/examples/notebook/009-RealData.ipynb +36 -38
  38. hikyuu/examples/notebook/Demo/Demo2.ipynb +146 -116
  39. hikyuu/extend.pyi +4 -3
  40. hikyuu/gui/data/UseTdxImportToH5Thread.py +4 -2
  41. hikyuu/gui/start_qmt.py +1 -1
  42. hikyuu/hub.pyi +6 -6
  43. hikyuu/include/hikyuu/Block.h +9 -9
  44. hikyuu/include/hikyuu/HistoryFinanceInfo.h +3 -3
  45. hikyuu/include/hikyuu/KData.h +51 -28
  46. hikyuu/include/hikyuu/KDataImp.h +12 -7
  47. hikyuu/include/hikyuu/KDataPrivatedBufferImp.h +13 -7
  48. hikyuu/include/hikyuu/KDataSharedBufferImp.h +8 -6
  49. hikyuu/include/hikyuu/KQuery.h +11 -11
  50. hikyuu/include/hikyuu/KRecord.h +1 -1
  51. hikyuu/include/hikyuu/MarketInfo.h +10 -10
  52. hikyuu/include/hikyuu/Stock.h +30 -30
  53. hikyuu/include/hikyuu/StockManager.h +11 -10
  54. hikyuu/include/hikyuu/StockTypeInfo.h +9 -9
  55. hikyuu/include/hikyuu/StockWeight.h +9 -9
  56. hikyuu/include/hikyuu/TimeLineRecord.h +1 -1
  57. hikyuu/include/hikyuu/TransRecord.h +1 -1
  58. hikyuu/include/hikyuu/data_driver/BlockInfoDriver.h +6 -0
  59. hikyuu/include/hikyuu/data_driver/KDataDriver.h +4 -3
  60. hikyuu/include/hikyuu/indicator/IndParam.h +1 -1
  61. hikyuu/include/hikyuu/indicator/Indicator.h +56 -27
  62. hikyuu/include/hikyuu/indicator/Indicator2InImp.h +0 -4
  63. hikyuu/include/hikyuu/indicator/IndicatorImp.h +146 -73
  64. hikyuu/include/hikyuu/indicator/crt/CONTEXT.h +11 -1
  65. hikyuu/include/hikyuu/indicator/crt/IC.h +19 -14
  66. hikyuu/include/hikyuu/indicator/crt/ICIR.h +4 -7
  67. hikyuu/include/hikyuu/indicator/imp/IAbs.h +1 -0
  68. hikyuu/include/hikyuu/indicator/imp/IAcos.h +1 -0
  69. hikyuu/include/hikyuu/indicator/imp/IAd.h +0 -2
  70. hikyuu/include/hikyuu/indicator/imp/IAdvance.h +3 -0
  71. hikyuu/include/hikyuu/indicator/imp/IAma.h +3 -0
  72. hikyuu/include/hikyuu/indicator/imp/IAsin.h +1 -0
  73. hikyuu/include/hikyuu/indicator/imp/IAtan.h +1 -0
  74. hikyuu/include/hikyuu/indicator/imp/IAtr.h +2 -3
  75. hikyuu/include/hikyuu/indicator/imp/IBackset.h +2 -4
  76. hikyuu/include/hikyuu/indicator/imp/IBlockSetNum.h +3 -0
  77. hikyuu/include/hikyuu/indicator/imp/ICeil.h +1 -0
  78. hikyuu/include/hikyuu/indicator/imp/IContext.h +0 -3
  79. hikyuu/include/hikyuu/indicator/imp/ICorr.h +3 -0
  80. hikyuu/include/hikyuu/indicator/imp/ICos.h +1 -0
  81. hikyuu/include/hikyuu/indicator/imp/ICost.h +0 -2
  82. hikyuu/include/hikyuu/indicator/imp/ICount.h +2 -1
  83. hikyuu/include/hikyuu/indicator/imp/ICval.h +1 -4
  84. hikyuu/include/hikyuu/indicator/imp/ICycle.h +0 -2
  85. hikyuu/include/hikyuu/indicator/imp/IDecline.h +3 -0
  86. hikyuu/include/hikyuu/indicator/imp/IDevsq.h +4 -1
  87. hikyuu/include/hikyuu/indicator/imp/IDiff.h +1 -0
  88. hikyuu/include/hikyuu/indicator/imp/IDma.h +2 -0
  89. hikyuu/include/hikyuu/indicator/imp/IDropna.h +0 -4
  90. hikyuu/include/hikyuu/indicator/imp/IEma.h +3 -1
  91. hikyuu/include/hikyuu/indicator/imp/IEvery.h +5 -1
  92. hikyuu/include/hikyuu/indicator/imp/IExist.h +5 -1
  93. hikyuu/include/hikyuu/indicator/imp/IExp.h +1 -0
  94. hikyuu/include/hikyuu/indicator/imp/IFilter.h +4 -5
  95. hikyuu/include/hikyuu/indicator/imp/IFinance.h +1 -2
  96. hikyuu/include/hikyuu/indicator/imp/IFloor.h +1 -0
  97. hikyuu/include/hikyuu/indicator/imp/IHhvbars.h +5 -1
  98. hikyuu/include/hikyuu/indicator/imp/IHighLine.h +5 -1
  99. hikyuu/include/hikyuu/indicator/imp/IHsl.h +0 -2
  100. hikyuu/include/hikyuu/indicator/imp/IIc.h +3 -6
  101. hikyuu/include/hikyuu/indicator/imp/IInBlock.h +1 -2
  102. hikyuu/include/hikyuu/indicator/imp/IIntpart.h +1 -0
  103. hikyuu/include/hikyuu/indicator/imp/IIsInf.h +1 -0
  104. hikyuu/include/hikyuu/indicator/imp/IIsInfa.h +1 -0
  105. hikyuu/include/hikyuu/indicator/imp/IIsLastBar.h +0 -1
  106. hikyuu/include/hikyuu/indicator/imp/IIsNa.h +1 -0
  107. hikyuu/include/hikyuu/indicator/imp/IJumpDown.h +1 -0
  108. hikyuu/include/hikyuu/indicator/imp/IJumpUp.h +1 -0
  109. hikyuu/include/hikyuu/indicator/imp/IKData.h +1 -2
  110. hikyuu/include/hikyuu/indicator/imp/ILiuTongPan.h +0 -2
  111. hikyuu/include/hikyuu/indicator/imp/ILn.h +1 -0
  112. hikyuu/include/hikyuu/indicator/imp/ILog.h +1 -0
  113. hikyuu/include/hikyuu/indicator/imp/ILowLine.h +5 -1
  114. hikyuu/include/hikyuu/indicator/imp/ILowLineBars.h +5 -1
  115. hikyuu/include/hikyuu/indicator/imp/IMa.h +6 -1
  116. hikyuu/include/hikyuu/indicator/imp/IMacd.h +2 -0
  117. hikyuu/include/hikyuu/indicator/imp/INot.h +1 -0
  118. hikyuu/include/hikyuu/indicator/imp/IPow.h +3 -1
  119. hikyuu/include/hikyuu/indicator/imp/IQuantileTrunc.h +1 -0
  120. hikyuu/include/hikyuu/indicator/imp/IRecover.h +3 -0
  121. hikyuu/include/hikyuu/indicator/imp/IRef.h +3 -1
  122. hikyuu/include/hikyuu/indicator/imp/IResult.h +1 -0
  123. hikyuu/include/hikyuu/indicator/imp/IReverse.h +1 -0
  124. hikyuu/include/hikyuu/indicator/imp/IRoc.h +6 -1
  125. hikyuu/include/hikyuu/indicator/imp/IRocp.h +5 -1
  126. hikyuu/include/hikyuu/indicator/imp/IRocr.h +5 -1
  127. hikyuu/include/hikyuu/indicator/imp/IRocr100.h +5 -1
  128. hikyuu/include/hikyuu/indicator/imp/IRound.h +1 -0
  129. hikyuu/include/hikyuu/indicator/imp/IRoundDown.h +1 -0
  130. hikyuu/include/hikyuu/indicator/imp/IRoundUp.h +1 -0
  131. hikyuu/include/hikyuu/indicator/imp/ISaftyLoss.h +1 -0
  132. hikyuu/include/hikyuu/indicator/imp/ISign.h +1 -0
  133. hikyuu/include/hikyuu/indicator/imp/ISin.h +1 -0
  134. hikyuu/include/hikyuu/indicator/imp/ISlope.h +5 -1
  135. hikyuu/include/hikyuu/indicator/imp/ISma.h +2 -0
  136. hikyuu/include/hikyuu/indicator/imp/ISpearman.h +3 -0
  137. hikyuu/include/hikyuu/indicator/imp/ISqrt.h +1 -0
  138. hikyuu/include/hikyuu/indicator/imp/IStdev.h +5 -1
  139. hikyuu/include/hikyuu/indicator/imp/IStdp.h +5 -1
  140. hikyuu/include/hikyuu/indicator/imp/ISum.h +6 -1
  141. hikyuu/include/hikyuu/indicator/imp/ITan.h +1 -0
  142. hikyuu/include/hikyuu/indicator/imp/ITime.h +1 -2
  143. hikyuu/include/hikyuu/indicator/imp/ITimeLine.h +0 -2
  144. hikyuu/include/hikyuu/indicator/imp/ITr.h +1 -2
  145. hikyuu/include/hikyuu/indicator/imp/IVar.h +5 -1
  146. hikyuu/include/hikyuu/indicator/imp/IVarp.h +5 -1
  147. hikyuu/include/hikyuu/indicator/imp/IVigor.h +0 -2
  148. hikyuu/include/hikyuu/indicator/imp/IWma.h +5 -1
  149. hikyuu/include/hikyuu/indicator/imp/IZongGuBen.h +1 -2
  150. hikyuu/include/hikyuu/indicator_talib/imp/TaAdosc.h +0 -2
  151. hikyuu/include/hikyuu/indicator_talib/imp/TaSar.h +0 -2
  152. hikyuu/include/hikyuu/indicator_talib/imp/TaSarext.h +0 -4
  153. hikyuu/include/hikyuu/indicator_talib/imp/TaStoch.h +0 -3
  154. hikyuu/include/hikyuu/indicator_talib/imp/TaStochf.h +0 -2
  155. hikyuu/include/hikyuu/indicator_talib/imp/TaUltosc.h +0 -2
  156. hikyuu/include/hikyuu/indicator_talib/imp/ta_defines.h +2 -4
  157. hikyuu/include/hikyuu/indicator_talib/imp/ta_imp.h +70 -90
  158. hikyuu/include/hikyuu/plugin/hkuextra.h +2 -0
  159. hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +2 -0
  160. hikyuu/include/hikyuu/python/pybind_utils.h +22 -5
  161. hikyuu/include/hikyuu/trade_manage/TradeCostBase.h +5 -3
  162. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +9 -2
  163. hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +8 -3
  164. hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +5 -2
  165. hikyuu/include/hikyuu/trade_sys/environment/EnvironmentBase.h +6 -2
  166. hikyuu/include/hikyuu/trade_sys/moneymanager/MoneyManagerBase.h +5 -2
  167. hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +23 -19
  168. hikyuu/include/hikyuu/trade_sys/multifactor/NormalizeBase.h +6 -3
  169. hikyuu/include/hikyuu/trade_sys/multifactor/ScoresFilterBase.h +5 -2
  170. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h +3 -3
  171. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h +4 -4
  172. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h +4 -4
  173. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_Weight.h +4 -4
  174. hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +5 -2
  175. hikyuu/include/hikyuu/trade_sys/profitgoal/ProfitGoalBase.h +4 -2
  176. hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +12 -2
  177. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h +1 -1
  178. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_MultiFactor2.h +1 -1
  179. hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector.h +1 -0
  180. hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector2.h +1 -0
  181. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +0 -2
  182. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/PerformanceOptimalSelector.h +0 -4
  183. hikyuu/include/hikyuu/trade_sys/signal/SignalBase.h +5 -2
  184. hikyuu/include/hikyuu/trade_sys/slippage/SlippageBase.h +5 -2
  185. hikyuu/include/hikyuu/trade_sys/stoploss/StoplossBase.h +5 -2
  186. hikyuu/include/hikyuu/trade_sys/system/System.h +5 -2
  187. hikyuu/include/hikyuu/utilities/LruCache.h +299 -0
  188. hikyuu/include/hikyuu/utilities/arithmetic.h +2 -2
  189. hikyuu/include/hikyuu/utilities/omp_macro.h +25 -0
  190. hikyuu/include/hikyuu/utilities/plugin/PluginManager.h +5 -0
  191. hikyuu/include/hikyuu/utilities/thread/GlobalStealThreadPool.h +72 -19
  192. hikyuu/include/hikyuu/utilities/thread/GlobalThreadPool.h +0 -4
  193. hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +0 -4
  194. hikyuu/include/hikyuu/utilities/thread/algorithm.h +286 -0
  195. hikyuu/include/hikyuu/version.h +4 -4
  196. hikyuu/plugin/backtest.dll +0 -0
  197. hikyuu/plugin/checkdata.dll +0 -0
  198. hikyuu/plugin/clickhousedriver.dll +0 -0
  199. hikyuu/plugin/dataserver.dll +0 -0
  200. hikyuu/plugin/dataserver_parquet.dll +0 -0
  201. hikyuu/plugin/device.dll +0 -0
  202. hikyuu/plugin/extind.dll +0 -0
  203. hikyuu/plugin/hkuextra.dll +0 -0
  204. hikyuu/plugin/import2ch.dll +0 -0
  205. hikyuu/plugin/import2hdf5.dll +0 -0
  206. hikyuu/plugin/import2mysql.dll +0 -0
  207. hikyuu/plugin/tmreport.dll +0 -0
  208. hikyuu/test/Indicator.py +1 -2
  209. hikyuu/trade_manage/__init__.pyi +6 -5
  210. hikyuu/trade_manage/trade.pyi +6 -5
  211. hikyuu/util/__init__.pyi +1 -1
  212. hikyuu/util/singleton.pyi +1 -1
  213. {hikyuu-2.7.3.dist-info → hikyuu-2.7.5.dist-info}/METADATA +2 -13
  214. {hikyuu-2.7.3.dist-info → hikyuu-2.7.5.dist-info}/RECORD +217 -210
  215. {hikyuu-2.7.3.dist-info → hikyuu-2.7.5.dist-info}/WHEEL +1 -1
  216. {hikyuu-2.7.3.dist-info → hikyuu-2.7.5.dist-info}/entry_points.txt +0 -0
  217. {hikyuu-2.7.3.dist-info → hikyuu-2.7.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,299 @@
1
+ /*
2
+ * Copyright (c) 2026 hikyuu.org
3
+ *
4
+ * Created on: 2026-01-18
5
+ * Author: fasiondog
6
+ */
7
+
8
+ #pragma once
9
+ #include <unordered_map>
10
+ #include <list>
11
+ #include <mutex>
12
+ #include <shared_mutex>
13
+ #include <atomic>
14
+ #include <optional>
15
+
16
+ namespace hku {
17
+
18
+ class NullLock {
19
+ public:
20
+ void lock() noexcept {}
21
+ void unlock() noexcept {}
22
+ bool try_lock() noexcept {
23
+ return true;
24
+ }
25
+ void lock_shared() noexcept {}
26
+ void unlock_shared() noexcept {}
27
+ bool try_lock_shared() noexcept {
28
+ return true;
29
+ }
30
+ };
31
+
32
+ /**
33
+ * @brief LRU (Least Recently Used)
34
+ * 缓存实现(非严格意义LRU以便提升并发读取性能)
35
+ * @tparam KeyType 键的类型,必须支持哈希和相等比较
36
+ * @tparam ValueType 值的类型,必须支持拷贝和移动操作
37
+ */
38
+ template <typename KeyType, typename ValueType, class Lock = NullLock>
39
+ class LruCache final {
40
+ public:
41
+ using key_type = KeyType;
42
+ using value_type = ValueType;
43
+ using size_type = size_t;
44
+ typedef Lock lock_type;
45
+ using UniqueGuard = std::unique_lock<lock_type>;
46
+ using SharedGuard = std::shared_lock<lock_type>;
47
+
48
+ // 存储结构:值 + 原子脏标记(标记是否被get访问过,需要更新LRU顺序)
49
+ using CacheValue = std::pair<value_type, std::atomic<bool>>;
50
+ using LruList = std::list<key_type>;
51
+ using CacheMap =
52
+ std::unordered_map<key_type, std::pair<typename LruList::iterator, CacheValue>>;
53
+
54
+ /**
55
+ * @brief 构造函数
56
+ * @param capacity 缓存容量,默认为64,0表示无限制容量
57
+ * @param overflow 溢出容量,默认为8,允许缓存临时超出设定容量
58
+ * 仅当缓存大小 >= 容量+溢出容量时才触发淘汰机制
59
+ */
60
+ explicit LruCache(size_type capacity = 64, size_type overflow = 8)
61
+ : m_capacity(capacity), m_overflow(overflow) {}
62
+
63
+ ~LruCache() {
64
+ UniqueGuard lock(m_mutex);
65
+ m_cache.clear();
66
+ m_lru_list.clear();
67
+ }
68
+
69
+ /**
70
+ * @brief 插入键值对
71
+ * @param key 键
72
+ * @param value 值
73
+ */
74
+ void insert(const key_type& key, const value_type& value) {
75
+ UniqueGuard lock(m_mutex);
76
+ _batch_update_dirty_nodes();
77
+ auto it = m_cache.find(key);
78
+ if (it != m_cache.end()) {
79
+ it->second.second.first = value;
80
+ it->second.second.second.store(false, std::memory_order_relaxed);
81
+ m_lru_list.splice(m_lru_list.begin(), m_lru_list, it->second.first);
82
+ } else {
83
+ m_lru_list.emplace_front(key);
84
+ m_cache.emplace(key, std::make_pair(m_lru_list.begin(),
85
+ std::make_pair(value, false) // 初始脏标记为false
86
+ ));
87
+ _prune_if_needed();
88
+ }
89
+ }
90
+
91
+ /**
92
+ * @brief 插入键值对(移动版本)
93
+ * @param key 键
94
+ * @param value 值(右值引用)
95
+ */
96
+ void insert(const key_type& key, value_type&& value) {
97
+ UniqueGuard lock(m_mutex);
98
+ _batch_update_dirty_nodes();
99
+ auto it = m_cache.find(key);
100
+ if (it != m_cache.end()) {
101
+ it->second.second.first = std::move(value);
102
+ it->second.second.second.store(false, std::memory_order_relaxed);
103
+ m_lru_list.splice(m_lru_list.begin(), m_lru_list, it->second.first);
104
+ } else {
105
+ m_lru_list.emplace_front(key);
106
+ m_cache.emplace(
107
+ key, std::make_pair(m_lru_list.begin(), std::make_pair(std::move(value), false)));
108
+ _prune_if_needed();
109
+ }
110
+ }
111
+
112
+ /**
113
+ * @brief 获取键对应的值
114
+ * @param key 键
115
+ * @return 存在则返回值,否则返回ValueType的默认构造值
116
+ */
117
+ value_type get(const key_type& key) {
118
+ SharedGuard lock(m_mutex);
119
+ auto it = m_cache.find(key);
120
+ if (it != m_cache.end()) {
121
+ it->second.second.second.store(true, std::memory_order_relaxed);
122
+ return it->second.second.first;
123
+ }
124
+ return value_type{};
125
+ }
126
+
127
+ /**
128
+ * @brief 尝试获取键对应的值
129
+ * @param key 键
130
+ * @param value 用于接收值的引用参数
131
+ * @return 如果键存在返回true,否则返回false
132
+ */
133
+ bool tryGet(const key_type& key, value_type& value) {
134
+ SharedGuard lock(m_mutex);
135
+ auto it = m_cache.find(key);
136
+ if (it != m_cache.end()) {
137
+ it->second.second.second.store(true, std::memory_order_relaxed);
138
+ value = it->second.second.first;
139
+ return true;
140
+ }
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * @brief 检查是否包含指定键
146
+ * @param key 键
147
+ * @return 存在返回true,否则返回false
148
+ */
149
+ bool contains(const key_type& key) {
150
+ SharedGuard lock(m_mutex);
151
+ return m_cache.find(key) != m_cache.end();
152
+ }
153
+
154
+ /**
155
+ * @brief 删除指定键
156
+ * @param key 要删除的键
157
+ * @return 成功删除返回true,不存在返回false
158
+ */
159
+ bool remove(const key_type& key) {
160
+ UniqueGuard lock(m_mutex);
161
+ auto it = m_cache.find(key);
162
+ if (it != m_cache.end()) {
163
+ m_lru_list.erase(it->second.first);
164
+ m_cache.erase(it);
165
+ return true;
166
+ }
167
+ return false;
168
+ }
169
+
170
+ /**
171
+ * @brief 清空缓存
172
+ */
173
+ void clear() {
174
+ UniqueGuard lock(m_mutex);
175
+ m_cache.clear();
176
+ m_lru_list.clear();
177
+ }
178
+
179
+ /**
180
+ * @brief 获取缓存当前大小
181
+ * @return 当前缓存元素数量
182
+ */
183
+ size_type size() const {
184
+ SharedGuard lock(m_mutex);
185
+ return m_cache.size();
186
+ }
187
+
188
+ /**
189
+ * @brief 检查缓存是否为空
190
+ * @return 空返回true,否则返回false
191
+ */
192
+ bool empty() const {
193
+ SharedGuard lock(m_mutex);
194
+ return m_cache.empty();
195
+ }
196
+
197
+ /**
198
+ * @brief 获取缓存容量
199
+ * @return 缓存容量
200
+ */
201
+ size_type capacity() const {
202
+ SharedGuard lock(m_mutex);
203
+ return m_capacity;
204
+ }
205
+
206
+ /**
207
+ * @brief 获取缓存溢出容量
208
+ * @return 缓存溢出容量
209
+ */
210
+ size_type overflow() const {
211
+ SharedGuard lock(m_mutex);
212
+ return m_overflow;
213
+ }
214
+
215
+ /**
216
+ * @brief 设置缓存容量
217
+ * @param capacity 新的容量,0表示不限制容量
218
+ */
219
+ void resize(size_type capacity) {
220
+ UniqueGuard lock(m_mutex);
221
+ m_capacity = capacity;
222
+ _prune_if_needed();
223
+ }
224
+
225
+ /**
226
+ * @brief 设置缓存溢出容量
227
+ * @param overflow 新的溢出容量
228
+ */
229
+ void setOverflow(size_type overflow) {
230
+ UniqueGuard lock(m_mutex);
231
+ m_overflow = overflow;
232
+ _prune_if_needed();
233
+ }
234
+
235
+ private:
236
+ // 如果缓存已满,移除最久未使用的项
237
+ size_t _prune_if_needed() {
238
+ size_t maxAllowed = m_capacity + m_overflow;
239
+ if (m_capacity == 0 || m_cache.size() <= maxAllowed) {
240
+ return 0;
241
+ }
242
+ size_t count = 0;
243
+ while (m_cache.size() > m_capacity) {
244
+ m_cache.erase(m_lru_list.back());
245
+ m_lru_list.pop_back();
246
+ ++count;
247
+ }
248
+ return count;
249
+ }
250
+
251
+ // 批量更新所有脏节点:移到链表头部,清除脏标记
252
+ void _batch_update_dirty_nodes() {
253
+ // 修复点1:避免默认构造,改用指针/引用追踪最新脏节点
254
+ typename LruList::reverse_iterator latest_dirty_it;
255
+ bool has_dirty = false;
256
+
257
+ // 反向遍历链表:从尾部→头部,找第一个脏节点(最新访问的节点)
258
+ for (auto it = m_lru_list.rbegin(); it != m_lru_list.rend(); ++it) {
259
+ const key_type& key = *it;
260
+ auto cache_it = m_cache.find(key);
261
+ if (cache_it == m_cache.end()) {
262
+ continue;
263
+ }
264
+
265
+ auto& dirty_flag = cache_it->second.second.second;
266
+ // 修复点2:原子加载判断,避免未初始化访问
267
+ if (dirty_flag.load(std::memory_order_relaxed)) {
268
+ latest_dirty_it = it;
269
+ has_dirty = true;
270
+ break; // 仅处理最新访问的脏节点,保留1在尾部
271
+ }
272
+ }
273
+
274
+ // 仅移动最新访问的脏节点到头部(修复点3:反向迭代器转正向迭代器)
275
+ if (has_dirty) {
276
+ // C++17:反向迭代器转正向迭代器(base()方法)
277
+ auto forward_it = latest_dirty_it.base();
278
+ --forward_it; // 反向迭代器base()返回的是下一个正向迭代器,需减1
279
+
280
+ const key_type& key = *forward_it;
281
+ auto cache_it = m_cache.find(key);
282
+ if (cache_it != m_cache.end()) {
283
+ // 清除脏标记
284
+ cache_it->second.second.second.store(false, std::memory_order_relaxed);
285
+ // 移动节点到链表头部(splice仅支持正向迭代器)
286
+ m_lru_list.splice(m_lru_list.begin(), m_lru_list, forward_it);
287
+ }
288
+ }
289
+ }
290
+
291
+ private:
292
+ size_type m_capacity;
293
+ size_type m_overflow;
294
+ LruList m_lru_list;
295
+ CacheMap m_cache;
296
+ mutable lock_type m_mutex;
297
+ };
298
+
299
+ } // namespace hku
@@ -209,12 +209,12 @@ extern template float HKU_UTILS_API roundDown(float number, int ndigits);
209
209
  #endif
210
210
 
211
211
  /** 转小写字符串 */
212
- inline void to_lower(std::string &s) {
212
+ inline void to_lower(std::string &s) noexcept {
213
213
  std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
214
214
  }
215
215
 
216
216
  /** 转大写字符串 */
217
- inline void to_upper(std::string &s) {
217
+ inline void to_upper(std::string &s) noexcept {
218
218
  std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); });
219
219
  }
220
220
 
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright (c) 2026 hikyuu.org
3
+ *
4
+ * Created on: 2026-01-16
5
+ * Author: fasiondog
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "hikyuu/utilities/config.h"
11
+
12
+ #if defined(_OPENMP)
13
+ #include <omp.h>
14
+ #define HKU_OMP_PARALLEL_FOR _Pragma("omp parallel for")
15
+ #define HKU_OMP_SAFETY_PARALLEL_FOR \
16
+ _Pragma("omp parallel for num_threads(omp_get_max_threads()) if (!omp_in_parallel())")
17
+ #define HKU_OMP_CHECK_THRESHOLD(guard, threshold) \
18
+ if ((guard) > (threshold) && !omp_in_parallel()) { \
19
+ omp_set_num_threads(omp_get_max_threads()); \
20
+ }
21
+ #else
22
+ #define HKU_OMP_PARALLEL_FOR
23
+ #define HKU_OMP_SAFETY_PARALLEL_FOR
24
+ #define HKU_OMP_CHECK_THRESHOLD(guard, threshold)
25
+ #endif
@@ -37,6 +37,11 @@ public:
37
37
  m_plugin_path = plugin_path;
38
38
  }
39
39
 
40
+ void clear() noexcept {
41
+ std::unique_lock<std::shared_mutex> write_lock(m_mutex);
42
+ m_plugins.clear();
43
+ }
44
+
40
45
  template <typename PluginInterfaceT>
41
46
  PluginInterfaceT* getPlugin(const std::string& pluginname) noexcept {
42
47
  PluginInterfaceT* ret{nullptr};
@@ -8,8 +8,6 @@
8
8
  */
9
9
 
10
10
  #pragma once
11
- #ifndef HIKYUU_UTILITIES_THREAD_STEALTHREADPOOL_H
12
- #define HIKYUU_UTILITIES_THREAD_STEALTHREADPOOL_H
13
11
 
14
12
  #include <future>
15
13
  #include <thread>
@@ -65,7 +63,7 @@ public:
65
63
  m_threads.emplace_back(&GlobalStealThreadPool::worker_thread, this, i);
66
64
  }
67
65
  } catch (...) {
68
- m_done = true;
66
+ m_done.store(true, std::memory_order_release);
69
67
  throw;
70
68
  }
71
69
  }
@@ -74,7 +72,7 @@ public:
74
72
  * 析构函数,等待并阻塞至线程池内所有任务完成
75
73
  */
76
74
  ~GlobalStealThreadPool() {
77
- if (!m_done) {
75
+ if (!m_done.load(std::memory_order_acquire)) {
78
76
  join();
79
77
  }
80
78
  }
@@ -86,7 +84,7 @@ public:
86
84
 
87
85
  /** 剩余任务数 */
88
86
  size_t remain_task_count() const {
89
- if (m_done) {
87
+ if (m_done.load(std::memory_order_acquire)) {
90
88
  return 0;
91
89
  }
92
90
  size_t total = m_master_work_queue.size();
@@ -108,7 +106,7 @@ public:
108
106
  /** 向线程池提交任务 */
109
107
  template <typename FunctionType>
110
108
  auto submit(FunctionType f) {
111
- if (m_thread_need_stop.isSet() || m_done) {
109
+ if (m_thread_need_stop.isSet() || m_done.load(std::memory_order_acquire)) {
112
110
  throw std::logic_error(
113
111
  "You can't submit a task to the stopped GlobalStealThreadPool!!");
114
112
  }
@@ -116,13 +114,16 @@ public:
116
114
  typedef typename std::invoke_result<FunctionType>::type result_type;
117
115
  std::packaged_task<result_type()> task(f);
118
116
  task_handle<result_type> res(task.get_future());
119
- if (m_local_work_queue) {
117
+
118
+ std::thread::id id = std::this_thread::get_id();
119
+ if (m_local_work_queue && id == m_thread_id) {
120
120
  // 本地线程任务从前部入队列(递归成栈)
121
121
  m_local_work_queue->push_front(std::move(task));
122
122
  } else {
123
123
  m_master_work_queue.push(std::move(task));
124
124
  m_cv.notify_one();
125
125
  }
126
+
126
127
  return res;
127
128
  }
128
129
 
@@ -132,19 +133,17 @@ public:
132
133
 
133
134
  /** 返回线程池结束状态 */
134
135
  bool done() const {
135
- return m_done;
136
+ return m_done.load(std::memory_order_acquire);
136
137
  }
137
138
 
138
139
  /**
139
140
  * 等待各线程完成当前执行的任务后立即结束退出
140
141
  */
141
142
  void stop() {
142
- if (m_done) {
143
+ if (m_done.exchange(true, std::memory_order_acq_rel)) {
143
144
  return;
144
145
  }
145
146
 
146
- m_done = true;
147
-
148
147
  // 同时加入结束任务指示,以便在dll退出时也能够终止
149
148
  for (size_t i = 0; i < m_worker_num; i++) {
150
149
  if (m_interrupt_flags[i]) {
@@ -164,6 +163,7 @@ public:
164
163
  for (size_t i = 0; i < m_worker_num; i++) {
165
164
  m_queues[i]->clear();
166
165
  }
166
+ m_threads.clear();
167
167
  }
168
168
 
169
169
  /**
@@ -171,7 +171,7 @@ public:
171
171
  * @note 至此线程池能工作线程结束不可再使用
172
172
  */
173
173
  void join() {
174
- if (m_done) {
174
+ if (m_done.load(std::memory_order_acquire)) {
175
175
  return;
176
176
  }
177
177
 
@@ -196,7 +196,7 @@ public:
196
196
  }
197
197
  }
198
198
 
199
- m_done = true;
199
+ m_done.store(true, std::memory_order_release);
200
200
  for (size_t i = 0; i < m_worker_num; i++) {
201
201
  if (m_interrupt_flags[i]) {
202
202
  m_interrupt_flags[i]->set();
@@ -218,11 +218,46 @@ public:
218
218
  }
219
219
  }
220
220
 
221
- m_done = true;
221
+ m_done.store(true, std::memory_order_release);
222
222
  m_master_work_queue.clear();
223
223
  for (size_t i = 0; i < m_worker_num; i++) {
224
224
  m_queues[i]->clear();
225
225
  }
226
+ m_threads.clear();
227
+ }
228
+
229
+ public:
230
+ bool run_available_task_once() {
231
+ bool task_run = true;
232
+ task_type task;
233
+ if (m_local_work_queue) {
234
+ if (pop_task_from_local_queue(task)) {
235
+ if (!task.isNullTask()) {
236
+ task();
237
+ } else {
238
+ m_thread_need_stop.set();
239
+ }
240
+ } else if (pop_task_from_master_queue(task)) {
241
+ if (!task.isNullTask()) {
242
+ task();
243
+ } else {
244
+ m_thread_need_stop.set();
245
+ }
246
+ } else if (pop_task_from_other_thread_queue(task)) {
247
+ if (!task.isNullTask()) {
248
+ task();
249
+ }
250
+ } else {
251
+ task_run = false;
252
+ }
253
+ } else if (pop_task_from_master_queue(task)) {
254
+ if (!task.isNullTask()) {
255
+ task();
256
+ }
257
+ } else {
258
+ task_run = false;
259
+ }
260
+ return task_run;
226
261
  }
227
262
 
228
263
  private:
@@ -243,17 +278,20 @@ private:
243
278
  inline static thread_local WorkStealQueue* m_local_work_queue = nullptr; // 本地任务队列
244
279
  inline static thread_local int m_index = -1; // 在线程池中的序号
245
280
  inline static thread_local InterruptFlag m_thread_need_stop; // 线程停止运行指示
281
+ inline static thread_local std::thread::id m_thread_id;
246
282
  #else
247
283
  static thread_local WorkStealQueue* m_local_work_queue; // 本地任务队列
248
284
  static thread_local int m_index; // 在线程池中的序号
249
285
  static thread_local InterruptFlag m_thread_need_stop; // 线程停止运行指示
286
+ static thread_local std::thread::id m_thread_id;
250
287
  #endif
251
288
 
252
289
  void worker_thread(int index) {
290
+ m_thread_id = std::this_thread::get_id();
253
291
  m_interrupt_flags[index] = &m_thread_need_stop;
254
292
  m_index = index;
255
293
  m_local_work_queue = m_queues[index].get();
256
- while (!m_thread_need_stop.isSet() && !m_done) {
294
+ while (!m_thread_need_stop.isSet() && !m_done.load(std::memory_order_acquire)) {
257
295
  run_pending_task();
258
296
  }
259
297
  m_local_work_queue = nullptr;
@@ -277,10 +315,18 @@ private:
277
315
  m_thread_need_stop.set();
278
316
  }
279
317
  } else if (pop_task_from_other_thread_queue(task)) {
280
- task();
318
+ if (!task.isNullTask()) {
319
+ task();
320
+ }
281
321
  } else {
322
+ // std::this_thread::yield();
282
323
  std::unique_lock<std::mutex> lk(m_cv_mutex);
283
- m_cv.wait(lk, [this] { return this->m_done || !this->m_master_work_queue.empty(); });
324
+ m_cv.wait_for(lk, std::chrono::microseconds(10), [this] {
325
+ return this->m_done.load(std::memory_order_acquire) ||
326
+ !this->m_master_work_queue.empty() ||
327
+ (m_local_work_queue && !m_local_work_queue->empty()) ||
328
+ has_other_remain_task();
329
+ });
284
330
  }
285
331
  }
286
332
 
@@ -302,8 +348,15 @@ private:
302
348
  }
303
349
  return false;
304
350
  }
351
+
352
+ bool has_other_remain_task() {
353
+ for (int i = 0; i < m_worker_num; ++i) {
354
+ if (i != m_index && m_queues[i] && !m_queues[i]->empty()) {
355
+ return true;
356
+ }
357
+ }
358
+ return false;
359
+ }
305
360
  };
306
361
 
307
362
  } /* namespace hku */
308
-
309
- #endif /* HIKYUU_UTILITIES_THREAD_STEALTHREADPOOL_H */
@@ -8,8 +8,6 @@
8
8
  */
9
9
 
10
10
  #pragma once
11
- #ifndef HIKYUU_UTILITIES_THREAD_THREADPOOL_H
12
- #define HIKYUU_UTILITIES_THREAD_THREADPOOL_H
13
11
 
14
12
  #include <cstdio>
15
13
  #include <future>
@@ -220,5 +218,3 @@ private:
220
218
  #ifdef __GNUC__
221
219
  #pragma GCC diagnostic pop
222
220
  #endif
223
-
224
- #endif /* HIKYUU_UTILITIES_THREAD_THREADPOOL_H */
@@ -8,8 +8,6 @@
8
8
  */
9
9
 
10
10
  #pragma once
11
- #ifndef HIKYUU_UTILITIES_THREAD_THREADPOOL_H
12
- #define HIKYUU_UTILITIES_THREAD_THREADPOOL_H
13
11
 
14
12
  #include <cstdio>
15
13
  #include <future>
@@ -200,5 +198,3 @@ private:
200
198
  #ifdef __GNUC__
201
199
  #pragma GCC diagnostic pop
202
200
  #endif
203
-
204
- #endif /* HIKYUU_UTILITIES_THREAD_THREADPOOL_H */