提交 2408a9f0 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'scale-amd64' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

......@@ -148,15 +148,13 @@ private:
class radix_elem : public rcu_freed {
private:
bool deleted_;
std::atomic<u64> ref_;
public:
radix_elem() : rcu_freed("radix_elem"), deleted_(false), ref_(0) {}
bool deleted() { return deleted_; }
radix_elem() : rcu_freed("radix_elem"), ref_(0) {}
virtual ~radix_elem() {}
void decref(u64 delta = 1) {
if ((ref_ -= delta) == 0) {
deleted_ = true;
gc_delayed(this);
}
}
......@@ -218,6 +216,8 @@ struct radix {
radix_elem* search(u64 key);
radix_range search_lock(u64 start, u64 size);
iterator find(u64 key);
radix_iterator begin() const;
radix_iterator end() const;
......@@ -225,11 +225,11 @@ struct radix {
};
struct radix_iterator {
radix_iterator(const radix* r, u64 k, u64 limit)
radix_iterator(const radix* r, u64 k, u64 limit, bool skip_nulls)
: r_(r), k_(k), key_limit_(limit)
{
if (k_ != key_limit_)
prime_path();
prime_path(skip_nulls);
}
radix_iterator() = default;
radix_iterator(const radix_iterator &o) = default;
......@@ -250,10 +250,11 @@ struct radix_iterator {
// Advance the iterator until it points at a non-null entry or end.
// If the current element is non-null, does nothing.
void skip_nulls()
radix_iterator &skip_nulls()
{
if (!**this)
++(*this);
return *this;
}
// Return the key of the iterator's current element.
......@@ -291,7 +292,7 @@ private:
u32 level_;
// Prepare the initial path_ and level_ based on k_.
void prime_path();
void prime_path(bool skip_nulls);
// Advance to the next leaf. If skip_nulls is true, advances to the
// next non-null leaf. This assumes that k_ < key_limit_.
void advance(bool skip_nulls = true);
......@@ -299,20 +300,20 @@ private:
inline radix_iterator
radix_range::begin() const {
return radix_iterator(r_, start_, start_ + size_);
return radix_iterator(r_, start_, start_ + size_, true);
}
inline radix_iterator
radix_range::end() const {
return radix_iterator(r_, start_ + size_, start_ + size_);
return radix_iterator(r_, start_ + size_, start_ + size_, true);
}
inline radix_iterator
radix::begin() const {
return radix_iterator(this, 0, (u64)1 << key_bits);
return radix_iterator(this, 0, (u64)1 << key_bits, true);
}
inline radix_iterator
radix::end() const {
return radix_iterator(this, (u64)1 << key_bits, (u64)1 << key_bits);
return radix_iterator(this, (u64)1 << key_bits, (u64)1 << key_bits, true);
}
......@@ -180,6 +180,12 @@ radix::search_lock(u64 start, u64 size)
return radix_range(this, start >> shift_, size >> shift_);
}
radix::iterator
radix::find(u64 key)
{
return radix::iterator(this, key >> shift_, (u64)1 << key_bits, false);
}
radix_range::radix_range(radix *r, u64 start, u64 size)
: r_(r), start_(start), size_(size)
{
......@@ -261,8 +267,13 @@ radix_iterator::next_change() const
}
void
radix_iterator::prime_path()
radix_iterator::prime_path(bool skip_nulls)
{
// XXX(amdragon) Do this lazily in operator*. Then we don't need
// special-casing for the end iterator and callers can jump around
// the keyspace however they want (including, say, starting with the
// begin iterator of the whole radix tree and jumping to a
// particular key.)
dprintf("%p: Made iterator with k = %lx\n", r_, k_);
// Load the initial path
......@@ -276,7 +287,8 @@ radix_iterator::prime_path()
}
// Find a real element
skip_nulls();
if (skip_nulls)
this->skip_nulls();
dprintf("%p: Adjusted: k = %lx\n", r_, k_);
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论