提交 cd125819 创建 作者: David Benjamin's avatar David Benjamin

Skip empty swaths of iterator

Avoids things looping forever. Still a lot to fix up: The descend API is getting messy. We probably want to rewrite the iterator to keep a whole path, instead of bouncing up and down the tree a lot. Also, a level of duplicate nodes should be collapsed up a level (we can steal another bit). The iterator should also be replaced by something more compatible with crange to avoid the hacks in iteration. But in the meantime, at least this is functional.
上级 0f12d1d1
......@@ -57,6 +57,10 @@ struct radix {
}
radix_elem* search(u64 key);
radix_range search_lock(u64 start, u64 size);
// k is shifted value.
u64 skip_empty(u64 k) const;
NEW_DELETE_OPS(radix)
};
......@@ -64,8 +68,8 @@ struct radix_iterator {
const radix* r_;
u64 k_;
radix_iterator(const radix* r, u64 k) : r_(r), k_(k) {}
radix_iterator &operator++() { k_++; return *this; }
radix_iterator(const radix* r, u64 k) : r_(r), k_(r->skip_empty(k)) {}
radix_iterator &operator++() { k_++; k_ = r_->skip_empty(k_); return *this; }
radix_elem* operator*();
bool operator==(const radix_iterator &other) {
return r_ == other.r_ && k_ == other.k_; }
......
......@@ -56,6 +56,26 @@ radix::search_lock(u64 start, u64 size)
return radix_range(this, start >> shift_, size >> shift_);
}
u64
radix::skip_empty(u64 k) const
{
u64 next_k = k;
while (next_k < (1UL<<key_bits)) {
// Does next_k exist?
// FIXME: evil evil const_cast
u32 level = descend(next_k, const_cast<markptr<void>*>(&root_),
radix_levels-1, [](markptr<void> *v){}, false);
if (level == 0) {
return next_k;
}
u64 mask = 1UL<<(bits_per_level * level);
// Skip past everything we know is missing.
next_k = (next_k & ~(mask-1)) + mask;
}
// Nope, no successor.
return ~0ULL;
}
radix_range::radix_range(radix *r, u64 start, u64 size)
: r_(r), start_(start), size_(size)
{
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论