summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-10-02 19:09:25 +0800
committerGitHub <[email protected]>2025-10-02 19:09:25 +0800
commitc62972f4def074c8b0b433e557a48d313bf77a18 (patch)
tree0a24c95b7e5f3b2c0b73c3a8857b77dee04842ea
parent553eceaccbddb35e8499b3a4332a5b798219f796 (diff)
parent6377f4494967e341150f0e2bb042d3c7d8bd15c9 (diff)
Merge pull request #6872 from xmake-io/opti
Improve hash
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/engine.c16
-rw-r--r--core/src/xmake/hash/md5.c13
-rw-r--r--core/src/xmake/hash/prefix.h22
-rw-r--r--core/src/xmake/hash/rand128.c55
-rw-r--r--core/src/xmake/hash/rand32.c52
-rw-r--r--core/src/xmake/hash/rand64.c51
-rw-r--r--core/src/xmake/hash/sha.c11
-rw-r--r--core/src/xmake/hash/xxhash.c44
-rw-r--r--tests/benchmarks/hash.lua214
-rw-r--r--xmake/actions/config/configfiles.lua2
-rw-r--r--xmake/core/base/hash.lua70
-rw-r--r--xmake/core/base/os.lua3
-rw-r--r--xmake/core/base/scheduler.lua2
-rw-r--r--xmake/core/package/package.lua8
-rw-r--r--xmake/core/project/project.lua4
-rw-r--r--xmake/core/sandbox/modules/hash.lua79
-rw-r--r--xmake/modules/private/cache/build_cache.lua2
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua4
-rw-r--r--xmake/rules/c++/modules/support.lua4
-rw-r--r--xmake/rules/c++/unity_build/unity_build.lua2
21 files changed, 587 insertions, 71 deletions
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox
-Subproject b4c7e09b76751eacb7afa1521ac688e54b9cc76
+Subproject 46f5987ad31f4a52ee99417d62196f9bb524835
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/md5.c b/core/src/xmake/hash/md5.c
index 1ca594941..39fa82b15 100644
--- a/core/src/xmake/hash/md5.c
+++ b/core/src/xmake/hash/md5.c
@@ -57,10 +57,10 @@ tb_int_t xm_hash_md5(lua_State* lua)
// make md5 string
tb_char_t s[256];
- xm_hash_make_cstr(s, buffer, 16);
+ tb_size_t n = xm_hash_make_cstr(s, buffer, 16);
// save result
- lua_pushstring(lua, s);
+ lua_pushlstring(lua, s, n);
return 1;
}
@@ -108,14 +108,11 @@ tb_int_t xm_hash_md5(lua_State* lua)
tb_md5_exit(&md5, buffer, sizeof(buffer));
// make md5 string
- tb_size_t i = 0;
- tb_char_t s[256] = {0};
- for (i = 0; i < 16; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ tb_char_t s[256];
+ tb_size_t n = xm_hash_make_cstr(s, buffer, 16);
// save result
- lua_pushstring(lua, s);
-
- // ok
+ lua_pushlstring(lua, s, n);
ok = tb_true;
}
diff --git a/core/src/xmake/hash/prefix.h b/core/src/xmake/hash/prefix.h
index f5374a2d1..8a321e1eb 100644
--- a/core/src/xmake/hash/prefix.h
+++ b/core/src/xmake/hash/prefix.h
@@ -30,7 +30,26 @@
* helper implementation
*/
-static __tb_inline__ tb_void_t xm_hash_make_cstr(tb_char_t hash[256], tb_byte_t const* data, tb_size_t size)
+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";
tb_size_t i = 0;
@@ -44,6 +63,7 @@ static __tb_inline__ tb_void_t xm_hash_make_cstr(tb_char_t hash[256], tb_byte_t
s += 2;
}
*s = '\0';
+ return s - hash;
}
#endif
diff --git a/core/src/xmake/hash/rand128.c b/core/src/xmake/hash/rand128.c
new file mode 100644
index 000000000..1e1f34fde
--- /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_uclock();
+ s_seed.word[1] = (tb_uint64_t)tb_uclock();
+ }
+ 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..bbf565acd
--- /dev/null
+++ b/core/src/xmake/hash/rand32.c
@@ -0,0 +1,52 @@
+/*!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 tb_uint64_t s_seed = 0;
+ if (!s_seed)
+ s_seed = (tb_uint64_t)tb_uclock();
+ s_seed = xm_hash_xorshift64(s_seed);
+
+ tb_char_t s[256];
+ tb_uint32_t word = (s_seed >> 32) ^ (s_seed & 0xffffffff);
+ tb_size_t n = xm_hash_make_cstr(s, (tb_byte_t const*)&word, 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..31732bc53
--- /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_uclock();
+ 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/core/src/xmake/hash/sha.c b/core/src/xmake/hash/sha.c
index 4ffc2651e..ba5408279 100644
--- a/core/src/xmake/hash/sha.c
+++ b/core/src/xmake/hash/sha.c
@@ -62,13 +62,12 @@ tb_int_t xm_hash_sha(lua_State* lua)
tb_sha_exit(&sha, buffer, sizeof(buffer));
// make sha string
- tb_size_t i = 0;
+ tb_char_t s[256];
tb_size_t n = sha.digest_len << 2;
- tb_char_t s[256] = {0};
- for (i = 0; i < n; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ tb_size_t len = xm_hash_make_cstr(s, buffer, n);
// save result
- lua_pushstring(lua, s);
+ lua_pushlstring(lua, s, len);
return 1;
}
@@ -118,10 +117,10 @@ tb_int_t xm_hash_sha(lua_State* lua)
// make sha string
tb_char_t s[256];
tb_size_t n = sha.digest_len << 2;
- xm_hash_make_cstr(s, buffer, n);
+ tb_size_t len = xm_hash_make_cstr(s, buffer, n);
// save result
- lua_pushstring(lua, s);
+ lua_pushlstring(lua, s, len);
ok = tb_true;
}
diff --git a/core/src/xmake/hash/xxhash.c b/core/src/xmake/hash/xxhash.c
index 8f2cc630c..cf4f67e37 100644
--- a/core/src/xmake/hash/xxhash.c
+++ b/core/src/xmake/hash/xxhash.c
@@ -44,7 +44,7 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
// get mode
tb_size_t mode = (tb_size_t)lua_tointeger(lua, 1);
- if (mode != 64 && mode != 128)
+ if (mode != 32 && mode != 64 && mode != 128)
{
lua_pushnil(lua);
lua_pushfstring(lua, "invalid mode(%d)!", (tb_int_t)mode);
@@ -66,17 +66,24 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
// compuate hash
tb_byte_t const* buffer = tb_null;
+ tb_uint32_t value32;
XXH64_hash_t value64;
XXH128_hash_t value128;
- if (mode == 64)
+ if (mode == 128)
+ {
+ value128 = XM_XXH3_128bits(data, size);
+ buffer = (tb_byte_t const*)&value128;
+ }
+ else if (mode == 64)
{
value64 = XM_XXH3_64bits(data, size);
buffer = (tb_byte_t const*)&value64;
}
- else if (mode == 128)
+ else if (mode == 32)
{
- value128 = XM_XXH3_128bits(data, size);
- buffer = (tb_byte_t const*)&value128;
+ value64 = XM_XXH3_64bits(data, size);
+ value32 = (value64 >> 32) ^ (value64 & 0xffffffff);
+ buffer = (tb_byte_t const*)&value32;
}
if (!buffer)
{
@@ -88,10 +95,10 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
// make xxhash string
tb_char_t s[256];
tb_size_t n = mode >> 3;
- xm_hash_make_cstr(s, buffer, n);
+ tb_size_t len = xm_hash_make_cstr(s, buffer, n);
// save result
- lua_pushstring(lua, s);
+ lua_pushlstring(lua, s, len);
return 1;
}
@@ -109,7 +116,7 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
if (tb_stream_open(stream) && state)
{
// reset xxhash
- if (mode == 64) XM_XXH3_64bits_reset(state);
+ if (mode == 32 || mode == 64) XM_XXH3_64bits_reset(state);
else XM_XXH3_128bits_reset(state);
// read data and update xxhash
@@ -122,7 +129,7 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
// ok?
if (real > 0)
{
- if (mode == 64) XM_XXH3_64bits_update(state, data, real);
+ if (mode == 32 || mode == 64) XM_XXH3_64bits_update(state, data, real);
else XM_XXH3_128bits_update(state, data, real);
}
// no data? continue it
@@ -141,26 +148,33 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
// compuate hash
tb_byte_t const* buffer;
+ tb_uint32_t value32;
XXH64_hash_t value64;
XXH128_hash_t value128;
- if (mode == 64)
+ if (mode == 128)
+ {
+ value128 = XM_XXH3_128bits_digest(state);
+ buffer = (tb_byte_t const*)&value128;
+ }
+ else if (mode == 64)
{
value64 = XM_XXH3_64bits_digest(state);
buffer = (tb_byte_t const*)&value64;
}
- else
+ else if (mode == 32)
{
- value128 = XM_XXH3_128bits_digest(state);
- buffer = (tb_byte_t const*)&value128;
+ value64 = XM_XXH3_64bits_digest(state);
+ value32 = (value64 >> 32) ^ (value64 & 0xffffffff);
+ buffer = (tb_byte_t const*)&value32;
}
// make xxhash string
tb_char_t s[256];
tb_size_t n = mode >> 3;
- xm_hash_make_cstr(s, buffer, n);
+ tb_size_t len = xm_hash_make_cstr(s, buffer, n);
// save result
- lua_pushstring(lua, s);
+ lua_pushlstring(lua, s, len);
ok = tb_true;
}
diff --git a/tests/benchmarks/hash.lua b/tests/benchmarks/hash.lua
new file mode 100644
index 000000000..0f33684a0
--- /dev/null
+++ b/tests/benchmarks/hash.lua
@@ -0,0 +1,214 @@
+import("core.base.bytes")
+
+local COUNT = 1000000
+
+function test_md5(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10000
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.md5(data)
+ end
+ t = os.mclock() - t
+ print("md5(%d): %d ms, hash: %s", COUNT, t * 10000, h)
+end
+
+function test_sha1(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10000
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.sha1(data)
+ end
+ t = os.mclock() - t
+ print("sha1(%d): %d ms, hash: %s", COUNT, t * 10000, h)
+end
+
+function test_sha256(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10000
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.sha256(data)
+ end
+ t = os.mclock() - t
+ print("sha256(%d): %d ms, hash: %s", COUNT, t * 10000, h)
+end
+
+function test_uuid(data)
+ local h
+ local n = COUNT / 10000
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.uuid(data)
+ end
+ t = os.mclock() - t
+ print("uuid(%d): %d ms, hash: %s", COUNT, t * 10000, h)
+end
+
+function test_xxhash32(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.xxhash32(data)
+ end
+ t = os.mclock() - t
+ print("xxhash32(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_xxhash64(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.xxhash64(data)
+ end
+ t = os.mclock() - t
+ print("xxhash64(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_xxhash128(data)
+ data = bytes(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.xxhash128(data)
+ end
+ t = os.mclock() - t
+ print("xxhash128(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_strhash32(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.strhash32(data)
+ end
+ t = os.mclock() - t
+ print("strhash32(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_strhash64(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.strhash64(data)
+ end
+ t = os.mclock() - t
+ print("strhash64(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_strhash128(data)
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.strhash128(data)
+ end
+ t = os.mclock() - t
+ print("strhash128(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_random_uuid()
+ local h
+ local n = COUNT / 1000
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.uuid()
+ end
+ t = os.mclock() - t
+ print("uuid(%d): %d ms, hash: %s", COUNT, t * 1000, h)
+end
+
+function test_rand32()
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.rand32()
+ end
+ t = os.mclock() - t
+ print("rand32(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_rand64()
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.rand64()
+ end
+ t = os.mclock() - t
+ print("rand64(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_rand128()
+ local h
+ local n = COUNT / 10
+ local t = os.mclock()
+ for i = 1, n do
+ h = hash.rand128()
+ end
+ t = os.mclock() - t
+ print("rand128(%d): %d ms, hash: %s", COUNT, t * 10, h)
+end
+
+function test_longstr()
+ print("========================================== test long string ==========================================")
+ local data = ""
+ for i = 1, 10000 do
+ data = data .. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ end
+ test_md5(data)
+ test_sha1(data)
+ test_sha256(data)
+ test_uuid(data)
+ test_xxhash32(data)
+ test_xxhash64(data)
+ test_xxhash128(data)
+ test_strhash32(data)
+ test_strhash64(data)
+ test_strhash128(data)
+end
+
+function test_shortstr()
+ print("========================================== test short string ==========================================")
+ COUNT = COUNT * 100
+ local data = ""
+ for i = 1, 10 do
+ data = data .. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ end
+ test_md5(data)
+ test_sha1(data)
+ test_sha256(data)
+ test_uuid(data)
+ test_xxhash32(data)
+ test_xxhash64(data)
+ test_xxhash128(data)
+ test_strhash32(data)
+ test_strhash64(data)
+ test_strhash128(data)
+end
+
+function test_random()
+ print("========================================== test random ==========================================")
+ test_random_uuid()
+ test_rand32()
+ test_rand64()
+ test_rand128()
+end
+
+function main()
+ test_longstr()
+ test_shortstr()
+ test_random()
+end
diff --git a/xmake/actions/config/configfiles.lua b/xmake/actions/config/configfiles.lua
index ce435d774..60e5ef378 100644
--- a/xmake/actions/config/configfiles.lua
+++ b/xmake/actions/config/configfiles.lua
@@ -292,7 +292,7 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets, preprocessors
end
else
-- generate to the temporary file first
- local dstfile_tmp = path.join(os.tmpdir(), hash.uuid4(srcfile))
+ local dstfile_tmp = os.tmpfile(srcfile)
os.tryrm(dstfile_tmp)
os.cp(srcfile, dstfile_tmp)
diff --git a/xmake/core/base/hash.lua b/xmake/core/base/hash.lua
index 362eb67e5..e846ba302 100644
--- a/xmake/core/base/hash.lua
+++ b/xmake/core/base/hash.lua
@@ -25,11 +25,15 @@ local hash = hash or {}
local io = require("base/io")
local utils = require("base/utils")
local bytes = require("base/bytes")
+local libc = require("base/libc")
-- save metatable and builtin functions
hash._md5 = hash._md5 or hash.md5
hash._sha = hash._sha or hash.sha
hash._xxhash = hash._xxhash or hash.xxhash
+hash._rand32 = hash._rand32 or hash.rand32
+hash._rand64 = hash._rand64 or hash.rand64
+hash._rand128 = hash._rand128 or hash.rand128
-- generate md5 from the given file or data
function hash.md5(file_or_data)
@@ -70,6 +74,24 @@ function hash.sha256(file_or_data)
return hashstr, errors
end
+-- generate uuid, e.g "91E8ECF1-417F-4EDF-A574-E22D7D8D204A"
+function hash.uuid(str)
+ return hash.uuid4(str)
+end
+
+-- generate xxhash32 from the given file or data
+function hash.xxhash32(file_or_data)
+ local hashstr, errors
+ if bytes.instance_of(file_or_data) then
+ local datasize = file_or_data:size()
+ local dataaddr = file_or_data:caddr()
+ hashstr, errors = hash._xxhash(32, dataaddr, datasize)
+ else
+ hashstr, errors = hash._xxhash(32, file_or_data)
+ end
+ return hashstr, errors
+end
+
-- generate xxhash64 from the given file or data
function hash.xxhash64(file_or_data)
local hashstr, errors
@@ -96,20 +118,52 @@ function hash.xxhash128(file_or_data)
return hashstr, errors
end
--- generate uuid, e.g "91E8ECF1-417F-4EDF-A574-E22D7D8D204A"
-function hash.uuid(str)
- return hash.uuid4(str)
-end
-
--- TODO, we should optimize it
-- generate hash32 from string, e.g. "91e8ecf1"
function hash.strhash32(str)
- return hash.uuid4(str):split("-", {plain = true})[1]:lower()
+ local data = libc.ptraddr(libc.dataptr(str))
+ local size = #str
+ return hash._xxhash(32, data, size)
+end
+
+-- generate hash64 from string, e.g. "91e8ecf191e8ecf1"
+function hash.strhash64(str)
+ local data = libc.ptraddr(libc.dataptr(str))
+ local size = #str
+ return hash._xxhash(64, data, size)
end
-- generate hash128 from string, e.g. "91e8ecf1417f4edfa574e22d7d8d204a"
function hash.strhash128(str)
- return hash.uuid4(str):replace("-", "", {plain = true}):lower()
+ local data = libc.ptraddr(libc.dataptr(str))
+ local size = #str
+ return hash._xxhash(128, data, size)
+end
+
+-- generate random32 hash
+function hash.rand32()
+ if hash._rand32 then
+ return hash._rand32()
+ else
+ return hash.strhash32(tostring(math.random()))
+ end
+end
+
+-- generate random64 hash
+function hash.rand64()
+ if hash._rand64 then
+ return hash._rand64()
+ else
+ return hash.strhash64(tostring(math.random()))
+ end
+end
+
+-- generate random128 hash
+function hash.rand128()
+ if hash._rand128 then
+ return hash._rand128()
+ else
+ return hash.strhash128(tostring(math.random()))
+ end
end
-- return module: hash
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 41fe07d22..988d9e4bf 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -761,7 +761,8 @@ function os.tmpfile(opt_or_key)
key = opt_or_key.key
opt = opt_or_key
end
- return path.join(os.tmpdir(opt), "_" .. (hash.uuid4(key):gsub("-", "")))
+ local filename = "_" .. (key and hash.strhash128(key) or (hash.rand128()))
+ return path.join(os.tmpdir(opt), filename)
end
-- exit program
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua
index c96b32441..63c9fe009 100644
--- a/xmake/core/base/scheduler.lua
+++ b/xmake/core/base/scheduler.lua
@@ -299,7 +299,7 @@ function scheduler:_co_curenvs_update(envs)
for _, key in ipairs(table.orderkeys(envs)) do
envs_hash = envs_hash .. key:upper() .. envs[key]
end
- envs_hash = hash.uuid4(envs_hash):sub(1, 8)
+ envs_hash = hash.strhash32(envs_hash)
self._CO_CURENVS_HASH = envs_hash
-- save the current directory for each coroutine
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 7a1d8e24b..db943815a 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -1691,6 +1691,12 @@ function _instance:_compute_buildhash()
self:buildhash()
end
+-- hash.strhash128 has been switched to xxhash.
+-- For compatibility, the old hash algorithm is still used here.
+function _instance:_strhash128(str)
+ return hash.uuid4(str):replace("-", "", {plain = true}):lower()
+end
+
-- get the build hash
function _instance:buildhash()
local buildhash = self._BUILDHASH
@@ -1752,7 +1758,7 @@ function _instance:buildhash()
table.sort(toolchains)
str = str .. "_" .. table.concat(toolchains, "_")
end
- return hash.strhash128(str)
+ return self:_strhash128(str)
end
local function _get_installdir(...)
local name = self:name():lower():gsub("::", "_")
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 86050ebec..5af05c21f 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -25,6 +25,7 @@ local project = project or {}
local os = require("base/os")
local io = require("base/io")
local path = require("base/path")
+local hash = require("base/hash")
local task = require("base/task")
local utils = require("base/utils")
local table = require("base/table")
@@ -1380,7 +1381,8 @@ function project.tmpfile(opt_or_key)
key = opt_or_key.key
opt = opt_or_key
end
- return path.join(project.tmpdir(opt), "_" .. (hash.uuid4(key):gsub("-", "")))
+ local filename = "_" .. (key and hash.strhash128(key) or (hash.rand128()))
+ return path.join(project.tmpdir(opt), "_" .. filename)
end
-- get all modes
diff --git a/xmake/core/sandbox/modules/hash.lua b/xmake/core/sandbox/modules/hash.lua
index 47235bcd6..b5927b029 100644
--- a/xmake/core/sandbox/modules/hash.lua
+++ b/xmake/core/sandbox/modules/hash.lua
@@ -47,7 +47,7 @@ end
function sandbox_hash.sha1(file_or_data)
local sha1, errors = hash.sha1(file_or_data)
if not sha1 then
- raise("cannot generate sha1 for %s, %s", file_or_data, errors or "unknown errors")
+ raise("cannot generate sha1, %s", errors or "unknown errors")
end
return sha1
end
@@ -56,7 +56,7 @@ end
function sandbox_hash.sha256(file_or_data)
local sha256, errors = hash.sha256(file_or_data)
if not sha256 then
- raise("cannot generate sha256 for %s, %s", file_or_data, errors or "unknown errors")
+ raise("cannot generate sha256, %s", errors or "unknown errors")
end
return sha256
end
@@ -65,45 +65,90 @@ end
function sandbox_hash.md5(file_or_data)
local md5, errors = hash.md5(file_or_data)
if not md5 then
- raise("cannot generate md5 for %s, %s", file_or_data, errors or "unknown errors")
+ raise("cannot generate md5, %s", errors or "unknown errors")
end
return md5
end
+-- generate xxhash32 from the given file or data
+function sandbox_hash.xxhash32(file_or_data)
+ local result, errors = hash.xxhash32(file_or_data)
+ if not result then
+ raise("cannot generate xxhash32, %s", errors or "unknown errors")
+ end
+ return result
+end
+
-- generate xxhash64 from the given file or data
function sandbox_hash.xxhash64(file_or_data)
- local xxhash64, errors = hash.xxhash64(file_or_data)
- if not xxhash64 then
- raise("cannot generate xxhash64 for %s, %s", file_or_data, errors or "unknown errors")
+ local result, errors = hash.xxhash64(file_or_data)
+ if not result then
+ raise("cannot generate xxhash64, %s", errors or "unknown errors")
end
- return xxhash64
+ return result
end
-- generate xxhash128 from the given file or data
function sandbox_hash.xxhash128(file_or_data)
- local xxhash128, errors = hash.xxhash128(file_or_data)
- if not xxhash128 then
- raise("cannot generate xxhash128 for %s, %s", file_or_data, errors or "unknown errors")
+ local result, errors = hash.xxhash128(file_or_data)
+ if not result then
+ raise("cannot generate xxhash128, %s", errors or "unknown errors")
end
- return xxhash128
+ return result
end
-- generate hash32 from string
function sandbox_hash.strhash32(str)
- local hash32, errors = hash.strhash32(str)
- if not hash32 then
+ local result, errors = hash.strhash32(str)
+ if not result then
+ raise("cannot generate hash32 for %s, %s", str, errors or "unknown errors")
+ end
+ return result
+end
+
+-- generate hash64 from string
+function sandbox_hash.strhash64(str)
+ local result, errors = hash.strhash64(str)
+ if not result then
raise("cannot generate hash32 for %s, %s", str, errors or "unknown errors")
end
- return hash32
+ return result
end
-- generate hash128 from string
function sandbox_hash.strhash128(str)
- local hash128, errors = hash.strhash128(str)
- if not hash128 then
+ local result, errors = hash.strhash128(str)
+ if not result then
raise("cannot generate hash128 for %s, %s", str, errors or "unknown errors")
end
- return hash128
+ return result
+end
+
+-- generate random32
+function sandbox_hash.rand32()
+ local result, errors = hash.rand32()
+ if not result then
+ raise("cannot generate random32, %s", errors or "unknown errors")
+ end
+ return result
+end
+
+-- generate random64
+function sandbox_hash.rand64()
+ local result, errors = hash.rand64()
+ if not result then
+ raise("cannot generate random64, %s", errors or "unknown errors")
+ end
+ return result
+end
+
+-- generate random128
+function sandbox_hash.rand128()
+ local result, errors = hash.rand128()
+ if not result then
+ raise("cannot generate random128, %s", errors or "unknown errors")
+ end
+ return result
end
-- return module
diff --git a/xmake/modules/private/cache/build_cache.lua b/xmake/modules/private/cache/build_cache.lua
index 3b82578e5..905426ef5 100644
--- a/xmake/modules/private/cache/build_cache.lua
+++ b/xmake/modules/private/cache/build_cache.lua
@@ -128,7 +128,7 @@ function cachekey(program, cppinfo, envs)
end
end
end
- return hash.xxhash128(bytes(table.concat(items, "")))
+ return hash.strhash128(table.concat(items, ""))
end
-- get cache root directory
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index a5ec312cb..a339a654e 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -1074,7 +1074,7 @@ function _add_target_link_libraries(cmakelists, target, outputdir)
local has_links = #target:objectfiles() > objectfiles_set:size()
- local key = target:name() .. "_" .. hash.uuid():split("-", {plain = true})[1]
+ local key = target:name() .. "_" .. hash.rand32()
if has_links then
cmakelists:print("add_library(target_objectfiles_%s OBJECT IMPORTED GLOBAL)", key)
cmakelists:print("set_property(TARGET target_objectfiles_%s PROPERTY IMPORTED_OBJECTS", key)
@@ -1244,7 +1244,7 @@ function _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir
--
-- @see https://gitlab.kitware.com/cmake/cmake/-/issues/17802
--
- local key = target:name() .. "_" .. hash.uuid():split("-", {plain = true})[1]
+ local key = target:name() .. "_" .. hash.rand32()
cmakelists:print("add_custom_command(OUTPUT output_%s", key)
for _, cmd in ipairs(cmds) do
local command = _get_command_string(cmd, outputdir)
diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua
index 8d1c39531..cee0f1ab8 100644
--- a/xmake/rules/c++/modules/support.lua
+++ b/xmake/rules/c++/modules/support.lua
@@ -336,7 +336,7 @@ function modules_cachedir(target, opt)
moduletype = "interfaces"
elseif opt.scan then
moduletype = "scans"
- else
+ else
moduletype = "implementation"
end
local cachedir = path.join(target:autogendir(), "rules", "bmi", "cache", moduletype)
@@ -347,7 +347,7 @@ function modules_cachedir(target, opt)
end
function get_modulehash(sourcefile)
- return hash.uuid(sourcefile):split("-", {plain = true})[1]:lower()
+ return hash.strhash32(sourcefile)
end
function get_metafile(target, module)
diff --git a/xmake/rules/c++/unity_build/unity_build.lua b/xmake/rules/c++/unity_build/unity_build.lua
index e8f37f868..3df2d75b4 100644
--- a/xmake/rules/c++/unity_build/unity_build.lua
+++ b/xmake/rules/c++/unity_build/unity_build.lua
@@ -36,7 +36,7 @@ function _merge_unityfile(target, sourcefile_unity, sourcefiles, opt)
sourcefile_unity = path.absolute(sourcefile_unity)
sourcefile = path.relative(sourcefile, path.directory(sourcefile_unity))
if uniqueid then
- unityfile:print("#define %s %s", uniqueid, "unity_" .. hash.uuid():split("-", {plain = true})[1])
+ unityfile:print("#define %s %s", uniqueid, "unity_" .. hash.rand32())
end
unityfile:print("#include \"%s\"", sourcefile)
if uniqueid then