Files
oceanbase/deps/oblib/unittest/lib/resource/test_resource_limiter.cpp
2024-11-23 18:14:57 +00:00

147 lines
4.2 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#define private public
#include "lib/resource/ob_resource_limiter.h"
using namespace oceanbase::lib;
TEST(TestResourceLimiter, basic)
{
int64_t max = 1LL<<30;
ObResourceLimiter root(max, 0);
ObResourceLimiter l1(max, 0);
ObResourceLimiter l2(max, 0);
ASSERT_EQ(NULL, root.child_);
ASSERT_EQ(NULL, l1.parent_);
ASSERT_EQ(NULL, l2.parent_);
root.add_child(&l1);
ASSERT_EQ(&l1, root.child_);
ASSERT_EQ(&root, l1.parent_);
root.add_child(&l2);
ASSERT_EQ(&l2, root.child_);
ASSERT_EQ(&root, l2.parent_);
root.del_child(&l2);
root.del_child(&l1);
ASSERT_EQ(NULL, root.child_);
ASSERT_EQ(NULL, l1.parent_);
ASSERT_EQ(NULL, l2.parent_);
int64_t size = 1<<10;
root.add_child(&l1);
ASSERT_EQ(0, root.hold_);
l1.acquire(size);
ASSERT_EQ(size, root.hold_);
root.del_child(&l1);
ASSERT_EQ(0, root.hold_);
root.add_child(&l1);
ASSERT_EQ(size, root.hold_);
}
TEST(TestResourceLimiter, max)
{
// create resource limiter tree.
int64_t max = 1LL<<30;
int64_t max_1 = 256<<20;
int64_t max_2 = INT64_MAX;
ObResourceLimiter root(max, 0);
ObResourceLimiter l1(max_1, 0);
ObResourceLimiter l2(max_2, 0);
root.add_child(&l1);
root.add_child(&l2);
ASSERT_EQ(l1.hold_, 0);
ASSERT_EQ(l2.hold_, 0);
ASSERT_EQ(root.hold_, 0);
// acquire succeed when limiter.hold_ <= limiter.max_.
ASSERT_EQ(false, l1.acquire(max_1 + 1));
ASSERT_EQ(true, l1.acquire(max_1));
ASSERT_EQ(l1.hold_, max_1);
ASSERT_EQ(root.hold_, max_1);
ASSERT_EQ(false, l2.acquire(max - max_1 + 1));
ASSERT_EQ(true, l2.acquire(max - max_1));
ASSERT_EQ(l1.hold_, max_1);
ASSERT_EQ(l2.hold_, max - max_1);
ASSERT_EQ(root.hold_, max);
}
TEST(TestResourceLimiter, min)
{
// create resource limiter tree.
int64_t max = 1LL<<30;
int64_t min_1 = 256<<20;
int64_t min_2 = max - min_1 + 1;
ObResourceLimiter root(max, 0);
ObResourceLimiter l1(INT64_MAX, min_1);
ObResourceLimiter l2(INT64_MAX, min_2);
root.add_child(&l1);
root.add_child(&l2);
// l2 can keep reservered resource when min_2 <= max - min_1.
ASSERT_EQ(l1.hold_, min_1);
ASSERT_EQ(l2.hold_, 0);
min_2 = max - min_1;
l2.set_min(min_2);
ASSERT_EQ(l2.hold_, min_2);
// the reservered resource cannot be hold by other limiter
ASSERT_EQ(true, l1.acquire(max-min_2));
ASSERT_EQ(false, l1.acquire(1));
}
TEST(TestResourceLimiter, acquire)
{
// create resource limiter tree.
int64_t max = 1LL<<30;
int64_t min_1 = 256<<20;
int64_t min_2 = 128<<20;
ObResourceLimiter root(max, 0);
ObResourceLimiter l1(INT64_MAX, min_1);
ObResourceLimiter l2(INT64_MAX, min_2);
root.add_child(&l1);
root.add_child(&l2);
// prioritize applying for resources from cache
int64_t hold = min_1;
int64_t cache = min_1;
ASSERT_EQ(hold, l1.hold_);
ASSERT_EQ(cache, l1.cache_);
ASSERT_EQ(true, l1.acquire(1024));
cache -= 1024;
ASSERT_EQ(cache, l1.cache_);
// applying for resources from parent when cache is not enough
ASSERT_EQ(true, l1.acquire(cache + 1));
hold += cache + 1;
ASSERT_EQ(hold, l1.hold_);
ASSERT_EQ(cache, l1.cache_);
// prioritize releasing resources to parent
int64_t p_hold = root.hold_;
ASSERT_EQ(true, l1.acquire(-1024));
hold -= 1024;
p_hold -= 1024;
ASSERT_EQ(hold, l1.hold_);
ASSERT_EQ(cache, l1.cache_);
ASSERT_EQ(p_hold, root.hold_);
// releasing resources to cache when hold will less than the reserver
ASSERT_EQ(true, l1.acquire(-(hold - min_1 + 1)));
cache += (hold - min_1 + 1);
ASSERT_EQ(hold, l1.hold_);
ASSERT_EQ(cache, l1.cache_);
ASSERT_EQ(p_hold, root.hold_);
}
int main(int argc, char *argv[])
{
OB_LOGGER.set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}