hikyuu 2.1.0__cp39-none-win_amd64.whl → 2.1.1__cp39-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/core39.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
@@ -7,6 +7,11 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include "hikyuu/utilities/config.h"
11
+ #if !HKU_ENABLE_NODE
12
+ #error "Don't enable node client, please config with --node=y"
13
+ #endif
14
+
10
15
  #include <atomic>
11
16
  #include <nng/nng.h>
12
17
  #include <nng/protocol/reqrep0/req.h>
@@ -59,13 +64,11 @@ public:
59
64
 
60
65
  return true;
61
66
 
67
+ } catch (const std::exception& e) {
68
+ HKU_ERROR_IF(m_show_log, "Failed dail server: {}! {}", m_server_addr, e.what());
62
69
  } catch (...) {
70
+ HKU_ERROR_IF(m_show_log, "Failed dail server: {}! Unknown error!", m_server_addr);
63
71
  }
64
- // } catch (const std::exception& e) {
65
- // HKU_ERROR("Failed dail server: {}! {}", m_server_addr, e.what());
66
- // } catch (...) {
67
- // HKU_ERROR("Failed dail server: {}! Unknown error!", m_server_addr);
68
- // }
69
72
 
70
73
  m_connected = false;
71
74
  nng_close(m_socket);
@@ -101,6 +104,10 @@ public:
101
104
  return _send(req) && _recv(res);
102
105
  }
103
106
 
107
+ void showLog(bool show) {
108
+ m_show_log = show;
109
+ }
110
+
104
111
  private:
105
112
  bool _send(const json& req) const noexcept {
106
113
  bool success = false;
@@ -118,13 +125,11 @@ private:
118
125
  NODE_NNG_CHECK(rv, "Failed nng_sendmsg!");
119
126
  success = true;
120
127
 
128
+ } catch (const std::exception& e) {
129
+ HKU_ERROR_IF(m_show_log, "Failed send result! {}", e.what());
121
130
  } catch (...) {
131
+ HKU_ERROR_IF(m_show_log, "Failed send result! Unknown error!");
122
132
  }
123
- // } catch (const std::exception& e) {
124
- // HKU_ERROR("Failed send result! {}", e.what());
125
- // } catch (...) {
126
- // HKU_ERROR("Failed send result! Unknown error!");
127
- // }
128
133
 
129
134
  if (!success) {
130
135
  nng_msg_free(msg);
@@ -137,21 +142,22 @@ private:
137
142
  bool success = false;
138
143
  nng_msg* msg{nullptr};
139
144
  int rv = nng_recvmsg(m_socket, &msg, 0);
140
- // HKU_ERROR_IF_RETURN(rv != 0, success, "Failed nng_recvmsg! {}", nng_strerror(rv));
141
- HKU_IF_RETURN(rv != 0, success);
145
+ if (rv != 0) {
146
+ HKU_ERROR_IF(m_show_log, "Failed nng_recvmsg! {}", nng_strerror(rv));
147
+ return success;
148
+ }
149
+
142
150
  m_last_ack_time = Datetime::now();
143
151
 
144
152
  try {
145
153
  res = decodeMsg(msg);
146
154
  success = true;
147
155
 
156
+ } catch (const std::exception& e) {
157
+ HKU_ERROR_IF(m_show_log, "Failed recv response! {}", e.what());
148
158
  } catch (...) {
159
+ HKU_ERROR_IF(m_show_log, "Failed recv response! Unknown error!");
149
160
  }
150
- // } catch (const std::exception& e) {
151
- // HKU_ERROR("Failed recv response! {}", e.what());
152
- // } catch (...) {
153
- // HKU_ERROR("Failed recv response! Unknown error!");
154
- // }
155
161
 
156
162
  nng_msg_free(msg);
157
163
  return success;
@@ -161,8 +167,9 @@ private:
161
167
  std::mutex m_mutex;
162
168
  std::string m_server_addr; // 服务端地址
163
169
  nng_socket m_socket;
164
- std::atomic_bool m_connected{false};
165
170
  Datetime m_last_ack_time{Datetime::now()}; // 最后一次接收服务端响应的时间
171
+ std::atomic_bool m_connected{false};
172
+ std::atomic_bool m_show_log{true};
166
173
  };
