Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions src/mds/filesystem/partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ static const std::string kPartitionMetricsPrefix = "dingofs_{}_partition_cache_{
DEFINE_uint32(mds_partition_cache_shard_max_count, 4 * 1024 * 1024, "partition cache shard max count");
DEFINE_uint32(mds_partition_dentry_op_max_count, 100000, "partition dentry op max count");

DEFINE_uint32(mds_partition_shard_split_threshold, 10000, "split shard when dentry count exceeds this");

const uint32_t kDentryDefaultNum = 1024;
DEFINE_uint32(mds_partition_shard_split_threshold, 8192, "split shard when dentry count exceeds this");

// --- DirShard implementation ---

Expand Down Expand Up @@ -133,24 +131,21 @@ size_t DirShard::Bytes() const {
std::pair<DirShardSPtr, DirShardSPtr> DirShard::Split(const std::string& key, uint64_t left_id, uint64_t right_id) {
utils::WriteLockGuard lk(lock_);

std::vector<Dentry> left_dentries, right_dentries;
left_dentries.reserve(kDentryDefaultNum);
right_dentries.reserve(kDentryDefaultNum);

absl::btree_map<std::string, Dentry> left_dentries, right_dentries;
for (auto& it : children_) {
if (it.first < key) {
left_dentries.push_back(it.second);
left_dentries[it.first] = it.second;
} else {
right_dentries.push_back(it.second);
right_dentries[it.first] = it.second;
}
}

// [start, key), [key, end)
Range left_range{range_.start, key};
Range right_range{key, range_.end};

DirShardSPtr left_shard = DirShard::New(left_id, left_range, version_, left_dentries);
DirShardSPtr right_shard = DirShard::New(right_id, right_range, version_, right_dentries);
DirShardSPtr left_shard = DirShard::New(left_id, left_range, version_, std::move(left_dentries));
DirShardSPtr right_shard = DirShard::New(right_id, right_range, version_, std::move(right_dentries));

return {left_shard, right_shard};
}
Expand Down Expand Up @@ -469,10 +464,10 @@ void ShardPartition::DeleteShardNoLock(const std::string& start) { shard_map_.er

Status ShardPartition::FetchDirShard(const Range& range, DirShardSPtr& out_shard) {
utils::Duration duration;
std::vector<Dentry> dentries;
absl::btree_map<std::string, Dentry> dentries;
Trace trace;
ScanDirShardOperation operation(trace, fs_id_, ino_, range, [&dentries](const DentryEntry& dentry) -> bool {
dentries.push_back(Dentry(dentry));
dentries[dentry.name()] = Dentry(dentry);
return true;
});

Expand All @@ -483,7 +478,8 @@ Status ShardPartition::FetchDirShard(const Range& range, DirShardSPtr& out_shard

uint64_t version = result.attr.version();

out_shard = DirShard::New(NextShardID(), range, version, dentries);
out_shard = DirShard::New(NextShardID(), range, version, std::move(dentries));

PutShard(out_shard);

LOG(INFO) << fmt::format("[partition.{}.{}][{}us] fetch dir shard, range{} {}.", fs_id_, ino_, duration.ElapsedUs(),
Expand Down
11 changes: 11 additions & 0 deletions src/mds/filesystem/partition.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,22 @@ class DirShard {
}
last_active_time_s_ = utils::Timestamp();
}
DirShard(uint64_t id, const Range& range, uint64_t version, absl::btree_map<std::string, Dentry>&& dentries)
: id_(id), range_{range}, version_(version) {
// ingest dentries to map
children_ = std::move(dentries);
last_active_time_s_ = utils::Timestamp();
}

static DirShardSPtr New(uint64_t id, const Range& range, uint64_t version, const std::vector<Dentry>& dentries) {
return std::make_shared<DirShard>(id, range, version, dentries);
}

static DirShardSPtr New(uint64_t id, const Range& range, uint64_t version,
absl::btree_map<std::string, Dentry>&& dentries) {
return std::make_shared<DirShard>(id, range, version, std::move(dentries));
}

uint64_t ID() const { return id_; }

// dentry operations
Expand Down
9 changes: 5 additions & 4 deletions src/mds/filesystem/store_operation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ Status BatchCreateFileOperation::RunInBatch(TxnUPtr& txn, AttrEntry& parent_attr
return Status::OK();
}

// todo: batch hardlink
Status HardLinkOperation::Run(TxnUPtr& txn) {
const uint32_t fs_id = dentry_.FsId();
const Ino parent = dentry_.ParentIno();
Expand Down Expand Up @@ -906,7 +907,7 @@ static Status ScanChunk(TxnUPtr& txn, uint32_t fs_id, Ino ino, std::map<uint64_t
}

static Status ResetFileRange(TxnUPtr& txn, uint32_t fs_id, Ino ino, uint64_t old_length, uint64_t new_length,
uint64_t slice_id, uint64_t chunk_size) {
uint64_t chunk_size) {
CHECK(new_length < old_length) << fmt::format("new_length({}) should be less than old_length({}).", new_length,
old_length);

Expand Down Expand Up @@ -963,8 +964,8 @@ Status UpdateAttrOperation::RunInBatch(TxnUPtr& txn, AttrEntry& attr, const std:
result_.delta_bytes = static_cast<int64_t>(attr_.length()) - static_cast<int64_t>(attr.length());
// if delta_length<0 then delete chunks beyond new length
if (result_.delta_bytes < 0) {
auto status = ResetFileRange(txn, attr_.fs_id(), attr_.ino(), attr.length(), attr_.length(),
extra_param_.slice_id, extra_param_.chunk_size);
auto status =
ResetFileRange(txn, attr_.fs_id(), attr_.ino(), attr.length(), attr_.length(), extra_param_.chunk_size);
if (!status.ok()) return status;
}

Expand Down Expand Up @@ -1444,7 +1445,7 @@ Status FlushFileOperation::Run(TxnUPtr& txn) {
if (param_.length > 0) {
int64_t delta_bytes = static_cast<int64_t>(param_.length) - static_cast<int64_t>(attr.length());
if (delta_bytes < 0) {
auto status = ResetFileRange(txn, fs_id_, ino_, attr.length(), param_.length, param_.slice_id, param_.chunk_size);
auto status = ResetFileRange(txn, fs_id_, ino_, attr.length(), param_.length, param_.chunk_size);
if (!status.ok()) return status;
}

Expand Down
32 changes: 16 additions & 16 deletions test/unit/mds/filesystem/test_partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class DirShardTest : public testing::Test {

TEST_F(DirShardTest, BasicPutGetDelete) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

ASSERT_TRUE(shard != nullptr);
ASSERT_EQ(shard->ID(), 1);
Expand Down Expand Up @@ -153,7 +153,7 @@ TEST_F(DirShardTest, BasicPutGetDelete) {

TEST_F(DirShardTest, MultipleDentries) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

// Put multiple dentries
for (int i = 0; i < 10; ++i) {
Expand Down Expand Up @@ -210,13 +210,13 @@ TEST_F(DirShardTest, Scan) {
TEST_F(DirShardTest, Contains) {
// Full range shard
Range range1{"", ""};
DirShardSPtr shard1 = DirShard::New(1, range1, 1, {});
DirShardSPtr shard1 = DirShard::New(1, range1, 1, std::vector<Dentry>{});
ASSERT_TRUE(shard1->Contains("anything"));
ASSERT_TRUE(shard1->Contains(""));

// Bounded range shard [a, c)
Range range2{"a", "c"};
DirShardSPtr shard2 = DirShard::New(2, range2, 1, {});
DirShardSPtr shard2 = DirShard::New(2, range2, 1, std::vector<Dentry>{});
ASSERT_TRUE(shard2->Contains("a"));
ASSERT_TRUE(shard2->Contains("apple"));
ASSERT_TRUE(shard2->Contains("b"));
Expand All @@ -226,7 +226,7 @@ TEST_F(DirShardTest, Contains) {

// Half-open range [c, )
Range range3{"c", ""};
DirShardSPtr shard3 = DirShard::New(3, range3, 1, {});
DirShardSPtr shard3 = DirShard::New(3, range3, 1, std::vector<Dentry>{});
ASSERT_TRUE(shard3->Contains("c"));
ASSERT_TRUE(shard3->Contains("z"));
ASSERT_FALSE(shard3->Contains("a"));
Expand All @@ -235,15 +235,15 @@ TEST_F(DirShardTest, Contains) {

TEST_F(DirShardTest, IsLastShard) {
Range range1{"", ""};
DirShardSPtr shard1 = DirShard::New(1, range1, 1, {});
DirShardSPtr shard1 = DirShard::New(1, range1, 1, std::vector<Dentry>{});
ASSERT_TRUE(shard1->IsLastShard());

Range range2{"a", ""};
DirShardSPtr shard2 = DirShard::New(2, range2, 1, {});
DirShardSPtr shard2 = DirShard::New(2, range2, 1, std::vector<Dentry>{});
ASSERT_TRUE(shard2->IsLastShard());

Range range3{"a", "c"};
DirShardSPtr shard3 = DirShard::New(3, range3, 1, {});
DirShardSPtr shard3 = DirShard::New(3, range3, 1, std::vector<Dentry>{});
ASSERT_FALSE(shard3->IsLastShard());
}

Expand Down Expand Up @@ -301,7 +301,7 @@ TEST_F(DirShardTest, Split) {

TEST_F(DirShardTest, SizeAndBytes) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

ASSERT_EQ(shard->Size(), 0);
ASSERT_EQ(shard->Bytes(), 0);
Expand All @@ -316,7 +316,7 @@ TEST_F(DirShardTest, SizeAndBytes) {

TEST_F(DirShardTest, ToString) {
Range range{"a", "c"};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

std::string str = shard->ToString();
ASSERT_NE(str.find("id(1)"), std::string::npos);
Expand All @@ -325,7 +325,7 @@ TEST_F(DirShardTest, ToString) {

TEST_F(DirShardTest, UpdateLastActiveTime) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

uint64_t before = shard->LastActiveTimeS();

Expand All @@ -342,7 +342,7 @@ TEST_F(DirShardTest, UpdateLastActiveTime) {

TEST_F(DirShardTest, EmptyShardOperations) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

// Mid on empty shard should return empty string
ASSERT_EQ(shard->Mid(), "");
Expand All @@ -362,7 +362,7 @@ TEST_F(DirShardTest, EmptyShardOperations) {

TEST_F(DirShardTest, OverwriteDentry) {
Range range{"", ""};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

// Put initial dentry
Dentry dentry1(
Expand Down Expand Up @@ -413,22 +413,22 @@ TEST_F(DirShardTest, ScanWithMixedTypes) {
TEST_F(DirShardTest, RangeBoundariesEdgeCases) {
// Test exact boundary matches
Range range{"a", "b"};
DirShardSPtr shard = DirShard::New(1, range, 1, {});
DirShardSPtr shard = DirShard::New(1, range, 1, std::vector<Dentry>{});

ASSERT_TRUE(shard->Contains("a"));
ASSERT_FALSE(shard->Contains("b"));

// Empty end boundary means unlimited
Range range2{"z", ""};
DirShardSPtr shard2 = DirShard::New(2, range2, 1, {});
DirShardSPtr shard2 = DirShard::New(2, range2, 1, std::vector<Dentry>{});

ASSERT_TRUE(shard2->Contains("z"));
ASSERT_TRUE(shard2->Contains("zzzz"));
ASSERT_FALSE(shard2->Contains("y"));

// Empty start and end means all
Range range3{"", ""};
DirShardSPtr shard3 = DirShard::New(3, range3, 1, {});
DirShardSPtr shard3 = DirShard::New(3, range3, 1, std::vector<Dentry>{});

ASSERT_TRUE(shard3->Contains(""));
ASSERT_TRUE(shard3->Contains("anything"));
Expand Down
Loading