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

First version of new iterator

上级 d17c6eab
......@@ -78,6 +78,39 @@ struct radix_iterator {
return r_ != other.r_ || k_ != other.k_; }
};
struct radix_iterator2 {
const radix* r_;
u64 k_;
// path_[i] is the node at level i. Note that the leaf is at zero
// and is radix_elem. The rest are radix_node. For now we assume all
// leaves are at level 0. Later we'll steal a bit for them. The root
// is path_[radix_levels].
void *path_[radix_levels+1];
radix_iterator2(const radix* r, u64 k);
radix_iterator2 &operator++() {
if (!advance(radix_levels-1)) k_ = ~0ULL;
return *this;
}
radix_elem* operator*() {
return (radix_elem*)path_[0];
}
radix_node* node(u32 level) { return (radix_node*)path_[level]; }
// Compare equality on just the key.
bool operator==(const radix_iterator2 &other) {
return r_ == other.r_ && k_ == other.k_; }
bool operator!=(const radix_iterator2 &other) {
return r_ != other.r_ || k_ != other.k_; }
private:
bool find_first_leaf(u32 level);
bool advance(u32 level);
};
#define radix_iterator radix_iterator2
static inline radix_iterator
begin(const radix &r) { return radix_iterator(&r, 0); }
......@@ -91,3 +124,4 @@ begin(const radix_range &rr) { return radix_iterator(rr.r_, rr.start_); }
static inline radix_iterator
end(const radix_range &rr) { return radix_iterator(rr.r_, rr.start_ + rr.size_); }
#undef radix_iterator
#include "crange_arch.hh"
#include "radix.hh"
static u64
enum { crange_debug = 0 };
#define dprintf(...) do { if (crange_debug) cprintf(__VA_ARGS__); } while(0)
// Returns the index needed to reach |level| from |level+1|.
static u32
index(u64 key, u32 level)
{
u64 idx = key >> (bits_per_level * level);
......@@ -49,6 +54,7 @@ radix::search(u64 key)
descend(key >> shift_, &root_, radix_levels-1, [&result](markptr<void> *v) {
result = (radix_elem*) v->ptr().load();
}, false);
dprintf("%p: search(%lu) -> %p\n", this, key >> shift_, result);
return result;
}
......@@ -110,6 +116,7 @@ radix_range::replace(u64 start, u64 size, radix_elem *val)
{
start = start >> r_->shift_;
size = size >> r_->shift_;
dprintf("%p: replace: [%lu, %lu) with %p\n", r_, start, start + size, val);
assert(start >= start_);
assert(start + size <= start_ + size_);
......@@ -138,3 +145,67 @@ radix_iterator::operator*()
}, false);
return result;
}
radix_iterator2::radix_iterator2(const radix* r, u64 k)
: r_(r), k_(k) {
dprintf("%p: Made iterator with k = %lu\n", r_, k_);
if (k_ != ~0ULL) {
path_[radix_levels] = r_->root_.ptr().load();
if (!find_first_leaf(radix_levels - 1))
k_ = ~0ULL;
}
dprintf("%p: Adjusted: k = %lu\n", r_, k_);
}
bool
radix_iterator2::advance(u32 level)
{
// First, see if we can advance a lower level.
if (level > 0 && advance(level-1)) {
// Nothing more to do.
return true;
}
// Try to advance this level.
for (u32 idx = index(k_, level) + 1;
idx < (1<<bits_per_level);
idx++) {
void *next = node(level+1)->ptr[idx].ptr().load();
if (next != nullptr) {
// Clear everything this level and under and set this one.
k_ &= ~((1ULL<<((level+1) * bits_per_level)) - 1);
k_ |= (u64(idx) << (level * bits_per_level));
path_[level] = next;
// Try to find a leaf.
if (level == 0 || find_first_leaf(level-1))
return true;
}
}
// Failed to advance. Abort.
return false;
}
bool
radix_iterator2::find_first_leaf(u32 level)
{
// Find the first non-empty node after k_ on this level.
for (u32 idx = index(k_, level); idx < (1<<bits_per_level); idx++) {
void *next = node(level+1)->ptr[idx].ptr().load();
if (next != nullptr) {
if (index(k_, level) != idx) {
// We had to advance; clear everything this level and under
// and set this one.
k_ &= ~((1ULL<<((level+1) * bits_per_level)) - 1);
k_ |= (u64(idx) << (level * bits_per_level));
}
path_[level] = next;
if (level == 0 || find_first_leaf(level-1))
return true;
}
}
// Failed to find a leaf. Abort.
return false;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论