{
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);
assert(p->dirty == false);
assert(v.length() == p->shard_info->bytes);
}
- if (p == last) {
- break;
- }
- ++p;
+ ++start;
}
}
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) {
<< std::dec << " dirty" << dendl;
p->dirty = true;
}
- if (p == last) {
- break;
- }
- ++p;
+ ++start;
}
}
/// 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