Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/bluestore: binary search specified shard #11245

Merged
merged 1 commit into from Sep 28, 2016
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 20 additions & 13 deletions src/os/bluestore/BlueStore.cc
Expand Up @@ -1776,11 +1776,18 @@ void BlueStore::ExtentMap::fault_range(
{
dout(30) << __func__ << " 0x" << std::hex << offset << "~" << length
<< std::dec << dendl;
auto p = seek_shard(offset);
auto start = seek_shard(offset);
auto last = seek_shard(offset + length);

if (start < 0)
return;

assert(last >= start);
bool first_key = true;
string key;
while (p != shards.end()) {
while (start <= last) {
assert((size_t)start < shards.size());
auto p = &shards[start];
if (!p->loaded) {
if (first_key) {
get_extent_shard_key(onode->key, p->offset, &key);
Expand All @@ -1801,10 +1808,7 @@ void BlueStore::ExtentMap::fault_range(
assert(p->dirty == false);
assert(v.length() == p->shard_info->bytes);
}
if (p == last) {
break;
}
++p;
++start;
}
}

Expand All @@ -1820,23 +1824,26 @@ void BlueStore::ExtentMap::dirty_range(
inline_bl.clear();
return;
}
auto p = seek_shard(offset);
auto start = seek_shard(offset);
auto last = seek_shard(offset + length);
while (p != shards.end()) {
if (start < 0)
return;

assert(last >= start);
while (start <= last) {
assert((size_t)start < shards.size());
auto p = &shards[start];
if (!p->loaded) {
dout(20) << __func__ << " shard 0x" << std::hex << p->offset << std::dec
<< " is not loaded, can't mark dirty" << dendl;
<< " is not loaded, can't mark dirty" << dendl;
assert(0 == "can't mark unloaded shard dirty");
}
if (!p->dirty) {
dout(20) << __func__ << " mark shard 0x" << std::hex << p->offset
<< std::dec << " dirty" << dendl;
p->dirty = true;
}
if (p == last) {
break;
}
++p;
++start;
}
}

Expand Down
35 changes: 21 additions & 14 deletions src/os/bluestore/BlueStore.h
Expand Up @@ -574,21 +574,28 @@ class BlueStore : public ObjectStore,
/// initialize Shards from the onode
void init_shards(Onode *on, bool loaded, bool dirty);

/// return shard containing offset
vector<Shard>::iterator seek_shard(uint32_t offset) {
// fixme: we could do a binary search here
// we want the right-most shard that has an offset <= @offset.
vector<Shard>::iterator p = shards.begin();
while (p != shards.end() &&
p->offset <= offset) {
++p;
}
if (p != shards.begin()) {
assert(p == shards.end() || p->offset > offset);
--p;
assert(p->offset <= offset);
/// return index of shard containing offset
/// or -1 if not found
int seek_shard(uint32_t offset) {
size_t end = shards.size();
size_t mid, left = 0;
size_t right = end; // one passed the right end

while (left < right) {
mid = left + (right - left) / 2;
if (offset >= shards[mid].offset) {
size_t next = mid + 1;
if (next >= end || offset < shards[next].offset)
return mid;
//continue to search forwards
left = next;
} else {
//continue to search backwards
right = mid;
}
}
return p;

return -1; // not found
}

/// ensure that a range of the map is loaded
Expand Down