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

Pass level into update_range

We want the level for use with index(). Probably should just drop cur_end now that it's redundant. Also reorder all those arguments to be saner.
上级 a9659913
...@@ -17,6 +17,13 @@ index(u64 key, u32 level) ...@@ -17,6 +17,13 @@ index(u64 key, u32 level)
return idx; return idx;
} }
// Returns the size of a subtree for a node at |level|.
static u64
level_size(u32 level)
{
return 1L << (bits_per_level * level);
}
static radix_entry static radix_entry
push_down(radix_entry cur, radix_ptr *ptr) push_down(radix_entry cur, radix_ptr *ptr)
{ {
...@@ -69,8 +76,9 @@ template <class CB> ...@@ -69,8 +76,9 @@ template <class CB>
u64 u64
update_range(radix_entry cur, radix_ptr *ptr, CB cb, update_range(radix_entry cur, radix_ptr *ptr, CB cb,
u64 cur_start, u64 cur_end, u64 cur_start, u64 cur_end,
u64 start, u64 end) u64 start, u64 end, u32 level = radix_levels)
{ {
assert(level_size(level) == cur_end - cur_start);
// If ranges are disjoint, do nothing. We manage to process everyone // If ranges are disjoint, do nothing. We manage to process everyone
// for free. // for free.
if (cur_start >= end || start >= cur_end) if (cur_start >= end || start >= cur_end)
...@@ -95,7 +103,7 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb, ...@@ -95,7 +103,7 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb,
// touch pointers with no intersection with ours. // touch pointers with no intersection with ours.
u64 ret = update_range(child->load(), child, cb, u64 ret = update_range(child->load(), child, cb,
child_start, child_start + child_size, child_start, child_start + child_size,
start, end); start, end, level - 1);
if (ret != child_start + child_size) return ret; if (ret != child_start + child_size) return ret;
} }
return cur_end; return cur_end;
...@@ -104,7 +112,7 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb, ...@@ -104,7 +112,7 @@ update_range(radix_entry cur, radix_ptr *ptr, CB cb,
// element. // element.
assert(start <= cur_start && cur_end <= end); assert(start <= cur_start && cur_end <= end);
// Callback returns how far it processed. // Callback returns how far it processed.
return cb(cur, ptr, cur_start, cur_end); return cb(cur, ptr, cur_start, cur_end, level);
} }
} }
...@@ -158,7 +166,7 @@ struct entry_locker { ...@@ -158,7 +166,7 @@ struct entry_locker {
u64 end_; u64 end_;
entry_locker(u64 start, u64 end) : start_(start), end_(end) { } entry_locker(u64 start, u64 end) : start_(start), end_(end) { }
u64 operator()(radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end) const { u64 operator()(radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end, u32 level) const {
while (cur.state() != entry_dead && cur.state() != entry_node) { while (cur.state() != entry_dead && cur.state() != entry_node) {
// Locked -> spin and try again. // Locked -> spin and try again.
if (cur.state() == entry_locked) { if (cur.state() == entry_locked) {
...@@ -177,7 +185,7 @@ struct entry_locker { ...@@ -177,7 +185,7 @@ struct entry_locker {
return cur_start; return cur_start;
// Someone pushed down. Recurse some more. // Someone pushed down. Recurse some more.
if (cur.state() == entry_node) if (cur.state() == entry_node)
return update_range(cur, ptr, *this, cur_start, cur_end, start_, end_); return update_range(cur, ptr, *this, cur_start, cur_end, start_, end_, level-1);
// We managed to lock! // We managed to lock!
assert(cur.state() == entry_locked); assert(cur.state() == entry_locked);
return cur_end; return cur_end;
...@@ -203,7 +211,7 @@ radix_range::~radix_range() ...@@ -203,7 +211,7 @@ radix_range::~radix_range()
if (!r_) if (!r_)
return; return;
u64 ret = update_range(r_->root_.load(), &r_->root_, [](radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end) -> u64 { u64 ret = update_range(r_->root_.load(), &r_->root_, [](radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end, u32 level) -> u64 {
do { do {
// It had better still be locked. // It had better still be locked.
assert(cur.state() == entry_locked); assert(cur.state() == entry_locked);
...@@ -225,7 +233,7 @@ radix_range::replace(u64 start, u64 size, radix_elem *val) ...@@ -225,7 +233,7 @@ radix_range::replace(u64 start, u64 size, radix_elem *val)
assert(start >= start_); assert(start >= start_);
assert(start + size <= start_ + size_); assert(start + size <= start_ + size_);
u64 ret = update_range(r_->root_.load(), &r_->root_, [val](radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end) -> u64 { u64 ret = update_range(r_->root_.load(), &r_->root_, [val](radix_entry cur, radix_ptr *ptr, u64 cur_start, u64 cur_end, u32 level) -> u64 {
dprintf(" -> [%lx, %lx); size = %lx\n", cur_start, cur_end, cur_end - cur_start); dprintf(" -> [%lx, %lx); size = %lx\n", cur_start, cur_end, cur_end - cur_start);
do { do {
assert(cur.state() == entry_locked); assert(cur.state() == entry_locked);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论