diff --git a/core/luabus/src/lua_socket_node.h b/core/luabus/src/lua_socket_node.h index 468127ae..fd176c04 100644 --- a/core/luabus/src/lua_socket_node.h +++ b/core/luabus/src/lua_socket_node.h @@ -36,18 +36,18 @@ class lua_socket_node int call_data(lua_State* L); int call_pb(lua_State* L, uint32_t session_id); - int call(lua_State* L, uint32_t session_id, uint8_t flag); + int call(lua_State* L, uint64_t session_id, uint8_t flag); - int forward_target(lua_State* L, uint32_t session_id, uint8_t flag, uint32_t target_id); - int forward_hash(lua_State* L, uint32_t session_id, uint8_t flag, uint8_t service_id, uint16_t hash); + int forward_target(lua_State* L, uint64_t session_id, uint8_t flag, uint32_t target_id); + int forward_hash(lua_State* L, uint64_t session_id, uint8_t flag, uint8_t service_id, uint16_t hash); - int forward_transfer(lua_State* L, uint32_t session_id, uint32_t target_id, uint8_t service_id); + int forward_transfer(lua_State* L, uint64_t session_id, uint32_t target_id, uint8_t service_id); - int transfer_call(lua_State* L, uint32_t session_id, uint32_t target_id); - int transfer_hash(lua_State* L, uint32_t session_id, uint8_t service_id, uint16_t hash); + int transfer_call(lua_State* L, uint64_t session_id, uint32_t target_id); + int transfer_hash(lua_State* L, uint64_t session_id, uint8_t service_id, uint16_t hash); template - int forward_by_group(lua_State* L, uint32_t session_id, uint8_t flag, uint8_t service_id) { + int forward_by_group(lua_State* L, uint64_t session_id, uint8_t flag, uint8_t service_id) { size_t data_len = 0; char* data = (char*)m_codec->encode(L, 4, &data_len); size_t length = data_len + sizeof(router_header); diff --git a/core/luabus/src/socket_router.h b/core/luabus/src/socket_router.h index d7e0ac4b..8e6c5e15 100644 --- a/core/luabus/src/socket_router.h +++ b/core/luabus/src/socket_router.h @@ -60,7 +60,6 @@ class socket_router bool do_forward_target(router_header* header, char* data, size_t data_len); bool do_forward_master(router_header* header, char* data, size_t data_len); bool do_forward_broadcast(router_header* header, int source, char* data, size_t data_len, size_t& broadcast_num); - bool do_transfer_call(transfer_header* header, char* data, size_t data_len); private: size_t m_route_count = 0; diff --git a/extend/lcodec/src/lcodec.cpp b/extend/lcodec/src/lcodec.cpp index 8928a105..c2be9b49 100644 --- a/extend/lcodec/src/lcodec.cpp +++ b/extend/lcodec/src/lcodec.cpp @@ -60,23 +60,6 @@ namespace lcodec { luakit::kit_state kit_state(L); auto llcodec = kit_state.new_table(); llcodec.set_function("bitarray", lbarray); - llcodec.set_function("guid_new", guid_new); - llcodec.set_function("guid_hex", guid_hex); - llcodec.set_function("guid_tohex", guid_tohex); - llcodec.set_function("guid_string", guid_string); - llcodec.set_function("guid_tostring", guid_tostring); - llcodec.set_function("guid_number", guid_number); - llcodec.set_function("guid_encode", guid_encode); - llcodec.set_function("guid_decode", guid_decode); - llcodec.set_function("guid_source", guid_source); - llcodec.set_function("guid_group", guid_group); - llcodec.set_function("guid_index", guid_index); - llcodec.set_function("guid_time", guid_time); - llcodec.set_function("hash_code", hash_code); - llcodec.set_function("jumphash", jumphash_l); - llcodec.set_function("fnv_1_32", fnv_1_32_l); - llcodec.set_function("fnv_1a_32", fnv_1a_32_l); - llcodec.set_function("murmur3_32", murmur3_32_l); llcodec.set_function("ketama_insert", ketama_insert); llcodec.set_function("ketama_remove", ketama_remove); llcodec.set_function("ketama_next", ketama_next); diff --git a/extend/luakit/include/lua_guid.h b/extend/luakit/include/lua_guid.h new file mode 100644 index 00000000..6e4a565a --- /dev/null +++ b/extend/luakit/include/lua_guid.h @@ -0,0 +1,164 @@ +#pragma once + +#include +#include +#include + +//g - group,7位(0~127) +//i - index,12位(0~4095) +//s - 序号,14位(0~17823) +//ts - 时间戳,30位 +//共63位,防止出现负数 + +namespace luakit { + + const uint32_t GROUP_BITS = 7; + const uint32_t INDEX_BITS = 12; + const uint32_t SNUM_BITS = 14; + + const uint32_t LETTER_LEN = 12; + const uint32_t LETTER_SIZE = 62; + + //基准时钟:2022-10-01 08:00:00 + const uint32_t BASE_TIME = 1664582400; + + const uint32_t MAX_GROUP = ((1 << GROUP_BITS) - 1); //128 - 1 + const uint32_t MAX_INDEX = ((1 << INDEX_BITS) - 1); //4096 - 1 + const uint32_t MAX_SNUM = ((1 << SNUM_BITS) - 1); //17824 - 1 - FULL_NUM + + //每一group独享一个id生成种子 + thread_local time_t last_time = 0; + thread_local size_t serial_inedx_table[(1 << GROUP_BITS)] = { 0 }; + + static char letter[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + inline uint64_t guid_new(uint32_t group, uint32_t index){ + if (group == 0) { + group = rand(); + } + if (index == 0) { + index = rand(); + } + group %= MAX_GROUP; + index %= MAX_INDEX; + time_t now_time; + time(&now_time); + size_t serial_index; + if (now_time <= last_time) { + serial_index = ++serial_inedx_table[group]; + //种子溢出以后,时钟往前推 + if (serial_index >= MAX_SNUM) { + serial_inedx_table[group] = 0; + last_time = ++now_time; + serial_index = 0; + } + } + else { + serial_inedx_table[group] = 0; + last_time = now_time; + } + return ((last_time - BASE_TIME) << (SNUM_BITS + GROUP_BITS + INDEX_BITS)) | + (serial_index << (GROUP_BITS + INDEX_BITS)) | (index << GROUP_BITS) | group; + } + + inline int guid_string(lua_State* L, uint32_t group, uint32_t index) { + char sguid[32]; + size_t guid = guid_new(group, index); + snprintf(sguid, 32, "%zu", guid); + lua_pushstring(L, sguid); + return 1; + } + + inline int guid_hex(lua_State* L, uint32_t group, uint32_t index) { + char sguid[32]; + size_t guid = guid_new(group, index); + snprintf(sguid, 32, "%016lx", guid); + lua_pushstring(L, sguid); + return 1; + } + + inline int guid_tostring(lua_State* L, uint64_t guid) { + char sguid[32]; + snprintf(sguid, 32, "%zu", guid); + lua_pushstring(L, sguid); + return 1; + } + + inline int guid_tohex(lua_State* L, uint64_t guid) { + char sguid[32]; + snprintf(sguid, 32, "%016lx", guid); + lua_pushstring(L, sguid); + return 1; + } + + inline uint64_t guid_number(std::string guid) { + return strtoull(guid.c_str(), nullptr, 10); + } + + inline int guid_encode(lua_State* L) { + char tmp[LETTER_LEN]; + memset(tmp, 0, LETTER_LEN); + uint64_t val = (lua_gettop(L) > 0) ? lua_tointeger(L, 1) : guid_new(0, 0); + for (int i = 0; i < LETTER_LEN - 1; ++i) { + tmp[i] = letter[val % LETTER_SIZE]; + val /= LETTER_SIZE; + if (val == 0) break; + } + lua_pushstring(L, tmp); + return 1; + } + + inline int find_index(char val) { + if (val >= 97) return val - 61; + if (val >= 65) return val - 55; + return val - 48; + } + + inline uint64_t guid_decode(std::string sval){ + uint64_t val = 0; + size_t len = sval.size(); + const char* cval = sval.c_str(); + for (int i = 0; i < len; ++i) { + val += uint64_t(find_index(cval[i]) * pow(LETTER_SIZE, i)); + } + return val; + } + + inline size_t format_guid(lua_State* L) { + if (lua_type(L, 1) == LUA_TSTRING) { + char* chEnd = NULL; + const char* sguid = lua_tostring(L, 1); + return strtoull(sguid, &chEnd, 16); + } + else { + return lua_tointeger(L, 1); + } + } + + inline int guid_group(lua_State* L) { + size_t guid = format_guid(L); + lua_pushinteger(L, guid & 0x7f); + return 1; + } + + inline int guid_index(lua_State* L) { + size_t guid = format_guid(L); + lua_pushinteger(L, (guid >> GROUP_BITS) & 0xfff); + return 1; + } + + inline int guid_time(lua_State* L) { + size_t guid = format_guid(L); + size_t time = (guid >> (GROUP_BITS + INDEX_BITS + SNUM_BITS)) & 0x3fffffff; + lua_pushinteger(L, time + BASE_TIME); + return 1; + } + + inline int guid_source(lua_State* L) { + size_t guid = format_guid(L); + lua_pushinteger(L, guid & 0x7f); + lua_pushinteger(L, (guid >> GROUP_BITS) & 0xfff); + lua_pushinteger(L, ((guid >> (GROUP_BITS + INDEX_BITS + SNUM_BITS)) & 0x3fffffff) + BASE_TIME); + return 3; + } +} diff --git a/extend/luakit/include/lua_hash.h b/extend/luakit/include/lua_hash.h new file mode 100644 index 00000000..6d30b075 --- /dev/null +++ b/extend/luakit/include/lua_hash.h @@ -0,0 +1,131 @@ +#pragma once + +namespace luakit { + + inline int hash_code(lua_State* L) { + size_t hcode = 0; + int type = lua_type(L, 1); + if (type == LUA_TNUMBER) { + hcode = std::hash{}(lua_tointeger(L, 1)); + } else if (type == LUA_TSTRING) { + hcode = std::hash{}(lua_tostring(L, 1)); + } else { + luaL_error(L, "hashkey only support number or string!"); + } + size_t mod = luaL_optinteger(L, 2, 0); + if (mod > 0) { + hcode = (hcode % mod) + 1; + } + lua_pushinteger(L, hcode); + return 1; + } + + inline uint32_t fnv_1_32(const char* bp, uint32_t hval) { + unsigned char* be = (unsigned char*)bp; + while (*bp) { + hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); + hval ^= (uint32_t)*bp++; + } + return hval; + } + + inline int fnv_1_32_l(lua_State* L) { + size_t len; + const char* bp = lua_tolstring(L, 1, &len); + uint32_t hval = luaL_optinteger(L, 2, 0); + lua_pushinteger(L, fnv_1_32(bp, hval)); + return 1; + } + + inline uint32_t fnv_1a_32(const char* b, size_t len, uint32_t hval) { + unsigned char* bp = (unsigned char*)b; + unsigned char* be = bp + len; + while (bp < be) { + hval ^= (uint32_t)*bp++; + hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); + } + return hval; + } + + inline int fnv_1a_32_l(lua_State* L) { + size_t len; + const char* bp = lua_tolstring(L, 1, &len); + uint32_t hval = luaL_optinteger(L, 2, 0); + lua_pushinteger(L, fnv_1a_32(bp, len, hval)); + return 1; + } + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + inline uint32_t rotl32(uint32_t x, int8_t r) { + return (x << r) | (x >> (32 - r)); + } + + inline uint32_t murmur3_32(const uint8_t* data, size_t length) { + uint32_t h1 = 0; + const int nblocks = length / 4; + // body + const uint32_t* blocks = (const uint32_t *)(data + nblocks*4); + for(int i = -nblocks; i; i++) { + uint32_t k1 = blocks[i]; + k1 *= c1; + k1 = rotl32(k1, 15); + k1 *= c2; + h1 ^= k1; + h1 = rotl32(h1, 13); + h1 = h1*5 + 0xe6546b64; + } + // tail + const uint8_t * tail = (const uint8_t*)(data + nblocks*4); + uint32_t k1 = 0; + switch(length & 3) + { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; + k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1; + }; + // finalization + h1 ^= length; + //fmix32 + h1 ^= h1 >> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >> 16; + return h1; + } + + inline int murmur3_32_l(lua_State* L) { + size_t length; + const uint8_t * data = (const uint8_t*)lua_tolstring(L, 1, &length); + lua_pushinteger(L, murmur3_32(data, length)); + return 1; + } + + inline int32_t jumphash(uint64_t key, int32_t num_buckets) { + int64_t b = -1, j = 0; + while (j < num_buckets) { + b = j; + key = key * 2862933555777941757ULL + 1; + j = (b + 1) * (double(1LL << 31) / double((key >> 33) + 1)); + } + return b; + } + + inline int jumphash_l(lua_State* L) { + uint64_t key = 0; + int type = lua_type(L, 1); + if (type == LUA_TNUMBER) { + key = lua_tointeger(L, 1); + } else if (type == LUA_TSTRING) { + key = fnv_1_32(lua_tostring(L, 1), 0); + } else { + luaL_error(L, "hashkey only support number or string!"); + } + int32_t num_buckets = lua_tointeger(L, 2); + int32_t hval = jumphash(key, num_buckets); + lua_pushinteger(L, hval + 1); + return 1; + } +} diff --git a/extend/luakit/include/lua_kit.h b/extend/luakit/include/lua_kit.h index 531f435a..5366c384 100644 --- a/extend/luakit/include/lua_kit.h +++ b/extend/luakit/include/lua_kit.h @@ -1,5 +1,7 @@ #pragma once #include "lua_buff.h" +#include "lua_guid.h" +#include "lua_hash.h" #include "lua_codec.h" #include "lua_table.h" #include "lua_class.h" @@ -21,6 +23,23 @@ namespace luakit { ); m_buf = new luabuf(); lua_table luakit = new_table("luakit"); + luakit.set_function("guid_new", guid_new); + luakit.set_function("guid_hex", guid_hex); + luakit.set_function("guid_tohex", guid_tohex); + luakit.set_function("guid_string", guid_string); + luakit.set_function("guid_tostring", guid_tostring); + luakit.set_function("guid_number", guid_number); + luakit.set_function("guid_encode", guid_encode); + luakit.set_function("guid_decode", guid_decode); + luakit.set_function("guid_source", guid_source); + luakit.set_function("guid_group", guid_group); + luakit.set_function("guid_index", guid_index); + luakit.set_function("guid_time", guid_time); + luakit.set_function("hash_code", hash_code); + luakit.set_function("jumphash", jumphash_l); + luakit.set_function("fnv_1_32", fnv_1_32_l); + luakit.set_function("fnv_1a_32", fnv_1a_32_l); + luakit.set_function("murmur3_32", murmur3_32_l); luakit.set_function("encode", [&](lua_State* L) { return encode(L, m_buf); }); luakit.set_function("decode", [&](lua_State* L) { return decode(L, m_buf); }); luakit.set_function("unserialize", [&](lua_State* L) { return unserialize(L); });