• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 
17 #include "ecmascript/tests/test_helper.h"
18 #include "ecmascript/ecma_string.h"
19 #include "common_components/platform/string_hash.h"
20 
21 using namespace panda::ecmascript;
22 using namespace common;
23 
24 namespace panda::test {
25 class EcmaStringHashTest : public BaseTestWithScope<false> {
26 public:
27     template <typename T>
ComputeHashRaw(const T * data,size_t size,uint32_t hashSeed)28     static uint32_t ComputeHashRaw(const T *data, size_t size, uint32_t hashSeed)
29     {
30         uint32_t hash = hashSeed;
31         for (size_t i = 0; i < size; i++) {
32             hash = hash * StringHash::HASH_MULTIPLY + data[i];
33         }
34         return hash;
35     }
36 
37     template <typename T>
ComputeHashOpt(const T * data,size_t size,uint32_t hashSeed)38     static uint32_t ComputeHashOpt(const T *data, size_t size, uint32_t hashSeed)
39     {
40         return BaseString::ComputeHashForData(data, size, hashSeed);
41     }
42 
ComputeConcatHash(const JSThread * thread,const JSHandle<EcmaString> & firstString,const JSHandle<EcmaString> & secondString)43     static uint32_t ComputeConcatHash(
44         const JSThread *thread,
45         const JSHandle<EcmaString> &firstString,
46         const JSHandle<EcmaString> &secondString)
47     {
48         return EcmaString::CalculateConcatHashCode(thread, firstString, secondString);
49     }
50 };
51 #if ENABLE_NEXT_OPTIMIZATION
52 /*
53 * @tc.name: ComputeHashForData
54 * @tc.desc: For short data,
55 * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i]
56 * @tc.type: FUNC
57 */
HWTEST_F_L0(EcmaStringHashTest,ComputeHashForData_001)58 HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_001)
59 {
60     std::string data = "Hello World! OpenHarmony";
61     uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
62     uint32_t optHash8 = ComputeHashOpt(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
63     EXPECT_EQ(rawHash8, optHash8);
64 
65     std::u16string data16 = u"Hello World! 鸿蒙 OpenHarmony";
66     uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
67     uint32_t optHash16 = ComputeHashOpt(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
68     EXPECT_EQ(rawHash16, optHash16);
69 }
70 
71 /*
72 * @tc.name: ComputeHashForData
73 * @tc.desc: For medium data,
74 * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i]
75 * @tc.type: FUNC
76 */
HWTEST_F_L0(EcmaStringHashTest,ComputeHashForData_002)77 HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_002)
78 {
79     std::string data = "Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~";
80     uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
81     uint32_t optHash8 = ComputeHashOpt(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
82     EXPECT_EQ(rawHash8, optHash8);
83 
84     std::u16string data16 = u"Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~ 鸿蒙";
85     uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
86     uint32_t optHash16 = ComputeHashOpt(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
87     EXPECT_EQ(rawHash16, optHash16);
88 }
89 
90 /*
91 * @tc.name: ComputeHashForData
92 * @tc.desc: For long data,
93 * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i]
94 * @tc.type: FUNC
95 */
HWTEST_F_L0(EcmaStringHashTest,ComputeHashForData_003)96 HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_003)
97 {
98     std::string data = "Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~";
99     std::u16string data16 = u"Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~ 鸿蒙";
100     for (int i = 0; i < 100; i++) {
101         data += std::to_string(i);
102         std::wstring wstring = std::to_wstring(i);
103         data16 += std::u16string(wstring.begin(), wstring.end());
104     }
105     uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
106     uint32_t optHash8 = ComputeHashOpt(reinterpret_cast<uint8_t*>(data.data()), data.size(), 0);
107     EXPECT_EQ(rawHash8, optHash8);
108 
109     uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
110     uint32_t optHash16 = ComputeHashOpt(reinterpret_cast<uint16_t*>(data16.data()), data16.size(), 0);
111     EXPECT_EQ(rawHash16, optHash16);
112 }
113 
HWTEST_F_L0(EcmaStringHashTest,CalculateConcatHashCode)114 HWTEST_F_L0(EcmaStringHashTest, CalculateConcatHashCode)
115 {
116     std::string firstData = "Hello World! OpenHarmony";
117     std::string secondData = "Hello World! OpenHarmony";
118     JSHandle<EcmaString> firstString(thread, EcmaStringAccessor::CreateFromUtf8(
119         instance, reinterpret_cast<uint8_t*>(firstData.data()), firstData.size(), true));
120     JSHandle<EcmaString> secondString(thread, EcmaStringAccessor::CreateFromUtf8(
121         instance, reinterpret_cast<uint8_t*>(secondData.data()), secondData.size(), true));
122 
123     std::string totalString = firstData + secondData;
124     uint32_t totalHash = ComputeHashOpt(reinterpret_cast<uint8_t*>(totalString.data()), totalString.size(), 0);
125     uint32_t concatHash = ComputeConcatHash(thread, firstString, secondString);
126     EXPECT_EQ(totalHash, concatHash);
127 }
128 #endif
129 }