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