|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /**
- * Copyright 2019 Huawei Technologies Co., Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include <sstream>
- #include "minddata/dataset/util/btree.h"
- #include "minddata/dataset/util/auto_index.h"
- #include "minddata/dataset/util/system_pool.h"
- #include "minddata/dataset/util/task_manager.h"
- #include "common/common.h"
- #include "gtest/gtest.h"
- #include "utils/log_adapter.h"
-
- using namespace mindspore::dataset;
- using mindspore::MsLogLevel::INFO;
- using mindspore::ExceptionType::NoExceptionType;
- using mindspore::LogStream;
-
- // For testing purposes, we will make the branching factor very low.
- struct mytraits {
- using slot_type = uint16_t;
- static const slot_type kLeafSlots = 6;
- static const slot_type kInnerSlots = 3;
- };
-
-
- class MindDataTestBPlusTree : public UT::Common {
- public:
- MindDataTestBPlusTree() = default;
- };
-
- // Test serial insert.
- TEST_F(MindDataTestBPlusTree, Test1) {
- Allocator<std::string> alloc(std::make_shared<SystemPool>());
- BPlusTree<uint64_t, std::string, Allocator<std::string>, std::less<uint64_t>, mytraits> btree(alloc);
- Status rc;
- for (int i = 0; i < 100; i++) {
- uint64_t key = 2 * i;
- std::ostringstream oss;
- oss << "Hello World. I am " << key;
- rc = btree.DoInsert(key, oss.str());
- EXPECT_TRUE(rc.IsOk());
- }
- for (int i = 0; i < 100; i++) {
- uint64_t key = 2 * i + 1;
- std::ostringstream oss;
- oss << "Hello World. I am " << key;
- rc = btree.DoInsert(key, oss.str());
- EXPECT_TRUE(rc.IsOk());
- }
- EXPECT_EQ(btree.size(), 200);
-
- // Test iterator
- {
- int cnt = 0;
- auto it = btree.begin();
- uint64_t prev = it.key();
- ++it;
- ++cnt;
- while (it != btree.end()) {
- uint64_t cur = it.key();
- std::string val = "Hello World. I am " + std::to_string(cur);
- EXPECT_TRUE(prev < cur);
- EXPECT_EQ(it.value(), val);
- prev = cur;
- ++it;
- ++cnt;
- }
- EXPECT_EQ(cnt, 200);
- // Now go backward
- for (int i = 0; i < 10; i++) {
- --it;
- EXPECT_EQ(199 - i, it.key());
- }
- }
-
- // Test search
- {
- MS_LOG(INFO) << "Locate key " << 100 << " Expect found.";
- auto r = btree.Search(100);
- auto &it = r.first;
- EXPECT_TRUE(r.second);
- EXPECT_EQ(it.key(), 100);
- EXPECT_EQ(it.value(), "Hello World. I am 100");
- MS_LOG(INFO) << "Locate key " << 300 << " Expect not found.";
- auto q = btree.Search(300);
- EXPECT_FALSE(q.second);
- }
-
- // Test duplicate key
- {
- rc = btree.DoInsert(100, "Expect error");
- EXPECT_EQ(rc, Status(StatusCode::kDuplicateKey));
- }
- }
-
- // Test concurrent insert.
- TEST_F(MindDataTestBPlusTree, Test2) {
- Allocator<std::string> alloc(std::make_shared<SystemPool>());
- BPlusTree<uint64_t, std::string, Allocator<std::string>, std::less<uint64_t>, mytraits> btree(alloc);
- TaskGroup vg;
- auto f = [&](int k) -> Status {
- TaskManager::FindMe()->Post();
- for (int i = 0; i < 100; i++) {
- uint64_t key = k * 100 + i;
- std::ostringstream oss;
- oss << "Hello World. I am " << key;
- Status rc = btree.DoInsert(key, oss.str());
- EXPECT_TRUE(rc.IsOk());
- }
- return Status::OK();
- };
- auto g = [&](int k) -> Status {
- TaskManager::FindMe()->Post();
- for (int i = 0; i < 1000; i++) {
- uint64_t key = rand() % 10000;;
- auto it = btree.Search(key);
- }
- return Status::OK();
- };
- // Spawn multiple threads to do insert.
- for (int k = 0; k < 100; k++) {
- vg.CreateAsyncTask("Concurrent Insert", std::bind(f, k));
- }
- // Spawn a few threads to do random search.
- for (int k = 0; k < 2; k++) {
- vg.CreateAsyncTask("Concurrent search", std::bind(g, k));
- }
- vg.join_all();
- EXPECT_EQ(btree.size(), 10000);
-
- // Test iterator
- {
- int cnt = 0;
- auto it = btree.begin();
- uint64_t prev = it.key();
- ++it;
- ++cnt;
- while (it != btree.end()) {
- uint64_t cur = it.key();
- std::string val = "Hello World. I am " + std::to_string(cur);
- EXPECT_TRUE(prev < cur);
- EXPECT_EQ(it.value(), val);
- prev = cur;
- ++it;
- ++cnt;
- }
- EXPECT_EQ(cnt, 10000);
- }
-
- // Test search
- {
- MS_LOG(INFO) << "Locating key from 0 to 9999. Expect found.";
- for (int i = 0; i < 10000; i++) {
- auto r = btree.Search(i);
- EXPECT_TRUE(r.second);
- if (r.second) {
- auto &it = r.first;
- EXPECT_EQ(it.key(), i);
- std::string val = "Hello World. I am " + std::to_string(i);
- EXPECT_EQ(it.value(), val);
- }
- }
- MS_LOG(INFO) << "Locate key " << 10000 << ". Expect not found";
- auto q = btree.Search(10000);
- EXPECT_FALSE(q.second);
- }
- }
-
- TEST_F(MindDataTestBPlusTree, Test3) {
- Allocator<std::string> alloc(std::make_shared<SystemPool>());
- AutoIndexObj<std::string, Allocator<std::string>> ai(alloc);
- Status rc;
- rc = ai.insert("Hello World");
- EXPECT_TRUE(rc.IsOk());
- rc = ai.insert({"a", "b", "c"});
- EXPECT_TRUE(rc.IsOk());
- uint64_t min = ai.min_key();
- uint64_t max = ai.max_key();
- EXPECT_EQ(min, 0);
- EXPECT_EQ(max, 3);
- auto r = ai.Search(2);
- auto &it = r.first;
- EXPECT_EQ(it.value(), "b");
- MS_LOG(INFO) << "Dump all the values using [] operator.";
- for (uint64_t i = min; i <= max; i++) {
- MS_LOG(DEBUG) << ai[i] << std::endl;
- }
- }
-
- TEST_F(MindDataTestBPlusTree, Test4) {
- Allocator<int64_t> alloc(std::make_shared<SystemPool>());
- AutoIndexObj<int64_t, Allocator<int64_t>> ai(alloc);
- Status rc;
- for (int i = 0; i < 1000; i++) {
- rc = ai.insert(std::make_unique<int64_t>(i));
- EXPECT_TRUE(rc.IsOk());
- }
- // Test iterator
- {
- int cnt = 0;
- auto it = ai.begin();
- uint64_t prev = it.key();
- ++it;
- ++cnt;
- while (it != ai.end()) {
- uint64_t cur = it.key();
- EXPECT_TRUE(prev < cur);
- EXPECT_EQ(it.value(), cnt);
- prev = cur;
- ++it;
- ++cnt;
- }
- EXPECT_EQ(cnt, 1000);
- }
- }
|