167
174
 
168
175
  } // namespace hku
@@ -7,7 +7,7 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include "hikyuu/exception.h"
10
+ #include <hikyuu/utilities/exception.h>
11
11
 
12
12
  namespace hku {
13
13
 
@@ -12,6 +12,7 @@
12
12
  #include <vector>
13
13
  #include <nng/nng.h>
14
14
  #include <nlohmann/json.hpp>
15
+ #include <hikyuu/utilities/Log.h>
15
16
  #include "NodeError.h"
16
17
 
17
18
  using json = nlohmann::json;
@@ -26,8 +27,8 @@ namespace hku {
26
27
  * req ->
27
28
  * {"cmd": int, ...}
28
29
  *
29
- * req ->
30
- * {"cmd": int, "ret": code, "msg": str}
30
+ * <- res
31
+ * {"ret": code, "msg": str} // msg 存在错误时返回错误信息 (可选)
31
32
  *
32
33
  *
33
34
  */
@@ -0,0 +1,246 @@
1
+ /*
2
+ * Copyright (c) 2022 hikyuu.org
3
+ *
4
+ * Created on: 2022-04-15
5
+ * Author: fasiondog
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "hikyuu/utilities/config.h"
11
+ #if !HKU_ENABLE_NODE
12
+ #error "Don't enable node server, please config with --node=y"
13
+ #endif
14
+
15
+ #include <string>
16
+ #include <unordered_map>
17
+ #include <nng/nng.h>
18
+ #include <nng/protocol/reqrep0/rep.h>
19
+
20
+ #include <hikyuu/utilities/osdef.h>
21
+ #if HKU_OS_WINDOWS
22
+ #ifndef NOMINMAX
23
+ #define NOMINMAX
24
+ #endif
25
+ #include <WS2tcpip.h>
26
+ #include <Ws2ipdef.h>
27
+ #else
28
+ #include <arpa/inet.h>
29
+ #endif
30
+
31
+ #include "hikyuu/utilities/Log.h"
32
+ #include "NodeMessage.h"
33
+
34
+ namespace hku {
35
+
36
+ class NodeServer {
37
+ CLASS_LOGGER_IMP(NodeServer)
38
+
39
+ public:
40
+ NodeServer() = default;
41
+ explicit NodeServer(const std::string& addr) : m_addr(addr) {}
42
+ virtual ~NodeServer() {
43
+ stop();
44
+ }
45
+
46
+ void setAddr(const std::string& addr) {
47
+ m_addr = addr;
48
+ }
49
+
50
+ void regHandle(const std::string& cmd, const std::function<json(json&& req)>& handle) {
51
+ m_handles[cmd] = handle;
52
+ }
53
+
54
+ void regHandle(const std::string& cmd, std::function<json(json&& req)>&& handle) {
55
+ m_handles[cmd] = std::move(handle);
56
+ }
57
+
58
+ void start(size_t max_parrel = 128) {
59
+ CLS_CHECK(!m_addr.empty(), "You must set NodeServer's addr first!");
60
+
61
+ // 启动 node server
62
+ int rv = nng_rep0_open(&m_socket);
63
+ CLS_CHECK(0 == rv, "Failed open server socket! {}", nng_strerror(rv));
64
+ rv = nng_listen(m_socket, m_addr.c_str(), &m_listener, 0);
65
+ CLS_CHECK(0 == rv, "Failed listen node server socket ({})! {}", m_addr, nng_strerror(rv));
66
+ CLS_TRACE("channel lisenter server: {}", m_addr);
67
+
68
+ m_works.resize(max_parrel);
69
+ for (size_t i = 0, total = m_works.size(); i < total; i++) {
70
+ Work* w = &m_works[i];
71
+ rv = nng_aio_alloc(&w->aio, _serverCallback, w);
72
+ CLS_CHECK(0 == rv, "Failed create work {}! {}", i, nng_strerror(rv));
73
+ rv = nng_ctx_open(&w->ctx, m_socket);
74
+ CLS_CHECK(0 == rv, "Failed open ctx {}! {}", i, nng_strerror(rv));
75
+ w->state = Work::INIT;
76
+ w->server = this;
77
+ }
78
+
79
+ for (size_t i = 0, total = m_works.size(); i < total; i++) {
80
+ _serverCallback(&m_works[i]);
81
+ }
82
+ }
83
+
84
+ void loop() {
85
+ while (true) {
86
+ std::this_thread::sleep_for(std::chrono::seconds(1));
87
+ }
88
+ }
89
+
90
+ void stop() {
91
+ HKU_IF_RETURN(m_works.empty(), void());
92
+ for (size_t i = 0, total = m_works.size(); i < total; i++) {
93
+ Work* w = &m_works[i];
94
+ w->server = nullptr;
95
+ w->state = Work::FINISH;
96
+ if (w->aio) {
97
+ nng_aio_stop(w->aio);
98
+ nng_aio_free(w->aio);
99
+ nng_ctx_close(w->ctx);
100
+ w->aio = nullptr;
101
+ }
102
+ }
103
+
104
+ // 关闭 socket 服务节点
105
+ nng_listener_close(m_listener);
106
+ nng_close(m_socket);
107
+ m_works.clear();
108
+ CLS_INFO("stopped node server.");
109
+ }
110
+
111
+ private:
112
+ struct Work {
113
+ enum { INIT, RECV, SEND, FINISH } state = INIT;
114
+ nng_aio* aio{nullptr};
115
+ nng_ctx ctx;
116
+ NodeServer* server{nullptr};
117
+ };
118
+
119
+ static void _serverCallback(void* arg) {
120
+ Work* work = static_cast<Work*>(arg);
121
+ int rv = 0;
122
+ switch (work->state) {
123
+ case Work::INIT:
124
+ work->state = Work::RECV;
125
+ nng_ctx_recv(work->ctx, work->aio);
126
+ break;
127
+
128
+ case Work::RECV:
129
+ _processRequest(work);
130
+ break;
131
+
132
+ case Work::SEND:
133
+ if ((rv = nng_aio_result(work->aio)) != 0) {
134
+ CLS_FATAL("Failed nng_ctx_send! {}", nng_strerror(rv));
135
+ work->state = Work::FINISH;
136
+ return;
137
+ }
138
+ work->state = Work::RECV;
139
+ nng_ctx_recv(work->ctx, work->aio);
140
+ break;
141
+
142
+ case Work::FINISH:
143
+ break;
144
+
145
+ default:
146
+ CLS_FATAL("nng bad state!");
147
+ break;
148
+ }
149
+ }
150
+
151
+ static void _processRequest(Work* work) {
152
+ NodeServer* server = work->server;
153
+ CLS_IF_RETURN(!server || !work->aio, void());
154
+ nng_msg* msg = nullptr;
155
+ json res;
156
+
157
+ try {
158
+ int rv = nng_aio_result(work->aio);
159
+ HKU_CHECK(rv == 0, "Failed nng_aio_result!");
160
+
161
+ msg = nng_aio_get_msg(work->aio);
162
+ json req = decodeMsg(msg);
163
+ NODE_CHECK(req.contains("cmd"), NodeErrorCode::MISSING_CMD, "Missing command!");
164
+
165
+ // 兼容老版本数字cmd
166
+ std::string cmd = req["cmd"].is_number() ? fmt::format("{}", req["cmd"].get<int>())
167
+ : req["cmd"].get<std::string>();
168
+ auto iter = server->m_handles.find(cmd);
169
+ NODE_CHECK(iter != server->m_handles.end(), NodeErrorCode::INVALID_CMD,
170
+ "The server does not know how to process the message: {}", cmd);
171
+
172
+ // tcp 连接尝试获取客户端地址和端口加入 req 中
173
+ req["remote_host"] = "";
174
+ req["remote_port"] = 0;
175
+ nng_pipe p = nng_msg_get_pipe(msg);
176
+ if (nng_pipe_id(p) > 0) {
177
+ uint16_t port = 0;
178
+ nng_sockaddr ra;
179
+ rv = nng_pipe_get_addr(p, NNG_OPT_REMADDR, &ra);
180
+ if (rv == 0) {
181
+ if (ra.s_family == NNG_AF_INET) {
182
+ char ipAddr[INET_ADDRSTRLEN];
183
+ inet_ntop(AF_INET, (void*)&ra.s_in.sa_addr, ipAddr, INET_ADDRSTRLEN);
184
+ port = ntohs(ra.s_in.sa_port);
185
+ req["remote_host"] = ipAddr;
186
+ req["remote_port"] = port;
187
+ } else if (ra.s_family == NNG_AF_INET6) {
188
+ char ipAddr[INET6_ADDRSTRLEN];
189
+ inet_ntop(AF_INET6, (void*)&ra.s_in.sa_addr, ipAddr, INET6_ADDRSTRLEN);
190
+ port = ntohs(ra.s_in6.sa_port);
191
+ req["remote_host"] = ipAddr;
192
+ req["remote_port"] = port;
193
+ }
194
+ }
195
+ }
196
+
197
+ res = iter->second(std::move(req));
198
+ res["ret"] = NodeErrorCode::SUCCESS;
199
+ encodeMsg(msg, res);
200
+
201
+ nng_aio_set_msg(work->aio, msg);
202
+ work->state = Work::SEND;
203
+ nng_ctx_send(work->ctx, work->aio);
204
+
205
+ } catch (const NodeNngError& e) {
206
+ CLS_FATAL(e.what());
207
+ work->state = Work::FINISH;
208
+
209
+ } catch (const NodeError& e) {
210
+ CLS_ERROR(e.what());
211
+ res["ret"] = e.errcode();
212
+ res["msg"] = e.what();
213
+ encodeMsg(msg, res);
214
+ nng_aio_set_msg(work->aio, msg);
215
+ work->state = Work::SEND;
216
+ nng_ctx_send(work->ctx, work->aio);
217
+
218
+ } catch (const std::exception& e) {
219
+ CLS_ERROR(e.what());
220
+ res["ret"] = NodeErrorCode::UNKNOWN_ERROR;
221
+ res["msg"] = e.what();
222
+ encodeMsg(msg, res);
223
+ nng_aio_set_msg(work->aio, msg);
224
+ work->state = Work::SEND;
225
+ nng_ctx_send(work->ctx, work->aio);
226
+
227
+ } catch (...) {
228
+ std::string errmsg = "Unknown error!";
229
+ CLS_ERROR(errmsg);
230
+ res["ret"] = NodeErrorCode::UNKNOWN_ERROR;
231
+ res["msg"] = errmsg;
232
+ nng_aio_set_msg(work->aio, msg);
233
+ work->state = Work::SEND;
234
+ nng_ctx_send(work->ctx, work->aio);
235
+ }
236
+ }
237
+
238
+ private:
239
+ std::string m_addr;
240
+ nng_socket m_socket;
241
+ nng_listener m_listener;
242
+ std::vector<Work> m_works;
243
+ std::unordered_map<std::string, std::function<json(json&& req)>> m_handles;
244
+ };
245
+
246
+ } // namespace hku
@@ -17,8 +17,8 @@
17
17
  #include "arithmetic.h"
18
18
  #include <cstdint>
19
19
 
20
- #ifndef HKU_API
21
- #define HKU_API
20
+ #ifndef HKU_UTILS_API
21
+ #define HKU_UTILS_API
22
22
  #endif
23
23
 
24
24
  namespace hku {
@@ -27,27 +27,27 @@ namespace hku {
27
27
  * 判断文件或目录是否存在
28
28
  * @param filename 文件名或目录名
29
29
  */
30
- bool HKU_API existFile(const std::string& filename) noexcept;
30
+ bool HKU_UTILS_API existFile(const std::string &filename) noexcept;
31
31
 
32
32
  /**
33
33
  * 创建目录
34
34
  * @param pathname 路径名
35
35
  * @return 如果目录已存在或者创建成功返回 true,否则返回 false
36
36
  */
37
- bool HKU_API createDir(const std::string& pathname) noexcept;
37
+ bool HKU_UTILS_API createDir(const std::string &pathname) noexcept;
38
38
 
39
39
  /**
40
40
  * 删除文件
41
41
  * @param filename 文件名
42
42
  * @return 删除失败或文件不存在时返回false
43
43
  */
44
- bool HKU_API removeFile(const std::string& filename) noexcept;
44
+ bool HKU_UTILS_API removeFile(const std::string &filename) noexcept;
45
45
 
46
46
  /**
47
47
  * 删除目录及其包含的文件和子目录
48
48
  * @param path 待删除目录
49
49
  */
50
- bool HKU_API removeDir(const std::string& path) noexcept;
50
+ bool HKU_UTILS_API removeDir(const std::string &path) noexcept;
51
51
 
52
52
  /**
53
53
  * 拷贝文件
@@ -55,7 +55,8 @@ bool HKU_API removeDir(const std::string& path) noexcept;
55
55
  * @param dst 目标文件
56
56
  * @param flush 是否立即落盘
57
57
  */
58
- bool HKU_API copyFile(const std::string& src, const std::string& dst, bool flush = false) noexcept;
58
+ bool HKU_UTILS_API copyFile(const std::string &src, const std::string &dst,
59
+ bool flush = false) noexcept;
59
60
 
60
61
  /**
61
62
  * 文件、目录改名或移动
@@ -65,23 +66,23 @@ bool HKU_API copyFile(const std::string& src, const std::string& dst, bool flush
65
66
  * @return true 成功
66
67
  * @return false 失败 旧名文件不存在,或文件被占用等其他原因导致的失败
67
68
  */
68
- bool HKU_API renameFile(const std::string& oldname, const std::string& newname,
69
- bool overlay = false) noexcept;
69
+ bool HKU_UTILS_API renameFile(const std::string &oldname, const std::string &newname,
70
+ bool overlay = false) noexcept;
70
71
 
71
72
  /**
72
73
  * 获取用户路径
73
74
  */
74
- std::string HKU_API getUserDir();
75
+ std::string HKU_UTILS_API getUserDir();
75
76
 
76
77
  /**
77
78
  * 获取程序当前所在路径
78
79
  */
79
- std::string HKU_API getCurrentDir();
80
+ std::string HKU_UTILS_API getCurrentDir();
80
81
 
81
82
  /**
82
83
  * 输出终端是否支持彩色控制字符
83
84
  */
84
- bool HKU_API isColorTerminal() noexcept;
85
+ bool HKU_UTILS_API isColorTerminal() noexcept;
85
86
 
86
87
  /**
87
88
  * @brief 获取硬盘剩余存储空间大小
@@ -90,12 +91,12 @@ bool HKU_API isColorTerminal() noexcept;
90
91
  * @param path 指定路径名
91
92
  * @return uint64_t 获取失败时,返回 Null<uint64_t>()
92
93
  */
93
- uint64_t HKU_API getDiskFreeSpace(const char* path);
94
+ uint64_t HKU_UTILS_API getDiskFreeSpace(const char *path);
94
95
 
95
96
  /** 获取当前系统名称 */
96
- std::string HKU_API getPlatform();
97
+ std::string HKU_UTILS_API getPlatform();
97
98
 
98
99
  /** 获取当前CPU架构名称 */
99
- std::string HKU_API getCpuArch();
100
+ std::string HKU_UTILS_API getCpuArch();
100
101
 
101
102
  } // namespace hku
@@ -0,0 +1,110 @@
1
+ /*
2
+ * Copyright(C) 2021 hikyuu.org
3
+ *
4
+ * The code comes from: https://github.com/sniper00/snowflake-cpp
5
+ * Thanks sniper00
6
+ *
7
+ * Create on: 2021-04-13
8
+ * Author: fasiondog
9
+ */
10
+
11
+ #pragma once
12
+
13
+ #include <cstdint>
14
+ #include <chrono>
15
+ #include <stdexcept>
16
+ #include <mutex>
17
+
18
+ namespace hku {
19
+
20
+ class snowflake_nonlock {
21
+ public:
22
+ void lock() {}
23
+ void unlock() {}
24
+ };
25
+
26
+ template <int64_t Twepoch, typename Lock = snowflake_nonlock>
27
+ class snowflake {
28
+ using lock_type = Lock;
29
+ static constexpr int64_t TWEPOCH = Twepoch;
30
+ static constexpr int64_t WORKER_ID_BITS = 5L;
31
+ static constexpr int64_t DATACENTER_ID_BITS = 5L;
32
+ static constexpr int64_t MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;
33
+ static constexpr int64_t MAX_DATACENTER_ID = (1 << DATACENTER_ID_BITS) - 1;
34
+ static constexpr int64_t SEQUENCE_BITS = 12L;
35
+ static constexpr int64_t WORKER_ID_SHIFT = SEQUENCE_BITS;
36
+ static constexpr int64_t DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
37
+ static constexpr int64_t TIMESTAMP_LEFT_SHIFT =
38
+ SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
39
+ static constexpr int64_t SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1;
40
+
41
+ using time_point = std::chrono::time_point<std::chrono::steady_clock>;
42
+
43
+ time_point start_time_point_ = std::chrono::steady_clock::now();
44
+ int64_t start_millsecond_ = std::chrono::duration_cast<std::chrono::milliseconds>(
45
+ std::chrono::system_clock::now().time_since_epoch())
46
+ .count();
47
+
48
+ int64_t last_timestamp_ = -1;
49
+ int64_t workerid_ = 0;
50
+ int64_t datacenterid_ = 0;
51
+ int64_t sequence_ = 0;
52
+ lock_type lock_;
53
+
54
+ public:
55
+ snowflake() = default;
56
+
57
+ snowflake(const snowflake&) = delete;
58
+
59
+ snowflake& operator=(const snowflake&) = delete;
60
+
61
+ void init(int64_t workerid, int64_t datacenterid) {
62
+ std::lock_guard<lock_type> lock(lock_);
63
+ if (workerid > MAX_WORKER_ID || workerid < 0) {
64
+ throw std::runtime_error("worker Id can't be greater than 31 or less than 0");
65
+ }
66
+
67
+ if (datacenterid > MAX_DATACENTER_ID || datacenterid < 0) {
68
+ throw std::runtime_error("datacenter Id can't be greater than 31 or less than 0");
69
+ }
70
+
71
+ workerid_ = workerid;
72
+ datacenterid_ = datacenterid;
73
+ }
74
+
75
+ int64_t nextid() {
76
+ std::lock_guard<lock_type> lock(lock_);
77
+ // std::chrono::steady_clock cannot decrease as physical time moves forward
78
+ auto timestamp = millsecond();
79
+ if (last_timestamp_ == timestamp) {
80
+ sequence_ = (sequence_ + 1) & SEQUENCE_MASK;
81
+ if (sequence_ == 0) {
82
+ timestamp = wait_next_millis(last_timestamp_);
83
+ }
84
+ } else {
85
+ sequence_ = 0;
86
+ }
87
+
88
+ last_timestamp_ = timestamp;
89
+
90
+ return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) |
91
+ (datacenterid_ << DATACENTER_ID_SHIFT) | (workerid_ << WORKER_ID_SHIFT) | sequence_;
92
+ }
93
+
94
+ private:
95
+ int64_t millsecond() const {
96
+ auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
97
+ std::chrono::steady_clock::now() - start_time_point_);
98
+ return start_millsecond_ + diff.count();
99
+ }
100
+
101
+ int64_t wait_next_millis(int64_t last) const {
102
+ auto timestamp = millsecond();
103
+ while (timestamp <= last) {
104
+ timestamp = millsecond();
105
+ }
106
+ return timestamp;
107
+ }
108
+ };
109
+
110
+ } // namespace hku
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Copyright (c) 2019~2021, hikyuu
3
+ *
4
+ * Created on: 2021/12/16
5
+ * Author: fasiondog
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "cppdef.h"
11
+
12
+ #if CPP_STANDARD >= CPP_STANDARD_17
13
+ #include <string>
14
+ #include <string_view>
15
+ namespace hku {
16
+
17
+ using std::string_view;
18
+
19
+ }
20
+
21
+ #else
22
+
23
+ #include <string>
24
+ #include <cstring>
25
+ #include "Log.h"
26
+
27
+ namespace hku {
28
+
29
+ class string_view {
30
+ public:
31
+ constexpr string_view() noexcept = default;
32
+
33
+ string_view(const char *data, std::size_t size) : _data(data), _size(size) {
34
+ HKU_CHECK_THROW(data, std::invalid_argument, "Input null ptr!");
35
+ };
36
+
37
+ string_view(const char *data) : _data(data) { // NOSONAR
38
+ HKU_CHECK_THROW(data, std::invalid_argument, "Input null ptr!");
39
+ _size = std::strlen(data);
40
+ }
41
+
42
+ string_view(const std::string &str) : _data(str.data()), _size(str.size()) {} // NOSONAR
43
+
44
+ constexpr string_view(const string_view &) noexcept = default;
45
+
46
+ string_view &operator=(const string_view &) noexcept = default;
47
+
48
+ constexpr const char &operator[](std::size_t pos) const {
49
+ return _data[pos];
50
+ }
51
+
52
+ constexpr const char *data() const noexcept {
53
+ return _data;
54
+ }
55
+
56
+ constexpr std::size_t size() const noexcept {
57
+ return _size;
58
+ }
59
+
60
+ private:
61
+ constexpr string_view(std::nullptr_t) = delete;
62
+
63
+ private:
64
+ const char *_data = nullptr;
65
+ std::size_t _size = 0;
66
+ };
67
+
68
+ } // namespace hku
69
+
70
+ #endif
@@ -22,8 +22,8 @@
22
22
  #pragma GCC diagnostic push
