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