• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include <string>
17 #include "ecmascript/base/builtins_base.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_handle.h"
21 #include "ecmascript/js_object-inl.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/object_factory.h"
24 #include "ecmascript/tagged_tree.h"
25 #include "ecmascript/tests/test_helper.h"
26 
27 using namespace panda;
28 
29 using namespace panda::ecmascript;
30 
31 namespace panda::test {
32 class TaggedTreeTest : public testing::Test {
33 public:
SetUpTestCase()34     static void SetUpTestCase()
35     {
36         GTEST_LOG_(INFO) << "SetUpTestCase";
37     }
38 
TearDownTestCase()39     static void TearDownTestCase()
40     {
41         GTEST_LOG_(INFO) << "TearDownCase";
42     }
43 
SetUp()44     void SetUp() override
45     {
46         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
47     }
48 
TearDown()49     void TearDown() override
50     {
51         TestHelper::DestroyEcmaVMWithScope(instance, scope);
52     }
53 
54     EcmaVM *instance {nullptr};
55     EcmaHandleScope *scope {nullptr};
56     JSThread *thread {nullptr};
57 
GetGlobalEnv()58     JSHandle<GlobalEnv> GetGlobalEnv()
59     {
60         EcmaVM *ecma = thread->GetEcmaVM();
61         return ecma->GetGlobalEnv();
62     }
63     class TestClass : public base::BuiltinsBase {
64     public:
TestCompareFunction(EcmaRuntimeCallInfo * argv)65         static JSTaggedValue TestCompareFunction(EcmaRuntimeCallInfo *argv)
66         {
67             JSThread *thread = argv->GetThread();
68             JSHandle<JSTaggedValue> valueX = GetCallArg(argv, 0);
69             JSHandle<JSTaggedValue> valueY = GetCallArg(argv, 1);
70 
71             if (valueX->IsString() && valueY->IsString()) {
72                 auto xHandle = JSHandle<EcmaString>(valueX);
73                 auto yHandle = JSHandle<EcmaString>(valueY);
74                 int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
75                 if (result < 0) {
76                     return JSTaggedValue(1);
77                 }
78                 if (result == 0) {
79                     return JSTaggedValue(0);
80                 }
81                 return JSTaggedValue(-1);
82             }
83 
84             if (valueX->IsNumber() && valueY->IsString()) {
85                 return JSTaggedValue(1);
86             }
87             if (valueX->IsString() && valueY->IsNumber()) {
88                 return JSTaggedValue(-1);
89             }
90 
91             ComparisonResult res = ComparisonResult::UNDEFINED;
92             if (valueX->IsNumber() && valueY->IsNumber()) {
93                 res = JSTaggedValue::StrictNumberCompare(valueY->GetNumber(), valueX->GetNumber());
94             } else {
95                 res = JSTaggedValue::Compare(thread, valueY, valueX);
96             }
97             return res == ComparisonResult::GREAT ?
98                 JSTaggedValue(1) : (res == ComparisonResult::LESS ? JSTaggedValue(-1) : JSTaggedValue(0));
99         }
100     };
101 };
102 
103 template <typename T>
CheckRBTreeOfAllPaths(JSHandle<T> & tree,int numsOfBlack,int index,int count)104 bool CheckRBTreeOfAllPaths(JSHandle<T> &tree, int numsOfBlack, int index, int count)
105 {
106     if (index < 0) {
107         return count == numsOfBlack;
108     }
109     if (tree->GetColor(index) == TreeColor::BLACK) {
110         count++;
111     }
112     if (CheckRBTreeOfAllPaths(tree, numsOfBlack, tree->GetLeftChildIndex(index), count) &&
113         CheckRBTreeOfAllPaths(tree, numsOfBlack, tree->GetRightChildIndex(index), count)) {
114         return true;
115     }
116     return false;
117 }
118 
119 template <typename T>
CheckBlackNodeNumbers(JSHandle<T> & tree,int index)120 bool CheckBlackNodeNumbers(JSHandle<T> &tree, int index)
121 {
122     int numsOfBlack = 0;
123     int child = index;
124     while (child >= 0) {
125         if (tree->GetColor(child) == TreeColor::BLACK) {
126             numsOfBlack++;
127         }
128         child = tree->GetLeftChildIndex(child);
129     }
130     return CheckRBTreeOfAllPaths(tree, numsOfBlack, index, 0);
131 }
132 
133 template <typename T>
IsVaildRBTree(JSThread * thread,JSHandle<T> & tree,int nodeIndex)134 bool IsVaildRBTree(JSThread *thread, JSHandle<T> &tree, int nodeIndex)
135 {
136     CQueue<int> nodes;
137     nodes.emplace(nodeIndex);
138     while (!nodes.empty()) {
139         int index = nodes.front();
140         int parent = tree->GetParent(index);
141         int pleft = tree->GetLeftChildIndex(parent);
142         int pright = tree->GetRightChildIndex(parent);
143         if (parent >= 0 && index != pleft && index != pright) {
144             return false;
145         }
146 
147         int ileft = tree->GetLeftChildIndex(index);
148         JSHandle<JSTaggedValue> indexKey(thread, tree->GetKey(index));
149         if (ileft >= 0) {
150             JSHandle<JSTaggedValue> leftKey(thread, tree->GetKey(ileft));
151             ComparisonResult result = TaggedTree<T>::EntryCompare(thread, leftKey, indexKey, tree);
152             if (tree->GetParent(ileft) != index || result != ComparisonResult::LESS) {
153                 return false;
154             }
155             nodes.emplace(ileft);
156         }
157         int iright = tree->GetRightChildIndex(index);
158         if (iright >= 0) {
159             JSHandle<JSTaggedValue> rightKey(thread, tree->GetKey(iright));
160             ComparisonResult result = TaggedTree<T>::EntryCompare(thread, rightKey, indexKey, tree);
161             if (tree->GetParent(iright) != index || result != ComparisonResult::GREAT) {
162                 return false;
163             }
164             nodes.emplace(iright);
165         }
166 
167         // check red node
168         TreeColor indexColor = tree->GetColor(index);
169         if (indexColor == TreeColor::RED) {
170             if (ileft >= 0 && tree->GetColor(ileft) == TreeColor::RED) {
171                 return false;
172             }
173             if (iright >= 0 && tree->GetColor(iright) == TreeColor::RED) {
174                 return false;
175             }
176         }
177         // check black node
178         if (!CheckBlackNodeNumbers(tree, index)) {
179             return false;
180         }
181         nodes.pop();
182     }
183     return true;
184 }
185 
HWTEST_F_L0(TaggedTreeTest,TreeMapCreate)186 HWTEST_F_L0(TaggedTreeTest, TreeMapCreate)
187 {
188     constexpr int NODE_NUMBERS = 64;
189     JSHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread, NODE_NUMBERS));
190     EXPECT_EQ(tmap->Capacity(), NODE_NUMBERS);
191     EXPECT_EQ(tmap->GetRootEntries(), -1);
192     EXPECT_EQ(tmap->NumberOfElements(), 0);
193     EXPECT_EQ(tmap->NumberOfDeletedElements(), 0);
194 }
195 
HWTEST_F_L0(TaggedTreeTest,TreeSetCreate)196 HWTEST_F_L0(TaggedTreeTest, TreeSetCreate)
197 {
198     constexpr int NODE_NUMBERS = 64;
199     JSHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread, NODE_NUMBERS));
200     EXPECT_EQ(tset->Capacity(), NODE_NUMBERS);
201     EXPECT_EQ(tset->GetRootEntries(), -1);
202     EXPECT_EQ(tset->NumberOfElements(), 0);
203     EXPECT_EQ(tset->NumberOfDeletedElements(), 0);
204 }
205 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapAddKeyAndValue)206 HWTEST_F_L0(TaggedTreeTest, TestTreeMapAddKeyAndValue)
207 {
208     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
209     constexpr int NODE_NUMBERS = 64;
210     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread, NODE_NUMBERS));
211     JSHandle<JSTaggedValue> objFun = GetGlobalEnv()->GetObjectFunction();
212 
213     char keyArray[] = "mykey1";
214     JSHandle<EcmaString> stringKey1 = factory->NewFromStdString(keyArray);
215     JSHandle<JSTaggedValue> key1(stringKey1);
216     JSHandle<JSTaggedValue> value1(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
217     char key2Array[] = "mykey2";
218     JSHandle<EcmaString> stringKey2 = factory->NewFromStdString(key2Array);
219     JSHandle<JSTaggedValue> key2(stringKey2);
220     JSHandle<JSTaggedValue> value2(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
221 
222     // test set()
223     tmap.Update(TaggedTreeMap::Set(thread, tmap, key1, value1));
224     EXPECT_EQ(tmap->NumberOfElements(), 1);
225     tmap.Update(TaggedTreeMap::Set(thread, tmap, key2, value2));
226     EXPECT_EQ(tmap->NumberOfElements(), 2);
227 
228     // test find()
229     JSTaggedValue res = TaggedTreeMap::Get(thread, tmap, key1);
230     EXPECT_EQ(value1.GetTaggedValue(), res);
231 
232     // test remove()
233     int entry = TaggedTreeMap::FindEntry(thread, tmap, key1);
234     res = TaggedTreeMap::Delete(thread, tmap, entry);
235     EXPECT_EQ(TaggedTreeMap::Cast(res.GetTaggedObject())->NumberOfElements(), 1);
236     tmap.Update(res);
237     EXPECT_EQ(tmap->NumberOfElements(), 1);
238     res = TaggedTreeMap::Get(thread, tmap, key1);
239     EXPECT_EQ(res, JSTaggedValue::Undefined());
240 }
241 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetAddValue)242 HWTEST_F_L0(TaggedTreeTest, TestTreeSetAddValue)
243 {
244     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
245     constexpr int NODE_NUMBERS = 64;
246     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread, NODE_NUMBERS));
247 
248     char keyArray[] = "mykey1";
249     JSHandle<EcmaString> stringKey1 = factory->NewFromStdString(keyArray);
250     JSHandle<JSTaggedValue> key1(stringKey1);
251     char key2Array[] = "mykey2";
252     JSHandle<EcmaString> stringKey2 = factory->NewFromStdString(key2Array);
253     JSHandle<JSTaggedValue> key2(stringKey2);
254 
255     // test set()
256     tset.Update(TaggedTreeSet::Add(thread, tset, key1));
257     EXPECT_EQ(tset->NumberOfElements(), 1);
258     tset.Update(TaggedTreeSet::Add(thread, tset, key2));
259     EXPECT_EQ(tset->NumberOfElements(), 2);
260 
261     // test find()
262     int entry = TaggedTreeSet::FindEntry(thread, tset, key1);
263     EXPECT_TRUE(entry >= 0);
264 
265     // test remove()
266     JSTaggedValue res = TaggedTreeSet::Delete(thread, tset, entry);
267     EXPECT_EQ(TaggedTreeSet::Cast(res.GetTaggedObject())->NumberOfElements(), 1);
268     EXPECT_EQ(-1, TaggedTreeSet::FindEntry(thread, tset, key1));
269     EXPECT_EQ(tset->NumberOfElements(), 1);
270 }
271 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGrowCapacity)272 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGrowCapacity)
273 {
274     constexpr int NODE_NUMBERS = 32;
275     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
276     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
277     JSHandle<JSFunction> objFun(GetGlobalEnv()->GetObjectFunction());
278     char keyArray[7] = "mykey"; // 7 means array length
279     for (int i = 0; i < NODE_NUMBERS; i++) {
280         keyArray[5] = '1' + static_cast<uint32_t>(i); // 5 means index of keyArray
281         keyArray[6] = 0;       // 6 means index of keyArray
282         JSHandle<JSTaggedValue> key(factory->NewFromStdString(keyArray));
283         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
284         // test set()
285         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
286         EXPECT_TRUE(TaggedTreeMap::FindEntry(thread, tmap, key) >= 0);
287     }
288 
289     for (int i = 0; i < NODE_NUMBERS; i++) {
290         keyArray[5] = '1' + static_cast<uint32_t>(i); // 5 means index of keyArray
291         keyArray[6] = 0;       // 6 means index of keyArray
292         JSHandle<JSTaggedValue> stringKey(factory->NewFromStdString(keyArray));
293         // test get()
294         JSTaggedValue res = TaggedTreeMap::Get(thread, tmap, stringKey);
295         EXPECT_EQ(JSTaggedValue(i), res);
296     }
297     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS);
298     EXPECT_EQ(tmap->Capacity(), 63); // 63 means capacity after Grow
299 }
300 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGrowCapacity)301 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGrowCapacity)
302 {
303     constexpr int NODE_NUMBERS = 32;
304     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
305     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
306     // create key
307     char keyArray[7] = "mykey"; // 7 means array length
308     for (int i = 0; i < NODE_NUMBERS; i++) {
309         keyArray[5] = '1' + static_cast<uint32_t>(i); // 5 means index of keyArray
310         keyArray[6] = 0;       // 6 means index of keyArray
311         JSHandle<EcmaString> stringKey = factory->NewFromStdString(keyArray);
312         JSHandle<JSTaggedValue> key(stringKey);
313 
314         // test set()
315         tset.Update(TaggedTreeSet::Add(thread, tset, key));
316         EXPECT_TRUE(TaggedTreeSet::FindEntry(thread, tset, key) >= 0);
317     }
318 
319     for (int i = 0; i < NODE_NUMBERS; i++) {
320         keyArray[5] = '1' + static_cast<uint32_t>(i); // 5 means index of keyArray
321         keyArray[6] = 0;       // 6 means index of keyArray
322         JSHandle<JSTaggedValue> stringKey(factory->NewFromStdString(keyArray));
323         // test get()#
324         EXPECT_TRUE(TaggedTreeSet::FindEntry(thread, tset, stringKey) >= 0);
325     }
326     EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS);
327     EXPECT_EQ(tset->Capacity(), 63); // 63 means capacity after Grow
328 }
329 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapHasValue)330 HWTEST_F_L0(TaggedTreeTest, TestTreeMapHasValue)
331 {
332     constexpr int NODE_NUMBERS = 8;
333     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
334     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
335     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
336     std::string myKey("mykey");
337     std::string myValue("myvalue");
338 
339     // test TaggedTreeMap HasValue
340     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
341     for (int i = 0; i < NODE_NUMBERS; i++) {
342         std::string ikey = myKey + std::to_string(i);
343         std::string ivalue = myValue + std::to_string(i);
344         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
345         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
346         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
347     }
348     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS);
349     EXPECT_EQ(tmap->Capacity(), 15); // 15 means capacity after Grow
350 
351     for (int i = 0; i < NODE_NUMBERS; i++) {
352         std::string ivalue = myValue + std::to_string(i);
353         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
354         bool success = tmap->HasValue(thread, value.GetTaggedValue());
355         EXPECT_TRUE(success);
356     }
357 }
358 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGetLowerKey)359 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGetLowerKey)
360 {
361     constexpr int NODE_NUMBERS = 8;
362     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
363     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
364     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
365     std::string myKey("mykey");
366     std::string myValue("myvalue");
367 
368     // test TaggedTreeMap
369     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
370     for (int i = 0; i < NODE_NUMBERS; i++) {
371         std::string ikey = myKey + std::to_string(i);
372         std::string ivalue = myValue + std::to_string(i);
373         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
374         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
375         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
376     }
377 
378     std::string minKey = myKey + std::to_string(0);
379     key.Update(factory->NewFromStdString(minKey).GetTaggedValue());
380     JSTaggedValue lowerKey = TaggedTreeMap::GetLowerKey(thread, tmap, key);
381     EXPECT_TRUE(lowerKey.IsUndefined());
382 
383     // add [1, 1]
384     key.Update(JSTaggedValue(1));
385     value.Update(JSTaggedValue(1));
386     tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
387 
388     key.Update(factory->NewFromStdString(minKey).GetTaggedValue());
389     lowerKey = TaggedTreeMap::GetLowerKey(thread, tmap, key);
390     EXPECT_EQ(lowerKey, JSTaggedValue(1));
391 
392     // check mykey1 ...mykeyn
393     JSMutableHandle<JSTaggedValue> keyToCompare(thread, JSTaggedValue::Undefined());
394     for (uint32_t i = 1; i < NODE_NUMBERS; i++) {
395         std::string ikey = myKey + std::to_string(i);
396         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
397         std::string tmp = myKey + std::to_string(i - 1);
398         keyToCompare.Update(factory->NewFromStdString(tmp).GetTaggedValue());
399         lowerKey = TaggedTreeMap::GetLowerKey(thread, tmap, key);
400         EXPECT_EQ(lowerKey, keyToCompare.GetTaggedValue());
401     }
402 }
403 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGetHigherKey)404 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGetHigherKey)
405 {
406     constexpr int NODE_NUMBERS = 8;
407     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
408     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
409     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
410 
411     // test TaggedTreeMap
412     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
413     for (int i = 0; i < NODE_NUMBERS; i++) {
414         key.Update(JSTaggedValue(i));
415         value.Update(JSTaggedValue(i));
416         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
417     }
418 
419     JSMutableHandle<JSTaggedValue> maxKey(thread, JSTaggedValue(NODE_NUMBERS - 1));
420     JSTaggedValue higherKey = TaggedTreeMap::GetHigherKey(thread, tmap, maxKey);
421     EXPECT_TRUE(higherKey.IsUndefined());
422 
423     // add [mykey, mykey]
424     std::string myKey("mykey");
425     key.Update(factory->NewFromStdString(myKey).GetTaggedValue());
426     tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
427 
428     higherKey = TaggedTreeMap::GetHigherKey(thread, tmap, maxKey);
429     EXPECT_EQ(higherKey, key.GetTaggedValue());
430 
431     // check 1 ...n
432     JSMutableHandle<JSTaggedValue> keyToCompare(thread, JSTaggedValue::Undefined());
433     for (int i = 0; i < NODE_NUMBERS - 1; i++) {
434         key.Update(JSTaggedValue(i));
435         keyToCompare.Update(JSTaggedValue(i + 1));
436         higherKey = TaggedTreeMap::GetHigherKey(thread, tmap, key);
437         EXPECT_EQ(higherKey, keyToCompare.GetTaggedValue());
438     }
439 }
440 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGetFirsKey)441 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGetFirsKey)
442 {
443     constexpr int NODE_NUMBERS = 8;
444     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
445     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
446     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
447     std::string myKey("mykey");
448     std::string myValue("myvalue");
449 
450     // test TaggedTreeMap
451     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
452     for (int i = 0; i < NODE_NUMBERS; i++) {
453         std::string ikey = myKey + std::to_string(i);
454         std::string ivalue = myValue + std::to_string(i);
455         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
456         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
457         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
458     }
459     std::string ckey = myKey + std::to_string(0);
460     key.Update(factory->NewFromStdString(ckey).GetTaggedValue());
461     JSTaggedValue firstKey = tmap->GetFirstKey();
462     EXPECT_EQ(firstKey, key.GetTaggedValue());
463 
464     for (int i = 0; i < NODE_NUMBERS; i++) {
465         key.Update(JSTaggedValue(i));
466         value.Update(JSTaggedValue(i));
467         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
468     }
469     firstKey = tmap->GetFirstKey();
470     EXPECT_EQ(firstKey, JSTaggedValue(0));
471 }
472 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGetLastKey)473 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGetLastKey)
474 {
475     constexpr int NODE_NUMBERS = 8;
476     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
477     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
478     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
479 
480     // test TaggedTreeMap
481     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
482     for (int i = 0; i < NODE_NUMBERS; i++) {
483         key.Update(JSTaggedValue(i));
484         value.Update(JSTaggedValue(i));
485         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
486     }
487     JSTaggedValue lastKey = tmap->GetLastKey();
488     EXPECT_EQ(lastKey, JSTaggedValue(NODE_NUMBERS - 1));
489 
490     std::string myKey("mykey");
491     std::string myValue("myvalue");
492     for (int i = 0; i < NODE_NUMBERS; i++) {
493         std::string ikey = myKey + std::to_string(i);
494         std::string ivalue = myValue + std::to_string(i);
495         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
496         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
497         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
498     }
499     std::string ckey = myKey + std::to_string(NODE_NUMBERS - 1);
500     key.Update(factory->NewFromStdString(ckey).GetTaggedValue());
501     lastKey = tmap->GetLastKey();
502     EXPECT_EQ(lastKey, key.GetTaggedValue());
503 }
504 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapSetAll)505 HWTEST_F_L0(TaggedTreeTest, TestTreeMapSetAll)
506 {
507     constexpr int NODE_NUMBERS = 8;
508     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
509     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
510     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
511 
512     // test TaggedTreeMap
513     JSMutableHandle<TaggedTreeMap> smap(thread, TaggedTreeMap::Create(thread));
514     for (int i = 0; i < NODE_NUMBERS; i++) {
515         key.Update(JSTaggedValue(i));
516         value.Update(JSTaggedValue(i));
517         smap.Update(TaggedTreeMap::Set(thread, smap, key, value));
518     }
519 
520     JSMutableHandle<TaggedTreeMap> dmap(thread, TaggedTreeMap::Create(thread));
521     std::string myKey("mykey");
522     std::string myValue("myvalue");
523     for (int i = 0; i < NODE_NUMBERS; i++) {
524         std::string ikey = myKey + std::to_string(i);
525         std::string ivalue = myValue + std::to_string(i);
526         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
527         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
528         dmap.Update(TaggedTreeMap::Set(thread, dmap, key, value));
529     }
530     dmap.Update(TaggedTreeMap::SetAll(thread, dmap, smap));
531 
532     for (int i = 0; i < NODE_NUMBERS; i++) {
533         key.Update(JSTaggedValue(i));
534         value.Update(JSTaggedValue(i));
535         JSTaggedValue res = TaggedTreeMap::Get(thread, dmap, key);
536         EXPECT_EQ(res, value.GetTaggedValue());
537 
538         std::string ikey = myKey + std::to_string(i);
539         std::string ivalue = myValue + std::to_string(i);
540         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
541         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
542         res = TaggedTreeMap::Get(thread, dmap, key);
543         EXPECT_EQ(res, value.GetTaggedValue());
544     }
545 }
546 
HWTEST_F_L0(TaggedTreeTest,TestTreeMapGetArrayFromMap)547 HWTEST_F_L0(TaggedTreeTest, TestTreeMapGetArrayFromMap)
548 {
549     constexpr int NODE_NUMBERS = 8;
550     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
551     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
552     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
553 
554     // test TaggedTreeMap
555     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
556     for (int i = 0; i < NODE_NUMBERS; i++) {
557         key.Update(JSTaggedValue(i));
558         value.Update(JSTaggedValue(i));
559         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
560     }
561 
562     std::string myKey("mykey");
563     std::string myValue("myvalue");
564     for (int i = 0; i < NODE_NUMBERS; i++) {
565         std::string ikey = myKey + std::to_string(i);
566         std::string ivalue = myValue + std::to_string(i);
567         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
568         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
569         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
570     }
571     JSHandle<TaggedArray> arr = TaggedTreeMap::GetArrayFromMap(thread, tmap);
572     EXPECT_EQ(static_cast<int>(arr->GetLength()), NODE_NUMBERS * 2);
573 
574     for (int i = 0; i < NODE_NUMBERS; i++) {
575         EXPECT_EQ(tmap->GetKey(arr->Get(i).GetInt()), JSTaggedValue(i));
576     }
577     for (int i = 0; i < NODE_NUMBERS; i++) {
578         std::string ikey = myKey + std::to_string(i);
579         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
580         EXPECT_EQ(tmap->GetKey(arr->Get(NODE_NUMBERS + i).GetInt()), key.GetTaggedValue());
581     }
582 }
583 
584 // TaggedTreeSet
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGetLowerKey)585 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGetLowerKey)
586 {
587     constexpr int NODE_NUMBERS = 8;
588     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
589     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
590     std::string myKey("mykey");
591 
592     // test TaggedTreeSet
593     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
594     for (int i = 0; i < NODE_NUMBERS; i++) {
595         std::string ikey = myKey + std::to_string(i);
596         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
597         tset.Update(TaggedTreeSet::Add(thread, tset, key));
598     }
599 
600     std::string minKey = myKey + std::to_string(0);
601     key.Update(factory->NewFromStdString(minKey).GetTaggedValue());
602     JSTaggedValue lowerKey = TaggedTreeSet::GetLowerKey(thread, tset, key);
603     EXPECT_TRUE(lowerKey.IsUndefined());
604 
605     // add [1, 1]
606     key.Update(JSTaggedValue(1));
607     tset.Update(TaggedTreeSet::Add(thread, tset, key));
608 
609     key.Update(factory->NewFromStdString(minKey).GetTaggedValue());
610     lowerKey = TaggedTreeSet::GetLowerKey(thread, tset, key);
611     EXPECT_EQ(lowerKey, JSTaggedValue(1));
612 
613     // check mykey1 ...mykeyn
614     JSMutableHandle<JSTaggedValue> keyToCompare(thread, JSTaggedValue::Undefined());
615     for (uint32_t i = 1; i < NODE_NUMBERS; i++) {
616         std::string ikey = myKey + std::to_string(i);
617         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
618         std::string tmp = myKey + std::to_string(i - 1);
619         keyToCompare.Update(factory->NewFromStdString(tmp).GetTaggedValue());
620         lowerKey = TaggedTreeSet::GetLowerKey(thread, tset, key);
621         EXPECT_EQ(lowerKey, keyToCompare.GetTaggedValue());
622     }
623 }
624 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGetHigherKey)625 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGetHigherKey)
626 {
627     constexpr int NODE_NUMBERS = 8;
628     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
629     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
630 
631     // test TaggedTreeSet
632     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
633     for (int i = 0; i < NODE_NUMBERS; i++) {
634         key.Update(JSTaggedValue(i));
635         tset.Update(TaggedTreeSet::Add(thread, tset, key));
636     }
637 
638     JSMutableHandle<JSTaggedValue> maxKey(thread, JSTaggedValue(NODE_NUMBERS - 1));
639     JSTaggedValue higherKey = TaggedTreeSet::GetHigherKey(thread, tset, maxKey);
640     EXPECT_TRUE(higherKey.IsUndefined());
641 
642     // add [mykey, mykey]
643     std::string myKey("mykey");
644     key.Update(factory->NewFromStdString(myKey).GetTaggedValue());
645     tset.Update(TaggedTreeSet::Add(thread, tset, key));
646 
647     higherKey = TaggedTreeSet::GetHigherKey(thread, tset, maxKey);
648     EXPECT_EQ(higherKey, key.GetTaggedValue());
649 
650     // check 1 ...n
651     JSMutableHandle<JSTaggedValue> keyToCompare(thread, JSTaggedValue::Undefined());
652     for (int i = 0; i < NODE_NUMBERS - 1; i++) {
653         key.Update(JSTaggedValue(i));
654         keyToCompare.Update(JSTaggedValue(i + 1));
655         higherKey = TaggedTreeSet::GetHigherKey(thread, tset, key);
656         EXPECT_EQ(higherKey, keyToCompare.GetTaggedValue());
657     }
658 }
659 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGetFirsKey)660 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGetFirsKey)
661 {
662     constexpr int NODE_NUMBERS = 8;
663     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
664     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
665     std::string myKey("mykey");
666 
667     // test TaggedTreeSet
668     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
669     for (int i = 0; i < NODE_NUMBERS; i++) {
670         std::string ikey = myKey + std::to_string(i);
671         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
672         tset.Update(TaggedTreeSet::Add(thread, tset, key));
673     }
674     std::string ckey = myKey + std::to_string(0);
675     key.Update(factory->NewFromStdString(ckey).GetTaggedValue());
676     JSTaggedValue firstKey = tset->GetFirstKey();
677     EXPECT_EQ(firstKey, key.GetTaggedValue());
678 
679     for (int i = 0; i < NODE_NUMBERS; i++) {
680         key.Update(JSTaggedValue(i));
681         tset.Update(TaggedTreeSet::Add(thread, tset, key));
682     }
683     firstKey = tset->GetFirstKey();
684     EXPECT_EQ(firstKey, JSTaggedValue(0));
685 }
686 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGetLastKey)687 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGetLastKey)
688 {
689     constexpr int NODE_NUMBERS = 8;
690     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
691     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
692 
693     // test TaggedTreeSet
694     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
695     for (int i = 0; i < NODE_NUMBERS; i++) {
696         key.Update(JSTaggedValue(i));
697         tset.Update(TaggedTreeSet::Add(thread, tset, key));
698     }
699     JSTaggedValue lastKey = tset->GetLastKey();
700     EXPECT_EQ(lastKey, JSTaggedValue(NODE_NUMBERS - 1));
701 
702     std::string myKey("mykey");
703     for (int i = 0; i < NODE_NUMBERS; i++) {
704         std::string ikey = myKey + std::to_string(i);
705         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
706         tset.Update(TaggedTreeSet::Add(thread, tset, key));
707     }
708     std::string ckey = myKey + std::to_string(NODE_NUMBERS - 1);
709     key.Update(factory->NewFromStdString(ckey).GetTaggedValue());
710     lastKey = tset->GetLastKey();
711     EXPECT_EQ(lastKey, key.GetTaggedValue());
712 }
713 
HWTEST_F_L0(TaggedTreeTest,TestTreeSetGetArrayFromSet)714 HWTEST_F_L0(TaggedTreeTest, TestTreeSetGetArrayFromSet)
715 {
716     constexpr int NODE_NUMBERS = 8;
717     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
718     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
719 
720     // test TaggedTreeSet
721     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
722     for (int i = 0; i < NODE_NUMBERS; i++) {
723         key.Update(JSTaggedValue(i));
724         tset.Update(TaggedTreeSet::Add(thread, tset, key));
725     }
726 
727     std::string myKey("mykey");
728     for (int i = 0; i < NODE_NUMBERS; i++) {
729         std::string ikey = myKey + std::to_string(i);
730         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
731         tset.Update(TaggedTreeSet::Add(thread, tset, key));
732     }
733     JSHandle<TaggedArray> arr = TaggedTreeSet::GetArrayFromSet(thread, tset);
734     EXPECT_EQ(static_cast<int>(arr->GetLength()), NODE_NUMBERS * 2);
735 
736     for (int i = 0; i < NODE_NUMBERS; i++) {
737         EXPECT_EQ(tset->GetKey(arr->Get(i).GetInt()), JSTaggedValue(i));
738     }
739     for (int i = 0; i < NODE_NUMBERS; i++) {
740         std::string ikey = myKey + std::to_string(i);
741         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
742         EXPECT_EQ(tset->GetKey(arr->Get(NODE_NUMBERS + i).GetInt()), key.GetTaggedValue());
743     }
744 }
745 
HWTEST_F_L0(TaggedTreeTest,TestSetAfterDelete)746 HWTEST_F_L0(TaggedTreeTest, TestSetAfterDelete)
747 {
748     constexpr int NODE_NUMBERS = 8;
749     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
750     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
751     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
752 
753     // test TaggedTreeMap
754     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
755     for (int i = 0; i < NODE_NUMBERS; i++) {
756         key.Update(JSTaggedValue(i));
757         value.Update(JSTaggedValue(i));
758         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
759     }
760     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS);
761     EXPECT_EQ(tmap->NumberOfDeletedElements(), 0);
762 
763     for (int i = 0; i < NODE_NUMBERS / 2; i++) {
764         key.Update(JSTaggedValue(i));
765         value.Update(JSTaggedValue(i));
766         JSTaggedValue dvalue = TaggedTreeMap::Delete(thread, tmap, TaggedTreeMap::FindEntry(thread, tmap, key));
767         EXPECT_EQ(dvalue, tmap.GetTaggedValue());
768     }
769     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS / 2);
770     EXPECT_EQ(tmap->NumberOfDeletedElements(), NODE_NUMBERS / 2);
771 
772     std::string myKey("mykey");
773     std::string myValue("myvalue");
774     for (int i = 0; i < NODE_NUMBERS; i++) {
775         std::string ikey = myKey + std::to_string(i);
776         std::string ivalue = myValue + std::to_string(i);
777         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
778         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
779         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
780     }
781     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS + NODE_NUMBERS / 2);
782     EXPECT_EQ(tmap->NumberOfDeletedElements(), 0);
783 
784     for (uint32_t i = NODE_NUMBERS / 2; i < NODE_NUMBERS; i++) {
785         key.Update(JSTaggedValue(i));
786         value.Update(JSTaggedValue(i));
787         JSTaggedValue gvalue = TaggedTreeMap::Get(thread, tmap, key);
788         EXPECT_EQ(gvalue, value.GetTaggedValue());
789     }
790 
791     for (int i = 0; i < NODE_NUMBERS; i++) {
792         std::string ikey = myKey + std::to_string(i);
793         std::string ivalue = myValue + std::to_string(i);
794         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
795         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
796         JSTaggedValue gvalue = TaggedTreeMap::Get(thread, tmap, key);
797         EXPECT_EQ(gvalue, value.GetTaggedValue());
798     }
799     EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS + NODE_NUMBERS / 2);
800     EXPECT_EQ(tmap->Capacity(), 31); // 31 means capacity after grow
801 
802     // TaggedTreeSet
803     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
804     for (int i = 0; i < NODE_NUMBERS; i++) {
805         key.Update(JSTaggedValue(i));
806         tset.Update(TaggedTreeSet::Add(thread, tset, key));
807     }
808     EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS);
809     EXPECT_EQ(tset->NumberOfDeletedElements(), 0);
810 
811     for (int i = 0; i < NODE_NUMBERS / 2; i++) {
812         key.Update(JSTaggedValue(i));
813         JSTaggedValue dvalue = TaggedTreeSet::Delete(thread, tset, TaggedTreeSet::FindEntry(thread, tset, key));
814         EXPECT_EQ(dvalue, tset.GetTaggedValue());
815     }
816     EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS / 2);
817     EXPECT_EQ(tset->NumberOfDeletedElements(), NODE_NUMBERS / 2);
818 
819     for (int i = 0; i < NODE_NUMBERS; i++) {
820         std::string ikey = myKey + std::to_string(i);
821         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
822         tset.Update(TaggedTreeSet::Add(thread, tset, key));
823     }
824     EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS + NODE_NUMBERS / 2);
825     EXPECT_EQ(tset->NumberOfDeletedElements(), 0);
826 
827     for (uint32_t i = NODE_NUMBERS / 2; i < NODE_NUMBERS; i++) {
828         key.Update(JSTaggedValue(i));
829         int entry = TaggedTreeSet::FindEntry(thread, tset, key);
830         EXPECT_TRUE(entry >= 0);
831     }
832 
833     for (int i = 0; i < NODE_NUMBERS; i++) {
834         std::string ikey = myKey + std::to_string(i);
835         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
836         int entry = TaggedTreeSet::FindEntry(thread, tset, key);
837         EXPECT_TRUE(entry >= 0);
838     }
839     EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS + NODE_NUMBERS / 2);
840     EXPECT_EQ(tset->Capacity(), 31); // 31 means capacity after grow
841 }
842 
HWTEST_F_L0(TaggedTreeTest,RBTreeAddCheck)843 HWTEST_F_L0(TaggedTreeTest, RBTreeAddCheck)
844 {
845     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
846     constexpr int NODE_NUMBERS = 16;
847     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
848     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
849     std::string myKey("mykey");
850     std::string myValue("myvalue");
851 
852     // test TaggedTreeMap
853     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
854     for (int i = 0; i < NODE_NUMBERS; i++) {
855         key.Update(JSTaggedValue(i));
856         value.Update(JSTaggedValue(i));
857         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
858         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
859         EXPECT_TRUE(success);
860     }
861     for (int i = 0; i < NODE_NUMBERS; i++) {
862         std::string ikey = myKey + std::to_string(i);
863         std::string ivalue = myValue + std::to_string(i);
864         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
865         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
866         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
867         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
868         EXPECT_TRUE(success);
869     }
870     EXPECT_TRUE(tmap->NumberOfElements() == NODE_NUMBERS * 2);
871 
872     // test TaggedTreeSet
873     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
874     for (int i = 0; i < NODE_NUMBERS; i++) {
875         key.Update(JSTaggedValue(i));
876         tset.Update(TaggedTreeSet::Add(thread, tset, key));
877         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
878         EXPECT_TRUE(success);
879     }
880     for (int i = 0; i < NODE_NUMBERS; i++) {
881         std::string ikey = myKey + std::to_string(i);
882         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
883         tset.Update(TaggedTreeSet::Add(thread, tset, key));
884         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
885         EXPECT_TRUE(success);
886     }
887     EXPECT_TRUE(tset->NumberOfElements() == NODE_NUMBERS * 2);
888 }
889 
HWTEST_F_L0(TaggedTreeTest,RBTreeDeleteCheck)890 HWTEST_F_L0(TaggedTreeTest, RBTreeDeleteCheck)
891 {
892     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
893     constexpr int NODE_NUMBERS = 16;
894     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
895     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
896     std::string myKey("mykey");
897     std::string myValue("myvalue");
898 
899     // test TaggedTreeMap
900     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
901     for (int i = 0; i < NODE_NUMBERS; i++) {
902         key.Update(JSTaggedValue(i));
903         value.Update(JSTaggedValue(i));
904         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
905         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
906         EXPECT_TRUE(success);
907     }
908     for (int i = 0; i < NODE_NUMBERS; i++) {
909         std::string ikey = myKey + std::to_string(i);
910         std::string ivalue = myValue + std::to_string(i);
911         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
912         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
913         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
914         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
915         EXPECT_TRUE(success);
916     }
917 
918     JSMutableHandle<JSTaggedValue> resOfDelete(thread, JSTaggedValue::Undefined());
919     for (int i = 0; i < NODE_NUMBERS; i++) {
920         key.Update(JSTaggedValue(i));
921         resOfDelete.Update(TaggedTreeMap::Delete(thread, tmap, TaggedTreeMap::FindEntry(thread, tmap, key)));
922         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
923         EXPECT_TRUE(success);
924         EXPECT_EQ(resOfDelete.GetTaggedValue(), tmap.GetTaggedValue());
925     }
926     EXPECT_TRUE(tmap->NumberOfElements() == NODE_NUMBERS);
927 
928     // test TaggedTreeSet
929     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
930     for (int i = 0; i < NODE_NUMBERS; i++) {
931         key.Update(JSTaggedValue(i));
932         tset.Update(TaggedTreeSet::Add(thread, tset, key));
933         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
934         EXPECT_TRUE(success);
935     }
936     for (int i = 0; i < NODE_NUMBERS; i++) {
937         std::string ikey = myKey + std::to_string(i);
938         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
939         tset.Update(TaggedTreeSet::Add(thread, tset, key));
940         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
941         EXPECT_TRUE(success);
942     }
943 
944     for (int i = 0; i < NODE_NUMBERS; i++) {
945         key.Update(JSTaggedValue(i));
946         resOfDelete.Update(TaggedTreeSet::Delete(thread, tset, TaggedTreeSet::FindEntry(thread, tset, key)));
947         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
948         EXPECT_TRUE(success);
949         EXPECT_EQ(resOfDelete.GetTaggedValue(), tset.GetTaggedValue());
950     }
951     EXPECT_TRUE(tset->NumberOfElements() == NODE_NUMBERS);
952 }
953 
HWTEST_F_L0(TaggedTreeTest,CustomCompareFunctionTest)954 HWTEST_F_L0(TaggedTreeTest, CustomCompareFunctionTest)
955 {
956     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
957     constexpr int NODE_NUMBERS = 9;
958     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
959     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
960     std::string myKey("mykey");
961     std::string myValue("myvalue");
962 
963     // test TaggedTreeMap
964     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
965     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
966     JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
967     tmap->SetCompare(thread, func.GetTaggedValue());
968     for (int i = 0; i < NODE_NUMBERS; i++) {
969         key.Update(JSTaggedValue(i));
970         value.Update(JSTaggedValue(i));
971         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
972         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
973         EXPECT_TRUE(success);
974     }
975     for (int i = 0; i < NODE_NUMBERS; i++) {
976         std::string ikey = myKey + std::to_string(i);
977         std::string ivalue = myValue + std::to_string(i);
978         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
979         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
980         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
981         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
982         EXPECT_TRUE(success);
983     }
984     EXPECT_TRUE(tmap->NumberOfElements() == NODE_NUMBERS * 2);
985 
986     JSHandle<TaggedArray> arr = TaggedTreeMap::GetArrayFromMap(thread, tmap);
987     EXPECT_EQ(static_cast<int>(arr->GetLength()), NODE_NUMBERS * 2);
988     for (int i = NODE_NUMBERS; i < NODE_NUMBERS * 2; i++) {
989         EXPECT_EQ(tmap->GetKey(arr->Get(i).GetInt()).GetInt(), (NODE_NUMBERS * 2  - 1 - i));
990     }
991     for (int i = 0; i < NODE_NUMBERS; i++) {
992         std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
993         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
994         EXPECT_EQ(tmap->GetKey(arr->Get(i).GetInt()), key.GetTaggedValue());
995     }
996 
997     // test TaggedTreeSet
998     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
999     tset->SetCompare(thread, func.GetTaggedValue());
1000     for (int i = 0; i < NODE_NUMBERS; i++) {
1001         key.Update(JSTaggedValue(i));
1002         tset.Update(TaggedTreeSet::Add(thread, tset, key));
1003         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
1004         EXPECT_TRUE(success);
1005     }
1006     for (int i = 0; i < NODE_NUMBERS; i++) {
1007         std::string ikey = myKey + std::to_string(i);
1008         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1009         tset.Update(TaggedTreeSet::Add(thread, tset, key));
1010         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
1011         EXPECT_TRUE(success);
1012     }
1013     EXPECT_TRUE(tset->NumberOfElements() == NODE_NUMBERS * 2);
1014 
1015     JSHandle<TaggedArray> sarr = TaggedTreeSet::GetArrayFromSet(thread, tset);
1016     EXPECT_EQ(static_cast<int>(arr->GetLength()), NODE_NUMBERS * 2);
1017     for (int i = NODE_NUMBERS; i < NODE_NUMBERS * 2; i++) {
1018         EXPECT_EQ(tset->GetKey(sarr->Get(i).GetInt()), JSTaggedValue(NODE_NUMBERS * 2  - 1 - i));
1019     }
1020     for (int i = 0; i < NODE_NUMBERS; i++) {
1021         std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1022         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1023         EXPECT_EQ(tset->GetKey(sarr->Get(i).GetInt()), key.GetTaggedValue());
1024     }
1025 }
1026 
HWTEST_F_L0(TaggedTreeTest,RBTreeDeleteShrink)1027 HWTEST_F_L0(TaggedTreeTest, RBTreeDeleteShrink)
1028 {
1029     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1030     constexpr int NODE_NUMBERS = 32;
1031     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1032     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1033     std::string myKey("mykey");
1034     std::string myValue("myvalue");
1035 
1036     // test TaggedTreeMap
1037     JSMutableHandle<TaggedTreeMap> tmap(thread, TaggedTreeMap::Create(thread));
1038     for (int i = 0; i < NODE_NUMBERS; i++) {
1039         key.Update(JSTaggedValue(i));
1040         value.Update(JSTaggedValue(i));
1041         tmap.Update(TaggedTreeMap::Set(thread, tmap, key, value));
1042         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
1043         EXPECT_TRUE(success);
1044     }
1045 
1046     JSMutableHandle<JSTaggedValue> resOfDelete(thread, JSTaggedValue::Undefined());
1047     for (int i = 0; i < NODE_NUMBERS / 2; i++) {
1048         key.Update(JSTaggedValue(i));
1049         resOfDelete.Update(TaggedTreeMap::Delete(thread, tmap, TaggedTreeMap::FindEntry(thread, tmap, key)));
1050         bool success = IsVaildRBTree<TaggedTreeMap>(thread, tmap, tmap->GetRootEntries());
1051         EXPECT_TRUE(success);
1052         EXPECT_EQ(resOfDelete.GetTaggedValue(), tmap.GetTaggedValue());
1053     }
1054 
1055     {
1056         EXPECT_EQ(tmap->Capacity(), NODE_NUMBERS * 2 - 1);
1057         key.Update(JSTaggedValue(NODE_NUMBERS / 2));
1058         resOfDelete.Update(TaggedTreeMap::Delete(thread, tmap, TaggedTreeMap::FindEntry(thread, tmap, key)));
1059         EXPECT_NE(resOfDelete.GetTaggedValue(), tmap.GetTaggedValue());
1060 
1061         key.Update(JSTaggedValue(NODE_NUMBERS / 2 + 1));
1062         JSHandle<TaggedTreeMap> newMap = JSHandle<TaggedTreeMap>::Cast(resOfDelete);
1063         resOfDelete.Update(TaggedTreeMap::Delete(thread, newMap, TaggedTreeMap::FindEntry(thread, newMap, key)));
1064         EXPECT_EQ(tmap->NumberOfElements(), NODE_NUMBERS / 2 - 1);
1065         EXPECT_EQ(newMap->NumberOfElements(), NODE_NUMBERS / 2 - 2); // 2 means two elements
1066         bool success = IsVaildRBTree<TaggedTreeMap>(thread, newMap, newMap->GetRootEntries());
1067         EXPECT_TRUE(success);
1068         EXPECT_EQ(newMap->Capacity(), NODE_NUMBERS - 1);
1069     }
1070 
1071     // test TaggedTreeSet
1072     JSMutableHandle<TaggedTreeSet> tset(thread, TaggedTreeSet::Create(thread));
1073     for (int i = 0; i < NODE_NUMBERS; i++) {
1074         std::string ikey = myKey + std::to_string(i);
1075         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1076         tset.Update(TaggedTreeSet::Add(thread, tset, key));
1077         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
1078         EXPECT_TRUE(success);
1079     }
1080 
1081     for (int i = 0; i < NODE_NUMBERS / 2; i++) {
1082         std::string ikey = myKey + std::to_string(i);
1083         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1084         resOfDelete.Update(TaggedTreeSet::Delete(thread, tset, TaggedTreeSet::FindEntry(thread, tset, key)));
1085         bool success = IsVaildRBTree<TaggedTreeSet>(thread, tset, tset->GetRootEntries());
1086         EXPECT_TRUE(success);
1087         EXPECT_EQ(resOfDelete.GetTaggedValue(), tset.GetTaggedValue());
1088     }
1089 
1090     {
1091         EXPECT_EQ(tset->Capacity(), NODE_NUMBERS * 2 - 1);
1092         std::string ikey = myKey + std::to_string(NODE_NUMBERS / 2);
1093         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1094         resOfDelete.Update(TaggedTreeSet::Delete(thread, tset, TaggedTreeSet::FindEntry(thread, tset, key)));
1095         EXPECT_NE(resOfDelete.GetTaggedValue(), tset.GetTaggedValue());
1096 
1097         ikey = myKey + std::to_string(NODE_NUMBERS / 2 + 1);
1098         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1099         JSHandle<TaggedTreeSet> newSet = JSHandle<TaggedTreeSet>::Cast(resOfDelete);
1100         resOfDelete.Update(TaggedTreeSet::Delete(thread, newSet, TaggedTreeSet::FindEntry(thread, newSet, key)));
1101         EXPECT_EQ(tset->NumberOfElements(), NODE_NUMBERS / 2 - 1);
1102         EXPECT_EQ(newSet->NumberOfElements(), NODE_NUMBERS / 2 - 2);
1103         bool success = IsVaildRBTree<TaggedTreeSet>(thread, newSet, newSet->GetRootEntries());
1104         EXPECT_TRUE(success);
1105         EXPECT_EQ(newSet->Capacity(), NODE_NUMBERS - 1);
1106     }
1107 }
1108 }  // namespace panda::test
1109