23
23
  #pragma GCC diagnostic ignored "-Wsign-compare"
24
24
  #endif
25
- #ifndef HKU_API
26
- #define HKU_API
25
+ #ifndef HKU_UTILS_API
26
+ #define HKU_UTILS_API
27
27
  #endif
28
28
 
29
29
  namespace hku {
@@ -35,7 +35,7 @@ namespace hku {
35
35
  #ifdef _MSC_VER
36
36
  class MQStealThreadPool {
37
37
  #else
38
- class HKU_API MQStealThreadPool {
38
+ class HKU_UTILS_API MQStealThreadPool {
39
39
  #endif
40
40
  public:
41
41
  /**
@@ -23,8 +23,8 @@
23
23
  #pragma GCC diagnostic ignored "-Wsign-compare"
24
24
  #endif
25
25
 
26
- #ifndef HKU_API
27
- #define HKU_API
26
+ #ifndef HKU_UTILS_API
27
+ #define HKU_UTILS_API
28
28
  #endif
29
29
 
30
30
  namespace hku {
@@ -38,7 +38,7 @@ namespace hku {
38
38
  #ifdef _MSC_VER
39
39
  class MQThreadPool {
40
40
  #else
41
- class HKU_API MQThreadPool {
41
+ class HKU_UTILS_API MQThreadPool {
42
42
  #endif
43
43
  public:
44
44
  /**