summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-10-01 00:47:56 +0800
committerruki <[email protected]>2025-10-01 00:47:56 +0800
commit9dc8bb99439f4d31e3563a5865764798c2094e8e (patch)
tree911e222e99d1df86804f1380940f829045fbe97b
parent672470e6e4ea7fd150354c131ba5fb60f7331643 (diff)
improve random hash
-rw-r--r--core/src/xmake/engine.c16
-rw-r--r--core/src/xmake/hash/prefix.h27
-rw-r--r--core/src/xmake/hash/rand128.c55
-rw-r--r--core/src/xmake/hash/rand32.c51
-rw-r--r--core/src/xmake/hash/rand64.c51
-rw-r--r--tests/benchmarks/hash.lua24
-rw-r--r--xmake/core/base/hash.lua26
-rw-r--r--xmake/core/base/os.lua2
-rw-r--r--xmake/core/project/project.lua2
-rw-r--r--xmake/core/sandbox/modules/hash.lua12
10 files changed, 215 insertions, 51 deletions
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index 203fc1d49..c3f8e9f5c 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -225,6 +225,9 @@ tb_int_t xm_hash_uuid4(lua_State* lua);
tb_int_t xm_hash_sha(lua_State* lua);
tb_int_t xm_hash_md5(lua_State* lua);
tb_int_t xm_hash_xxhash(lua_State* lua);
+tb_int_t xm_hash_rand32(lua_State* lua);
+tb_int_t xm_hash_rand64(lua_State* lua);
+tb_int_t xm_hash_rand128(lua_State* lua);
// the base64 functions
tb_int_t xm_base64_encode(lua_State* lua);
@@ -518,11 +521,14 @@ static luaL_Reg const g_path_functions[] =
// the hash functions
static luaL_Reg const g_hash_functions[] =
{
- { "uuid4", xm_hash_uuid4 }
-, { "sha", xm_hash_sha }
-, { "md5", xm_hash_md5 }
-, { "xxhash", xm_hash_xxhash }
-, { tb_null, tb_null }
+ { "uuid4", xm_hash_uuid4 }
+, { "sha", xm_hash_sha }
+, { "md5", xm_hash_md5 }
+, { "xxhash", xm_hash_xxhash }
+, { "rand32", xm_hash_rand32 }
+, { "rand64", xm_hash_rand64 }
+, { "rand128", xm_hash_rand128 }
+, { tb_null, tb_null }
};
// the base64 functions
diff --git a/core/src/xmake/hash/prefix.h b/core/src/xmake/hash/prefix.h
index cf4cb082d..59a3941d7 100644
--- a/core/src/xmake/hash/prefix.h
+++ b/core/src/xmake/hash/prefix.h
@@ -30,6 +30,33 @@
* helper implementation
*/
+static __tb_inline__ tb_uint32_t xm_hash_xorshift32(tb_uint32_t x)
+{
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ return x;
+}
+
+static __tb_inline__ tb_uint64_t xm_hash_xorshift64(tb_uint64_t x)
+{
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ return x;
+}
+
+// http://xorshift.di.unimi.it/xorshift128plus.c
+static __tb_inline__ tb_uint64_t xm_hash_xorshift128(tb_uint64_t* s)
+{
+ tb_uint64_t s1 = s[0];
+ tb_uint64_t const s0 = s[1];
+ s[0] = s0;
+ s1 ^= s1 << 23;
+ s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);
+ return s[1] + s0;
+}
+
static __tb_inline__ tb_size_t xm_hash_make_cstr(tb_char_t hash[256], tb_byte_t const* data, tb_size_t size)
{
static tb_char_t const* digits_table = "0123456789abcdef";
diff --git a/core/src/xmake/hash/rand128.c b/core/src/xmake/hash/rand128.c
new file mode 100644
index 000000000..946d396fd
--- /dev/null
+++ b/core/src/xmake/hash/rand128.c
@@ -0,0 +1,55 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, Xmake Open Source Community.
+ *
+ * @author ruki
+ * @file rand128.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "rand128"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_hash_rand128(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ static union { tb_byte_t b[16]; tb_uint64_t word[2]; } s_seed = {0};
+ if (!s_seed.word[0] && !s_seed.word[1])
+ {
+ s_seed.word[0] = (tb_uint64_t)tb_mclock();
+ s_seed.word[1] = (tb_uint64_t)tb_mclock();
+ }
+ s_seed.word[0] = xm_hash_xorshift128(s_seed.word);
+ s_seed.word[1] = xm_hash_xorshift128(s_seed.word);
+
+ tb_char_t s[256];
+ tb_size_t n = xm_hash_make_cstr(s, s_seed.b, 16);
+
+ lua_pushlstring(lua, s, n);
+ return 1;
+}
diff --git a/core/src/xmake/hash/rand32.c b/core/src/xmake/hash/rand32.c
new file mode 100644
index 000000000..b76b0ae15
--- /dev/null
+++ b/core/src/xmake/hash/rand32.c
@@ -0,0 +1,51 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, Xmake Open Source Community.
+ *
+ * @author ruki
+ * @file rand32.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "rand32"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_hash_rand32(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ static union { tb_byte_t b[4]; tb_uint32_t word; } s_seed = {0};
+ if (!s_seed.word)
+ s_seed.word = (tb_uint32_t)tb_mclock();
+ s_seed.word = xm_hash_xorshift32(s_seed.word);
+
+ tb_char_t s[64];
+ tb_size_t n = xm_hash_make_cstr(s, s_seed.b, 4);
+
+ lua_pushlstring(lua, s, n);
+ return 1;
+}
diff --git a/core/src/xmake/hash/rand64.c b/core/src/xmake/hash/rand64.c
new file mode 100644
index 000000000..a42d0eedb
--- /dev/null
+++ b/core/src/xmake/hash/rand64.c
@@ -0,0 +1,51 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, Xmake Open Source Community.
+ *
+ * @author ruki
+ * @file rand64.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "rand64"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_hash_rand64(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ static union { tb_byte_t b[8]; tb_uint64_t word; } s_seed = {0};
+ if (!s_seed.word)
+ s_seed.word = (tb_uint64_t)tb_mclock();
+ s_seed.word = xm_hash_xorshift64(s_seed.word);
+
+ tb_char_t s[256];
+ tb_size_t n = xm_hash_make_cstr(s, s_seed.b, 8);
+
+ lua_pushlstring(lua, s, n);
+ return 1;
+}
diff --git a/tests/benchmarks/hash.lua b/tests/benchmarks/hash.lua
index 554f3f166..0f33684a0 100644
--- a/tests/benchmarks/hash.lua
+++ b/tests/benchmarks/hash.lua
@@ -129,37 +129,37 @@ function test_random_uuid()
print("uuid(%d): %d ms, hash: %s", COUNT, t * 1000, h)
end
-function test_random32()
+function test_rand32()
local h
local n = COUNT / 10
local t = os.mclock()
for i = 1, n do
- h = hash.random32()
+ h = hash.rand32()
end
t = os.mclock() - t
- print("random32(%d): %d ms, hash: %s", COUNT, t * 10, h)
+ print("rand32(%d): %d ms, hash: %s", COUNT, t * 10, h)
end
-function test_random64()
+function test_rand64()
local h
local n = COUNT / 10
local t = os.mclock()
for i = 1, n do
- h = hash.random64()
+ h = hash.rand64()
end
t = os.mclock() - t
- print("random64(%d): %d ms, hash: %s", COUNT, t * 10, h)
+ print("rand64(%d): %d ms, hash: %s", COUNT, t * 10, h)
end
-function test_random128()
+function test_rand128()
local h
local n = COUNT / 10
local t = os.mclock()
for i = 1, n do
- h = hash.random128()
+ h = hash.rand128()
end
t = os.mclock() - t
- print("random128(%d): %d ms, hash: %s", COUNT, t * 10, h)
+ print("rand128(%d): %d ms, hash: %s", COUNT, t * 10, h)
end
function test_longstr()
@@ -202,9 +202,9 @@ end
function test_random()
print("========================================== test random ==========================================")
test_random_uuid()
- test_random32()
- test_random64()
- test_random128()
+ test_rand32()
+ test_rand64()
+ test_rand128()
end
function main()
diff --git a/xmake/core/base/hash.lua b/xmake/core/base/hash.lua
index 5f162af65..b4b42371d 100644
--- a/xmake/core/base/hash.lua
+++ b/xmake/core/base/hash.lua
@@ -136,31 +136,5 @@ function hash.strhash128(str)
return hash._xxhash(128, data, size)
end
--- init random seed
-function hash._init_random_seed()
- if hash._INIT_RANDOM_SEED == nil then
- math.randomseed(os.time())
- hash._INIT_RANDOM_SEED = true
- end
-end
-
--- generate random32 hash
-function hash.random32()
- return hash.strhash32(tostring(math.random()))
-end
-
--- generate random64 hash
-function hash.random64()
- return hash.strhash64(tostring(math.random()))
-end
-
--- generate random128 hash
-function hash.random128()
- return hash.strhash128(tostring(math.random()))
-end
-
--- init random seed first
-hash._init_random_seed()
-
-- return module: hash
return hash
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 72d395d77..988d9e4bf 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -761,7 +761,7 @@ function os.tmpfile(opt_or_key)
key = opt_or_key.key
opt = opt_or_key
end
- local filename = "_" .. (key and hash.strhash128(key) or (hash.random128()))
+ local filename = "_" .. (key and hash.strhash128(key) or (hash.rand128()))
return path.join(os.tmpdir(opt), filename)
end
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 0f3a83bda..5af05c21f 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -1381,7 +1381,7 @@ function project.tmpfile(opt_or_key)
key = opt_or_key.key
opt = opt_or_key
end
- local filename = "_" .. (key and hash.strhash128(key) or (hash.random128()))
+ local filename = "_" .. (key and hash.strhash128(key) or (hash.rand128()))
return path.join(project.tmpdir(opt), "_" .. filename)
end
diff --git a/xmake/core/sandbox/modules/hash.lua b/xmake/core/sandbox/modules/hash.lua
index 178bb2a5f..b5927b029 100644
--- a/xmake/core/sandbox/modules/hash.lua
+++ b/xmake/core/sandbox/modules/hash.lua
@@ -125,8 +125,8 @@ function sandbox_hash.strhash128(str)
end
-- generate random32
-function sandbox_hash.random32()
- local result, errors = hash.random32()
+function sandbox_hash.rand32()
+ local result, errors = hash.rand32()
if not result then
raise("cannot generate random32, %s", errors or "unknown errors")
end
@@ -134,8 +134,8 @@ function sandbox_hash.random32()
end
-- generate random64
-function sandbox_hash.random64()
- local result, errors = hash.random64()
+function sandbox_hash.rand64()
+ local result, errors = hash.rand64()
if not result then
raise("cannot generate random64, %s", errors or "unknown errors")
end
@@ -143,8 +143,8 @@ function sandbox_hash.random64()
end
-- generate random128
-function sandbox_hash.random128()
- local result, errors = hash.random128()
+function sandbox_hash.rand128()
+ local result, errors = hash.rand128()
if not result then
raise("cannot generate random128, %s", errors or "unknown errors")
end