Skip to content

Commit 89a4d92

Browse files
committed
Refine code
1 parent be0a0d4 commit 89a4d92

File tree

5 files changed

+252
-1
lines changed

5 files changed

+252
-1
lines changed

moxt/libc.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "libc.hpp"
22
#include "common.hpp"
3+
#include <atomic>
4+
#include <cstdio>
5+
#include <signal.h>
36

47
#define ANKERL_NANOBENCH_IMPLEMENT
58
#include <nanobench.h>
@@ -36,4 +39,24 @@ SEQ_FUNC int64_t seq_atomic_int64_load(std::atomic<int64_t> *p) {
3639

3740
SEQ_FUNC void seq_atomic_int64_store(std::atomic<int64_t> *p, int64_t i) {
3841
p->store(i);
42+
}
43+
44+
// Define a function pointer type for signal handlers
45+
typedef void (*SignalHandler)(int);
46+
47+
// Exported function to register a custom signal handler
48+
// Parameters:
49+
// signum: The signal number to catch
50+
// handler: The custom signal handler function to be called when the signal is
51+
// received
52+
SEQ_FUNC void seq_register_signal_handler(int signum, SignalHandler handler) {
53+
struct sigaction sigAction;
54+
sigemptyset(&sigAction.sa_mask);
55+
sigAction.sa_flags = 0;
56+
sigAction.sa_handler = handler;
57+
58+
if (sigaction(signum, &sigAction, NULL) == -1) {
59+
perror("sigaction");
60+
exit(EXIT_FAILURE);
61+
}
3962
}

moxt/libmisc.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <openssl/err.h>
3131
#include <openssl/opensslv.h>
3232
// #include <snmalloc/override/new.cc>
33+
#include "moxt/utils/snowflake.hpp"
3334
#include <atomic>
3435
#include <parallel_hashmap/phmap.h>
3536
#include <snmalloc/snmalloc.h>
@@ -208,6 +209,16 @@ SEQ_FUNC size_t seq_nanoid(char *result) {
208209
return n;
209210
}
210211

212+
Snowflake &GetSnowflakeInstance() {
213+
static Snowflake inst = [] {
214+
Snowflake::initWorkerId();
215+
return Snowflake();
216+
}();
217+
return inst;
218+
}
219+
220+
SEQ_FUNC int64_t seq_snowflake_id() { return GetSnowflakeInstance().getId(); }
221+
211222
// 存储全局对象地址值
212223
static std::unordered_map<int64_t, int64_t> globalIntMap;
213224

moxt/libsonic.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ SEQ_FUNC void seq_sonic_json_document_add_string(
7070
const char *key, size_t keyLen, const char *value, size_t valueLen) {
7171
auto key_ = std::string_view(key, keyLen);
7272
auto value_ = std::string_view(value, valueLen);
73-
logd("key={} value={}", key_, value_);
7473
doc->AddMember(key_, NodeType(value_), *alloc);
7574
}
7675

@@ -155,6 +154,69 @@ SEQ_FUNC void seq_sonic_json_document_add_bool_array(
155154
doc->AddMember(key_, nodeArgs, *alloc);
156155
}
157156

157+
SEQ_FUNC void seq_sonic_json_document_add_node(
158+
sonic_json::Document *doc, sonic_json::Document::Allocator *alloc,
159+
const char *key, size_t keyLen, NodeType *node) {
160+
auto key_ = std::string_view(key, keyLen);
161+
doc->AddMember(key_, *node, *alloc);
162+
}
163+
164+
SEQ_FUNC NodeType *
165+
seq_sonic_json_document_find_member(sonic_json::Document *doc,
166+
sonic_json::Document::Allocator *alloc,
167+
const char *key, size_t keyLen) {
168+
auto key_ = std::string_view(key, keyLen);
169+
auto m = doc->FindMember(key_);
170+
if (m == doc->MemberEnd()) {
171+
return nullptr;
172+
} else {
173+
return &m->value;
174+
}
175+
}
176+
177+
SEQ_FUNC NodeType *seq_sonic_json_node_new() {
178+
auto *node = new NodeType();
179+
return node;
180+
}
181+
182+
SEQ_FUNC void seq_sonic_json_node_free(NodeType *node) { delete node; }
183+
184+
SEQ_FUNC void seq_sonic_json_node_set_object(NodeType *node) {
185+
node->SetObject();
186+
}
187+
188+
SEQ_FUNC void seq_sonic_json_node_add_string(
189+
NodeType *node, sonic_json::Document::Allocator *alloc, const char *key,
190+
size_t keyLen, const char *value, size_t valueLen) {
191+
auto key_ = std::string_view(key, keyLen);
192+
auto value_ = std::string_view(value, valueLen);
193+
node->AddMember(key_, NodeType(value_), *alloc);
194+
}
195+
196+
SEQ_FUNC void
197+
seq_sonic_json_node_add_int(NodeType *node,
198+
sonic_json::Document::Allocator *alloc,
199+
const char *key, size_t keyLen, int64_t value) {
200+
auto key_ = std::string_view(key, keyLen);
201+
node->AddMember(key_, NodeType(value), *alloc);
202+
}
203+
204+
SEQ_FUNC void
205+
seq_sonic_json_node_add_double(NodeType *node,
206+
sonic_json::Document::Allocator *alloc,
207+
const char *key, size_t keyLen, double value) {
208+
auto key_ = std::string(key, keyLen);
209+
node->AddMember(key_, NodeType(value), *alloc);
210+
}
211+
212+
SEQ_FUNC void
213+
seq_sonic_json_node_add_bool(NodeType *node,
214+
sonic_json::Document::Allocator *alloc,
215+
const char *key, size_t keyLen, bool value) {
216+
auto key_ = std::string_view(key, keyLen);
217+
node->AddMember(key_, NodeType(value), *alloc);
218+
}
219+
158220
SEQ_FUNC size_t seq_sonic_json_document_to_string(sonic_json::Document *doc,
159221
char *result) {
160222
auto s = sonic_json_to_string(doc);

moxt/utils/snowflake.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "snowflake.hpp"
2+
#include <boost/asio.hpp>
3+
4+
using boost::asio::ip::host_name;
5+
using boost::asio::ip::tcp;
6+
7+
std::string getLocalIp() {
8+
boost::asio::io_service io_service;
9+
tcp::resolver resolver(io_service);
10+
tcp::resolver::query query(host_name(), "");
11+
tcp::resolver::iterator iter = resolver.resolve(query);
12+
tcp::resolver::iterator end;
13+
14+
std::string ip = "";
15+
16+
while (iter != end) {
17+
tcp::endpoint endpoint = *iter++;
18+
if (endpoint.address().is_v4()) {
19+
if (ip.empty()) {
20+
ip = endpoint.address().to_string();
21+
}
22+
// printf("endpoint.address: %s\n",
23+
// endpoint.address().to_string().c_str());
24+
}
25+
}
26+
27+
return ip;
28+
}
29+
30+
// return workerId
31+
uint32_t ipToWorkerId(const std::string &ipAddress) {
32+
uint32_t workerId = 0;
33+
std::string::const_iterator it = ipAddress.begin();
34+
size_t n = 0;
35+
while (it != ipAddress.end() && n < 3) {
36+
if (*it == '.') {
37+
++it;
38+
++n;
39+
} else {
40+
workerId = workerId * 10 + (*it - '0');
41+
++it;
42+
}
43+
}
44+
return workerId;
45+
}
46+
47+
bool Snowflake::initWorkerId() {
48+
const std::string &ip = getLocalIp();
49+
logi("local ip: {}", ip);
50+
workerId_ = ipToWorkerId(ip);
51+
logi("WorkerId init success: {}", workerId_);
52+
return true;
53+
}
54+
55+
int64_t Snowflake::getId() {
56+
std::lock_guard<std::mutex> guard(mutex_);
57+
58+
int64_t timestamp = getTimestamp();
59+
if (timestamp < lastTimestamp_) {
60+
loge("Clock back");
61+
return kFirstBitRevert & getIdByTs(timestamp);
62+
}
63+
64+
return getIdByTs(timestamp);
65+
}
66+
67+
// get snowflake id by timestamp
68+
// update lastTimestamp_ or sequence_
69+
int64_t Snowflake::getIdByTs(int64_t timestamp) {
70+
// if it is the same time, then the microsecond sequence
71+
if (lastTimestamp_ == timestamp) {
72+
sequence_ = (sequence_ + 1) & kMaxSequence;
73+
// if the microsecond sequence overflow
74+
if (sequence_ == 0) {
75+
// block to the next millisecond, get the new timestamp
76+
timestamp = nextTimestamp();
77+
}
78+
} else {
79+
sequence_ = 0;
80+
}
81+
lastTimestamp_ = timestamp;
82+
return (timestamp - kStartStmp) << kTimestampLeft |
83+
workerId_ << kWorkerIdLeft | sequence_;
84+
}
85+
86+
int64_t Snowflake::getTimestamp() {
87+
return std::chrono::duration_cast<std::chrono::milliseconds>(
88+
std::chrono::system_clock::now().time_since_epoch())
89+
.count();
90+
}
91+
92+
// wait for the next millisecond
93+
int64_t Snowflake::nextTimestamp() {
94+
int64_t timestamp = getTimestamp();
95+
while (timestamp <= lastTimestamp_) {
96+
timestamp = getTimestamp();
97+
}
98+
return timestamp;
99+
}

moxt/utils/snowflake.hpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
#ifndef SNOWFLAKE_HPP
3+
#define SNOWFLAKE_HPP
4+
5+
#include "moxt/common.hpp"
6+
#include <chrono>
7+
#include <cstdint>
8+
#include <tscns.h>
9+
10+
class Snowflake {
11+
friend int64_t getSequence(int64_t id);
12+
friend int64_t getWorkerId(int64_t id);
13+
friend int64_t getTimestamp(int64_t id);
14+
15+
public:
16+
Snowflake() = default;
17+
18+
static bool initWorkerId();
19+
20+
int64_t getId();
21+
22+
private:
23+
static int64_t getTimestamp();
24+
25+
int64_t nextTimestamp();
26+
27+
int64_t getIdByTs(int64_t timestamp);
28+
29+
std::mutex mutex_;
30+
/*
31+
* Snowflake id:
32+
* timestampBit 38 bits (8.6 years) |
33+
* workerBit 13 bits (8k workerid) |
34+
* sequenceBit 12 bits (4 million per second) |
35+
*/
36+
int64_t lastTimestamp_{-1};
37+
static inline int64_t workerId_{0};
38+
int64_t sequence_{0};
39+
40+
static constexpr int64_t kStartStmp =
41+
1704038400000; // start time: 2024-01-01 00:00:00
42+
static constexpr int64_t kWorkerBit = 13; // worker id bit
43+
static constexpr int64_t kSequenceBit = 12; // sequence bit
44+
45+
static constexpr int64_t kMaxWorkerId =
46+
(1 << kWorkerBit) - 1; // as worker id mask
47+
static constexpr int64_t kMaxSequence = (1 << kSequenceBit) - 1;
48+
49+
static constexpr int64_t kWorkerIdLeft = kSequenceBit; // workerId left bits
50+
static constexpr int64_t kTimestampLeft = kSequenceBit + kWorkerBit;
51+
52+
static constexpr int64_t kFirstBitRevert =
53+
0x9000000000000000; // revert the first bit
54+
};
55+
56+
#endif // SNOWFLAKE_HPP

0 commit comments

Comments
 (0)