hikyuu 2.1.0__cp310-none-win_amd64.whl → 2.1.1__cp310-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 (75) hide show
  1. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  2. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  3. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  4. hikyuu/cpp/core310.pyd +0 -0
  5. hikyuu/cpp/hikyuu.dll +0 -0
  6. hikyuu/extend.py +3 -1
  7. hikyuu/gui/HikyuuTDX.py +11 -6
  8. hikyuu/include/hikyuu/DataType.h +2 -1
  9. hikyuu/include/hikyuu/KRecord.h +1 -1
  10. hikyuu/include/hikyuu/StockManager.h +3 -0
  11. hikyuu/include/hikyuu/analysis/combinate.h +1 -1
  12. hikyuu/include/hikyuu/config.h +0 -12
  13. hikyuu/include/hikyuu/strategy/AccountTradeManager.h +3 -1
  14. hikyuu/include/hikyuu/utilities/FilterNode.h +267 -0
  15. hikyuu/include/hikyuu/utilities/LRUCache11.h +230 -0
  16. hikyuu/include/hikyuu/{Log.h → utilities/Log.h} +91 -113
  17. hikyuu/include/hikyuu/utilities/Null.h +1 -0
  18. hikyuu/include/hikyuu/utilities/Parameter.h +2 -1
  19. hikyuu/include/hikyuu/utilities/ResourcePool.h +636 -0
  20. hikyuu/include/hikyuu/utilities/SpendTimer.h +10 -9
  21. hikyuu/include/hikyuu/utilities/TimerManager.h +2 -2
  22. hikyuu/include/hikyuu/utilities/any_to_string.h +142 -0
  23. hikyuu/include/hikyuu/utilities/arithmetic.h +69 -33
  24. hikyuu/include/hikyuu/utilities/base64.h +59 -0
  25. hikyuu/include/hikyuu/utilities/config.h +41 -0
  26. hikyuu/include/hikyuu/utilities/datetime/Datetime.h +41 -31
  27. hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +24 -13
  28. hikyuu/include/hikyuu/utilities/db_connect/DBCondition.h +48 -48
  29. hikyuu/include/hikyuu/utilities/db_connect/DBConnect.h +10 -0
  30. hikyuu/include/hikyuu/utilities/db_connect/DBConnectBase.h +5 -22
  31. hikyuu/include/hikyuu/utilities/db_connect/DBUpgrade.h +3 -3
  32. hikyuu/include/hikyuu/utilities/db_connect/SQLException.h +1 -1
  33. hikyuu/include/hikyuu/utilities/db_connect/SQLResultSet.h +1 -1
  34. hikyuu/include/hikyuu/utilities/db_connect/SQLStatementBase.h +7 -7
  35. hikyuu/include/hikyuu/utilities/db_connect/TableMacro.h +1 -2
  36. hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLConnect.h +9 -9
  37. hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLStatement.h +18 -18
  38. hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteConnect.h +3 -3
  39. hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteStatement.h +2 -2
  40. hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteUtil.h +6 -6
  41. hikyuu/include/hikyuu/{exception.h → utilities/exception.h} +1 -0
  42. hikyuu/include/hikyuu/utilities/http_client/HttpClient.h +229 -0
  43. hikyuu/include/hikyuu/utilities/http_client/nng_wrap.h +517 -0
  44. hikyuu/include/hikyuu/utilities/http_client/url.h +25 -0
  45. hikyuu/include/hikyuu/utilities/{IniParser.h → ini_parser/IniParser.h} +10 -5
  46. hikyuu/include/hikyuu/utilities/ini_parser/__init__.py +1 -0
  47. hikyuu/include/hikyuu/utilities/md5.h +41 -0
  48. hikyuu/include/hikyuu/utilities/mo/__init__.py +1 -0
  49. hikyuu/include/hikyuu/utilities/mo/mo.h +48 -0
  50. hikyuu/include/hikyuu/utilities/mo/moFileReader.h +836 -0
  51. hikyuu/include/hikyuu/{global → utilities}/node/NodeClient.h +25 -18
  52. hikyuu/include/hikyuu/{global → utilities}/node/NodeError.h +1 -1
  53. hikyuu/include/hikyuu/{global → utilities}/node/NodeMessage.h +3 -2
  54. hikyuu/include/hikyuu/utilities/node/NodeServer.h +246 -0
  55. hikyuu/include/hikyuu/utilities/node/__init__.py +1 -0
  56. hikyuu/include/hikyuu/utilities/os.h +16 -15
  57. hikyuu/include/hikyuu/utilities/snowflake.h +110 -0
  58. hikyuu/include/hikyuu/utilities/string_view.h +70 -0
  59. hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +3 -3
  60. hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +3 -3
  61. hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +3 -3
  62. hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +3 -3
  63. hikyuu/include/hikyuu/version.h +4 -4
  64. hikyuu/sqlite3.dll +0 -0
  65. hikyuu/vcruntime140.dll +0 -0
  66. hikyuu/vcruntime140_1.dll +0 -0
  67. hikyuu-2.1.1.dist-info/METADATA +115 -0
  68. {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/RECORD +73 -53
  69. {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/top_level.txt +4 -1
  70. hikyuu/README.rst +0 -79
  71. hikyuu-2.1.0.dist-info/METADATA +0 -126
  72. /hikyuu/include/hikyuu/{global/node → utilities/http_client}/__init__.py +0 -0
  73. {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/LICENSE +0 -0
  74. {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/WHEEL +0 -0
  75. {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,636 @@
1
+ /*
2
+ * ResourcePool.h
3
+ *
4
+ * Copyright (c) 2019, hikyuu.org
5
+ *
6
+ * Created on: 2019-8-5
7
+ * Author: fasiondog
8
+ */
9
+ #pragma once
10
+ #ifndef HKU_UTILS_RESOURCE_POOL_H
11
+ #define HKU_UTILS_RESOURCE_POOL_H
12
+
13
+ #include <thread>
14
+ #include <mutex>
15
+ #include <condition_variable>
16
+ #include <queue>
17
+ #include <chrono>
18
+ #include <unordered_set>
19
+ #include "Parameter.h"
20
+ #include "Log.h"
21
+
22
+ namespace hku {
23
+
24
+ /**
25
+ * 资源获取超时异常
26
+ */
27
+ class GetResourceTimeoutException : public hku::exception {
28
+ public:
29
+ GetResourceTimeoutException(const char *msg)
30
+ : hku::exception(fmt::format("GetResourceTimeoutException {}", msg)) {}
31
+
32
+ GetResourceTimeoutException(const std::string &msg)
33
+ : hku::exception(fmt::format("GetResourceTimeoutException {}", msg)) {}
34
+
35
+ virtual ~GetResourceTimeoutException() {}
36
+ };
37
+
38
+ /**
39
+ * 新资源创建失败异常
40
+ */
41
+ class CreateResourceException : public hku::exception {
42
+ public:
43
+ CreateResourceException(const char *msg)
44
+ : hku::exception(fmt::format("CreateResourceException {}", msg)) {}
45
+
46
+ CreateResourceException(const std::string &msg)
47
+ : hku::exception(fmt::format("CreateResourceException {}", msg)) {}
48
+
49
+ virtual ~CreateResourceException() {}
50
+ };
51
+
52
+ /**
53
+ * 通用共享资源池
54
+ * @ingroup Utilities
55
+ */
56
+ template <typename ResourceType>
57
+ class ResourcePool {
58
+ public:
59
+ ResourcePool() = delete;
60
+ ResourcePool(const ResourcePool &) = delete;
61
+ ResourcePool &operator=(const ResourcePool &) = delete;
62
+
63
+ /**
64
+ * 构造函数
65
+ * @param param 连接参数
66
+ * @param maxPoolSize 允许的最大共享资源数,为 0 表示不限制
67
+ * @param maxIdleNum 运行的最大空闲资源数,为 0 表示用完即刻释放,无缓存
68
+ */
69
+ explicit ResourcePool(const Parameter &param, size_t maxPoolSize = 0, size_t maxIdleNum = 100)
70
+ : m_maxPoolSize(maxPoolSize), m_maxIdelSize(maxIdleNum), m_count(0), m_param(param) {}
71
+
72
+ /**
73
+ * 析构函数,释放所有缓存的资源
74
+ */
75
+ virtual ~ResourcePool() {
76
+ std::unique_lock<std::mutex> lock(m_mutex);
77
+
78
+ // 将所有已分配资源的 closer 和 pool 解绑
79
+ for (auto iter = m_closer_set.begin(); iter != m_closer_set.end(); ++iter) {
80
+ (*iter)->unbind();
81
+ }
82
+
83
+ // 删除所有空闲资源
84
+ while (!m_resourceList.empty()) {
85
+ ResourceType *p = m_resourceList.front();
86
+ m_resourceList.pop();
87
+ if (p) {
88
+ delete p;
89
+ }
90
+ }
91
+ }
92
+
93
+ /** 获取当前允许的最大资源数 */
94
+ size_t maxPoolSize() const {
95
+ return m_maxIdelSize;
96
+ }
97
+
98
+ /** 获取当前允许的最大空闲资源数 */
99
+ size_t maxIdleSize() const {
100
+ return m_maxIdelSize;
101
+ }
102
+
103
+ /** 设置最大资源数 */
104
+ void maxPoolSize(size_t num) {
105
+ std::lock_guard<std::mutex> lock(m_mutex);
106
+ m_maxPoolSize = num;
107
+ }
108
+
109
+ /** 设置允许的最大空闲资源数 */
110
+ void maxIdleSize(size_t num) {
111
+ std::lock_guard<std::mutex> lock(m_mutex);
112
+ m_maxIdelSize = num;
113
+ }
114
+
115
+ /** 资源实例指针类型 */
116
+ typedef std::shared_ptr<ResourceType> ResourcePtr;
117
+
118
+ /**
119
+ * 获取可用资源,如超出允许的最大资源数将返回空指针
120
+ * @exception CreateResourceException 新资源创建可能抛出异常
121
+ */
122
+ ResourcePtr get() {
123
+ std::lock_guard<std::mutex> lock(m_mutex);
124
+ ResourcePtr result;
125
+ ResourceType *p = nullptr;
126
+ if (m_resourceList.empty()) {
127
+ if (m_maxPoolSize > 0 && m_count >= m_maxPoolSize) {
128
+ return result;
129
+ }
130
+ try {
131
+ p = new ResourceType(m_param);
132
+ } catch (const std::exception &e) {
133
+ HKU_THROW_EXCEPTION(CreateResourceException, "Failed create a new Resource! {}",
134
+ e.what());
135
+ } catch (...) {
136
+ HKU_THROW_EXCEPTION(CreateResourceException,
137
+ "Failed create a new Resource! Unknown error!");
138
+ }
139
+ m_count++;
140
+ result = ResourcePtr(p, ResourceCloser(this));
141
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
142
+ return result;
143
+ }
144
+ p = m_resourceList.front();
145
+ m_resourceList.pop();
146
+ result = ResourcePtr(p, ResourceCloser(this));
147
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
148
+ return result;
149
+ }
150
+
151
+ /**
152
+ * 在指定的超时时间内获取可用资源
153
+ * @param ms_timeout 超时时间,单位毫秒
154
+ * @exception GetResourceTimeoutException, CreateResourceException
155
+ */
156
+ ResourcePtr getWaitFor(uint64_t ms_timeout) { // NOSONAR
157
+ std::unique_lock<std::mutex> lock(m_mutex);
158
+ ResourcePtr result;
159
+ ResourceType *p = nullptr;
160
+ if (m_resourceList.empty()) {
161
+ if (m_maxPoolSize > 0 && m_count >= m_maxPoolSize) {
162
+ // HKU_TRACE("超出最大资源数,等待空闲资源");
163
+ if (ms_timeout > 0) {
164
+ if (m_cond.wait_for(lock,
165
+ std::chrono::duration<uint64_t, std::milli>(ms_timeout),
166
+ [&] { return !m_resourceList.empty(); })) {
167
+ HKU_CHECK_THROW(!m_resourceList.empty(), GetResourceTimeoutException,
168
+ "Failed get resource!");
169
+ } else {
170
+ HKU_THROW_EXCEPTION(GetResourceTimeoutException, "Failed get resource!");
171
+ }
172
+ } else {
173
+ m_cond.wait(lock, [this] { return !m_resourceList.empty(); });
174
+ }
175
+ } else {
176
+ try {
177
+ p = new ResourceType(m_param);
178
+ } catch (const std::exception &e) {
179
+ HKU_THROW_EXCEPTION(CreateResourceException, "Failed create a new Resource! {}",
180
+ e.what());
181
+ } catch (...) {
182
+ HKU_THROW_EXCEPTION(CreateResourceException,
183
+ "Failed create a new Resource! Unknown error!");
184
+ }
185
+ m_count++;
186
+ result = ResourcePtr(p, ResourceCloser(this));
187
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
188
+ return result;
189
+ }
190
+ }
191
+ p = m_resourceList.front();
192
+ m_resourceList.pop();
193
+ result = ResourcePtr(p, ResourceCloser(this));
194
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
195
+ return result;
196
+ }
197
+
198
+ /**
199
+ * 获取可用资源,如超出允许的最大资源数,将阻塞等待直到获得空闲资源
200
+ * @exception CreateResourceException 新资源创建可能抛出异常
201
+ */
202
+ ResourcePtr getAndWait() {
203
+ return getWaitFor(0);
204
+ }
205
+
206
+ /** 当前活动的资源数, 即全部资源数(含空闲及被使用的资源) */
207
+ size_t count() const {
208
+ return m_count;
209
+ }
210
+
211
+ /** 当前空闲的资源数 */
212
+ size_t idleCount() const {
213
+ return m_resourceList.size();
214
+ }
215
+
216
+ /** 释放当前所有的空闲资源 */
217
+ void releaseIdleResource() {
218
+ std::lock_guard<std::mutex> lock(m_mutex);
219
+ _releaseIdleResourceNoLock();
220
+ }
221
+
222
+ private:
223
+ void _releaseIdleResourceNoLock() {
224
+ while (!m_resourceList.empty()) {
225
+ ResourceType *p = m_resourceList.front();
226
+ m_resourceList.pop();
227
+ m_count--;
228
+ if (p) {
229
+ delete p;
230
+ }
231
+ }
232
+ }
233
+
234
+ private:
235
+ size_t m_maxPoolSize; // 允许的最大共享资源数
236
+ size_t m_maxIdelSize; // 允许的最大空闲资源数
237
+ size_t m_count; // 当前活动的资源数
238
+ Parameter m_param;
239
+ std::mutex m_mutex;
240
+ std::condition_variable m_cond;
241
+ std::queue<ResourceType *> m_resourceList;
242
+
243
+ class ResourceCloser {
244
+ public:
245
+ explicit ResourceCloser(ResourcePool *pool) : m_pool(pool) { // NOSONAR
246
+ }
247
+
248
+ void operator()(ResourceType *conn) { // NOSONAR
249
+ if (conn) {
250
+ // 如果绑定了 pool,则归还资源;否则删除
251
+ if (m_pool) {
252
+ // HKU_DEBUG("retuan to pool");
253
+ m_pool->returnResource(conn, this);
254
+ } else {
255
+ // HKU_DEBUG("delete resource not in pool");
256
+ delete conn;
257
+ }
258
+ }
259
+ }
260
+
261
+ // 解绑资源池
262
+ void unbind() {
263
+ m_pool = nullptr;
264
+ }
265
+
266
+ private:
267
+ ResourcePool *m_pool;
268
+ };
269
+
270
+ /** 归还至资源池 */
271
+ void returnResource(ResourceType *p, ResourceCloser *closer) {
272
+ std::unique_lock<std::mutex> lock(m_mutex);
273
+ if (p) {
274
+ if (m_resourceList.size() < m_maxIdelSize) {
275
+ m_resourceList.push(p);
276
+ m_cond.notify_all();
277
+ } else {
278
+ delete p;
279
+ m_count--;
280
+ }
281
+ } else {
282
+ m_count--;
283
+ // HKU_WARN("Trying to return an empty pointer!");
284
+ }
285
+ if (closer) {
286
+ m_closer_set.erase(closer); // 移除该 closer
287
+ }
288
+ }
289
+
290
+ std::unordered_set<ResourceCloser *> m_closer_set; // 占用资源的 closer
291
+ };
292
+
293
+ /**
294
+ * @brief 带版本的资源接口,可由需要版本管理的资源继承
295
+ * @details 自带的 getVersion 和 setVerion 方法由 ResourceVersionPool 调用,不建议带有其他用途
296
+ */
297
+ class ResourceWithVersion {
298
+ public:
299
+ /** 默认构造函数 */
300
+ ResourceWithVersion() : m_version(0) {}
301
+
302
+ /** 析构函数 */
303
+ virtual ~ResourceWithVersion() {}
304
+
305
+ /** 获取资源版本 */
306
+ int getVersion() const {
307
+ return m_version;
308
+ }
309
+
310
+ /** 设置资源版本 **/
311
+ void setVersion(int version) {
312
+ m_version = version;
313
+ }
314
+
315
+ protected:
316
+ int m_version;
317
+ };
318
+
319
+ /**
320
+ * 通用版本的共享资源池,当资源池参数变更时,保证新资源使用新参数,老版本的资源再使用完毕后被自动回收
321
+ * @details 要求资源类具备 int getVersion() 和 void setVersion(int) 另个接口函数
322
+ * @ingroup Utilities
323
+ */
324
+ template <typename ResourceType>
325
+ class ResourceVersionPool {
326
+ public:
327
+ ResourceVersionPool() = delete;
328
+ ResourceVersionPool(const ResourceVersionPool &) = delete;
329
+ ResourceVersionPool &operator=(const ResourceVersionPool &) = delete;
330
+
331
+ /**
332
+ * 构造函数
333
+ * @param param 连接参数
334
+ * @param maxPoolSize 允许的最大共享资源数,为 0 表示不限制
335
+ * @param maxIdleNum 运行的最大空闲资源数,为 0 表示用完即刻释放,无缓存
336
+ */
337
+ explicit ResourceVersionPool(const Parameter &param, size_t maxPoolSize = 0,
338
+ size_t maxIdleNum = 100)
339
+ : m_maxPoolSize(maxPoolSize),
340
+ m_maxIdelSize(maxIdleNum),
341
+ m_count(0),
342
+ m_param(param),
343
+ m_version(0) {}
344
+
345
+ /**
346
+ * 析构函数,释放所有缓存的资源
347
+ */
348
+ virtual ~ResourceVersionPool() {
349
+ std::unique_lock<std::mutex> lock(m_mutex);
350
+
351
+ // 将所有已分配资源的 closer 和 pool 解绑
352
+ for (auto iter = m_closer_set.begin(); iter != m_closer_set.end(); ++iter) {
353
+ (*iter)->unbind();
354
+ }
355
+
356
+ // 删除所有空闲资源
357
+ while (!m_resourceList.empty()) {
358
+ ResourceType *p = m_resourceList.front();
359
+ m_resourceList.pop();
360
+ if (p) {
361
+ delete p;
362
+ }
363
+ }
364
+ }
365
+
366
+ /** 获取当前允许的最大资源数 */
367
+ size_t maxPoolSize() const {
368
+ return m_maxIdelSize;
369
+ }
370
+
371
+ /** 获取当前允许的最大空闲资源数 */
372
+ size_t maxIdleSize() const {
373
+ return m_maxIdelSize;
374
+ }
375
+
376
+ /** 设置最大资源数 */
377
+ void maxPoolSize(size_t num) {
378
+ std::lock_guard<std::mutex> lock(m_mutex);
379
+ m_maxPoolSize = num;
380
+ }
381
+
382
+ /** 设置允许的最大空闲资源数 */
383
+ void maxIdleSize(size_t num) {
384
+ std::lock_guard<std::mutex> lock(m_mutex);
385
+ m_maxIdelSize = num;
386
+ }
387
+
388
+ /** 指定参数是否存在 */
389
+ bool haveParam(const std::string &name) {
390
+ std::lock_guard<std::mutex> lock(m_mutex);
391
+ return m_param.have(name);
392
+ }
393
+
394
+ /** 获取指定参数的值,如参数不存在或类型不匹配抛出异常 */
395
+ template <typename ValueType>
396
+ ValueType getParam(const std::string &name) {
397
+ std::lock_guard<std::mutex> lock(m_mutex);
398
+ return m_param.get<ValueType>(name);
399
+ }
400
+
401
+ /**
402
+ * @brief 设定指定参数的值,参数仅在生成新的资源时生效
403
+ * @details 在原本存在该参数的情况下,新设定的值类型须和原有参数类型相同,否则将抛出异常
404
+ * @param name 参数名
405
+ * @param value 参数值
406
+ * @exception std::logic_error
407
+ */
408
+ template <typename ValueType>
409
+ void setParam(const std::string &name, const ValueType &value) {
410
+ std::lock_guard<std::mutex> lock(m_mutex);
411
+ // 如果参数未实际发送变化,则直接返回
412
+ HKU_IF_RETURN(m_param.have(name) && value == m_param.get<ValueType>(name), void());
413
+ m_param.set<ValueType>(name, value);
414
+ m_version++;
415
+ _releaseIdleResourceNoLock(); // 释放当前空闲资源,以便新参数值生效
416
+ }
417
+
418
+ /**
419
+ * @brief 设置资源参数,参数仅在生成新的资源时生效
420
+ * @param param 参数对象
421
+ */
422
+ void setParameter(const Parameter &param) {
423
+ std::lock_guard<std::mutex> lock(m_mutex);
424
+ m_param = param;
425
+ m_version++;
426
+ _releaseIdleResourceNoLock(); // 释放当前空闲资源,以便新参数值生效
427
+ }
428
+
429
+ /**
430
+ * @brief 设置资源参数,参数仅在生成新的资源时生效
431
+ * @param param 参数对象
432
+ */
433
+ void setParameter(Parameter &&param) {
434
+ std::lock_guard<std::mutex> lock(m_mutex);
435
+ m_param = std::move(param);
436
+ m_version++;
437
+ _releaseIdleResourceNoLock(); // 释放当前空闲资源,以便新参数值生效
438
+ }
439
+
440
+ /** 获取当前资源池版本 */
441
+ int getVersion() {
442
+ std::lock_guard<std::mutex> lock(m_mutex);
443
+ return m_version;
444
+ }
445
+
446
+ /** 递增当前资源池版本,相当于通知资源池资源版本发生变化 */
447
+ void incVersion(int version) {
448
+ std::lock_guard<std::mutex> lock(m_mutex);
449
+ m_version++;
450
+ }
451
+
452
+ /** 资源实例指针类型 */
453
+ typedef std::shared_ptr<ResourceType> ResourcePtr;
454
+
455
+ /**
456
+ * 获取可用资源,如超出允许的最大资源数将返回空指针
457
+ * @exception CreateResourceException 新资源创建可能抛出异常
458
+ */
459
+ ResourcePtr get() {
460
+ std::lock_guard<std::mutex> lock(m_mutex);
461
+ ResourcePtr result;
462
+ ResourceType *p = nullptr;
463
+ if (m_resourceList.empty()) {
464
+ if (m_maxPoolSize > 0 && m_count >= m_maxPoolSize) {
465
+ return result;
466
+ }
467
+ try {
468
+ p = new ResourceType(m_param);
469
+ p->setVersion(m_version);
470
+ } catch (const std::exception &e) {
471
+ HKU_THROW_EXCEPTION(CreateResourceException, "Failed create a new Resource! {}",
472
+ e.what());
473
+ } catch (...) {
474
+ HKU_THROW_EXCEPTION(CreateResourceException,
475
+ "Failed create a new Resource! Unknown error!");
476
+ }
477
+ m_count++;
478
+ result = ResourcePtr(p, ResourceCloser(this));
479
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
480
+ return result;
481
+ }
482
+ p = m_resourceList.front();
483
+ m_resourceList.pop();
484
+ result = ResourcePtr(p, ResourceCloser(this));
485
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
486
+ return result;
487
+ }
488
+
489
+ /**
490
+ * 在指定的超时时间内获取可用资源
491
+ * @param ms_timeout 超时时间,单位毫秒
492
+ * @exception GetResourceTimeoutException, CreateResourceException
493
+ */
494
+ ResourcePtr getWaitFor(uint64_t ms_timeout) { // NOSONAR
495
+ std::unique_lock<std::mutex> lock(m_mutex);
496
+ ResourcePtr result;
497
+ ResourceType *p = nullptr;
498
+ if (m_resourceList.empty()) {
499
+ if (m_maxPoolSize > 0 && m_count >= m_maxPoolSize) {
500
+ // HKU_TRACE("超出最大资源数,等待空闲资源");
501
+ if (ms_timeout > 0) {
502
+ if (m_cond.wait_for(lock,
503
+ std::chrono::duration<uint64_t, std::milli>(ms_timeout),
504
+ [&] { return !m_resourceList.empty(); })) {
505
+ HKU_CHECK_THROW(!m_resourceList.empty(), GetResourceTimeoutException,
506
+ "Failed get resource!");
507
+ } else {
508
+ HKU_THROW_EXCEPTION(GetResourceTimeoutException, "Failed get resource!");
509
+ }
510
+ } else {
511
+ m_cond.wait(lock, [this] { return !m_resourceList.empty(); });
512
+ }
513
+ } else {
514
+ try {
515
+ p = new ResourceType(m_param);
516
+ p->setVersion(m_version);
517
+ } catch (const std::exception &e) {
518
+ HKU_THROW_EXCEPTION(CreateResourceException, "Failed create a new Resource! {}",
519
+ e.what());
520
+ } catch (...) {
521
+ HKU_THROW_EXCEPTION(CreateResourceException,
522
+ "Failed create a new Resource! Unknown error!");
523
+ }
524
+ m_count++;
525
+ result = ResourcePtr(p, ResourceCloser(this));
526
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
527
+ return result;
528
+ }
529
+ }
530
+ p = m_resourceList.front();
531
+ m_resourceList.pop();
532
+ result = ResourcePtr(p, ResourceCloser(this));
533
+ m_closer_set.insert(std::get_deleter<ResourceCloser>(result));
534
+ return result;
535
+ }
536
+
537
+ /**
538
+ * 获取可用资源,如超出允许的最大资源数,将阻塞等待直到获得空闲资源
539
+ * @exception CreateResourceException 新资源创建可能抛出异常
540
+ */
541
+ ResourcePtr getAndWait() {
542
+ return getWaitFor(0);
543
+ }
544
+
545
+ /** 当前活动的资源数, 即全部资源数(含空闲及被使用的资源) */
546
+ size_t count() const {
547
+ return m_count;
548
+ }
549
+
550
+ /** 当前空闲的资源数 */
551
+ size_t idleCount() const {
552
+ return m_resourceList.size();
553
+ }
554
+
555
+ /** 释放当前所有的空闲资源 */
556
+ void releaseIdleResource() {
557
+ std::lock_guard<std::mutex> lock(m_mutex);
558
+ _releaseIdleResourceNoLock();
559
+ }
560
+
561
+ private:
562
+ void _releaseIdleResourceNoLock() {
563
+ while (!m_resourceList.empty()) {
564
+ ResourceType *p = m_resourceList.front();
565
+ m_resourceList.pop();
566
+ m_count--;
567
+ if (p) {
568
+ delete p;
569
+ }
570
+ }
571
+ }
572
+
573
+ private:
574
+ size_t m_maxPoolSize; // 允许的最大共享资源数
575
+ size_t m_maxIdelSize; // 允许的最大空闲资源数
576
+ size_t m_count; // 当前活动的资源数
577
+ Parameter m_param;
578
+ std::mutex m_mutex;
579
+ std::condition_variable m_cond;
580
+ std::queue<ResourceType *> m_resourceList;
581
+ int m_version;
582
+
583
+ class ResourceCloser {
584
+ public:
585
+ explicit ResourceCloser(ResourceVersionPool *pool) : m_pool(pool) { // NOSONAR
586
+ }
587
+
588
+ void operator()(ResourceType *conn) { // NOSONAR
589
+ if (conn) {
590
+ // 如果绑定了 pool,则归还资源;否则删除
591
+ if (m_pool) {
592
+ // HKU_DEBUG("retuan to pool");
593
+ m_pool->returnResource(conn, this);
594
+ } else {
595
+ // HKU_DEBUG("delete resource not in pool");
596
+ delete conn;
597
+ }
598
+ }
599
+ }
600
+
601
+ // 解绑资源池
602
+ void unbind() {
603
+ m_pool = nullptr;
604
+ }
605
+
606
+ private:
607
+ ResourceVersionPool *m_pool;
608
+ };
609
+
610
+ /** 归还至资源池 */
611
+ void returnResource(ResourceType *p, ResourceCloser *closer) {
612
+ std::unique_lock<std::mutex> lock(m_mutex);
613
+ if (p) {
614
+ // 当前归还资源的版本和资源池版本相等,且空闲资源列表小于最大空闲资源数时,接受归还的资源
615
+ if (p->getVersion() == m_version && m_resourceList.size() < m_maxIdelSize) {
616
+ m_resourceList.push(p);
617
+ m_cond.notify_all();
618
+ } else {
619
+ delete p;
620
+ m_count--;
621
+ }
622
+ } else {
623
+ m_count--;
624
+ // HKU_WARN("Trying to return an empty pointer!");
625
+ }
626
+ if (closer) {
627
+ m_closer_set.erase(closer); // 移除该 closer
628
+ }
629
+ }
630
+
631
+ std::unordered_set<ResourceCloser *> m_closer_set; // 占用资源的 closer
632
+ };
633
+
634
+ } // namespace hku
635
+
636
+ #endif /* HKU_UTILS_RESOURCE_POOL_H */
@@ -21,9 +21,10 @@
21
21
  #include <chrono>
22
22
  #include <vector>
23
23
  #include <fmt/format.h>
24
+ #include "hikyuu/utilities/config.h"
24
25
 
25
- #ifndef HKU_API
26
- #define HKU_API
26
+ #ifndef HKU_UTILS_API
27
+ #define HKU_UTILS_API
27
28
  #endif
28
29
  #ifdef __ANDROID__
29
30
  #include <android/log.h>
@@ -138,7 +139,7 @@ namespace hku {
138
139
  * @note 不建议直接使用,应使用相关工具宏
139
140
  * @see SPEND_TIME, SPEND_TIME_MSG, SPEND_TIMG_CONTROL
140
141
  */
141
- class HKU_API SpendTimer {
142
+ class HKU_UTILS_API SpendTimer {
142
143
  public:
143
144
  /** 构造函数,记录当前系统时间 */
144
145
  explicit SpendTimer()
@@ -237,19 +238,19 @@ private:
237
238
  std::vector<std::string> m_keep_desc;
238
239
 
239
240
  static bool ms_closed;
240
- friend void HKU_API close_spend_time();
241
- friend void HKU_API open_spend_time();
242
- friend bool HKU_API get_spend_time_status();
241
+ friend void HKU_UTILS_API close_spend_time();
242
+ friend void HKU_UTILS_API open_spend_time();
243
+ friend bool HKU_UTILS_API get_spend_time_status();
243
244
  };
244
245
 
245
246
  /** 全局关闭耗时打印输出 */
246
- void HKU_API close_spend_time();
247
+ void HKU_UTILS_API close_spend_time();
247
248
 
248
249
  /** 全局开启耗时打印输出 */
249
- void HKU_API open_spend_time();
250
+ void HKU_UTILS_API open_spend_time();
250
251
 
251
252
  /** 获取全局耗时打印输出状态:true - 开启,false - 关闭 */
252
- bool HKU_API get_spend_time_status();
253
+ bool HKU_UTILS_API get_spend_time_status();
253
254
 
254
255
  /**
255
256
  * 耗时计时器开启关闭状态看守,记录之前的耗时开关状态,并置为指定状态,释放时恢复原状态
@@ -11,7 +11,7 @@
11
11
  #include <unordered_map>
12
12
  #include <functional>
13
13
  #include "hikyuu/utilities/datetime/Datetime.h"
14
- #include "hikyuu/Log.h"
14
+ #include "hikyuu/utilities/Log.h"
15
15
  #include "thread/ThreadPool.h"
16
16
  #include "cppdef.h"
17
17
 
@@ -399,7 +399,7 @@ private:
399
399
  // 分配 timer_id
400
400
  int getNewTimerId() {
401
401
  int max_int = std::numeric_limits<int>::max();
402
- HKU_WARN_IF_RETURN(m_timers.size() >= max_int, -1, "Timer queue is full!");
402
+ HKU_WARN_IF_RETURN(m_timers.size() >= size_t(max_int), -1, "Timer queue is full!");
403
403
 
404
404
  if (m_current_timer_id >= max_int) {
405
405
  m_current_timer_id = 0;