Commit fb4e6ac9 authored by Max Kellermann's avatar Max Kellermann

lib/nfs/Cancellable: use boost::intrusive::list

Reduce Remove() overhead because we don't have to walk the list to find an iterator by reference.
parent 3560dc4b
...@@ -22,13 +22,15 @@ ...@@ -22,13 +22,15 @@
#include "Compiler.h" #include "Compiler.h"
#include <list> #include <boost/intrusive/list.hpp>
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
template<typename T> template<typename T>
class CancellablePointer { class CancellablePointer
: public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
public: public:
typedef T *pointer_type; typedef T *pointer_type;
typedef T &reference_type; typedef T &reference_type;
...@@ -38,7 +40,7 @@ private: ...@@ -38,7 +40,7 @@ private:
pointer_type p; pointer_type p;
public: public:
explicit constexpr CancellablePointer(reference_type _p):p(&_p) {} explicit CancellablePointer(reference_type _p):p(&_p) {}
CancellablePointer(const CancellablePointer &) = delete; CancellablePointer(const CancellablePointer &) = delete;
...@@ -70,7 +72,8 @@ public: ...@@ -70,7 +72,8 @@ public:
typedef typename CT::const_reference_type const_reference_type; typedef typename CT::const_reference_type const_reference_type;
private: private:
typedef std::list<CT> List; typedef boost::intrusive::list<CT,
boost::intrusive::constant_time_size<false>> List;
typedef typename List::iterator iterator; typedef typename List::iterator iterator;
typedef typename List::const_iterator const_iterator; typedef typename List::const_iterator const_iterator;
List list; List list;
...@@ -97,28 +100,14 @@ private: ...@@ -97,28 +100,14 @@ private:
return std::find_if(list.begin(), list.end(), MatchPointer(p)); return std::find_if(list.begin(), list.end(), MatchPointer(p));
} }
class MatchReference {
const CT &c;
public:
constexpr explicit MatchReference(const CT &_c):c(_c) {}
gcc_pure
bool operator()(const CT &a) const {
return &a == &c;
}
};
gcc_pure gcc_pure
iterator Find(CT &c) { iterator Find(CT &c) {
return std::find_if(list.begin(), list.end(), return list.iterator_to(c);
MatchReference(c));
} }
gcc_pure gcc_pure
const_iterator Find(const CT &c) const { const_iterator Find(const CT &c) const {
return std::find_if(list.begin(), list.end(), return list.iterator_to(c);
MatchReference(c));
} }
public: public:
...@@ -142,21 +131,9 @@ public: ...@@ -142,21 +131,9 @@ public:
CT &Add(reference_type p, Args&&... args) { CT &Add(reference_type p, Args&&... args) {
assert(Find(p) == list.end()); assert(Find(p) == list.end());
list.emplace_back(p, std::forward<Args>(args)...); CT *c = new CT(p, std::forward<Args>(args)...);
return list.back(); list.push_back(*c);
} return *c;
void RemoveLast() {
list.pop_back();
}
bool RemoveOptional(CT &ct) {
auto i = Find(ct);
if (i == list.end())
return false;
list.erase(i);
return true;
} }
void Remove(CT &ct) { void Remove(CT &ct) {
...@@ -164,6 +141,7 @@ public: ...@@ -164,6 +141,7 @@ public:
assert(i != list.end()); assert(i != list.end());
list.erase(i); list.erase(i);
delete &ct;
} }
void Cancel(reference_type p) { void Cancel(reference_type p) {
......
...@@ -161,7 +161,7 @@ NfsConnection::Open(const char *path, int flags, NfsCallback &callback, ...@@ -161,7 +161,7 @@ NfsConnection::Open(const char *path, int flags, NfsCallback &callback,
auto &c = callbacks.Add(callback, *this); auto &c = callbacks.Add(callback, *this);
if (!c.Open(context, path, flags, error)) { if (!c.Open(context, path, flags, error)) {
callbacks.RemoveLast(); callbacks.Remove(c);
return false; return false;
} }
...@@ -176,7 +176,7 @@ NfsConnection::Stat(struct nfsfh *fh, NfsCallback &callback, Error &error) ...@@ -176,7 +176,7 @@ NfsConnection::Stat(struct nfsfh *fh, NfsCallback &callback, Error &error)
auto &c = callbacks.Add(callback, *this); auto &c = callbacks.Add(callback, *this);
if (!c.Stat(context, fh, error)) { if (!c.Stat(context, fh, error)) {
callbacks.RemoveLast(); callbacks.Remove(c);
return false; return false;
} }
...@@ -192,7 +192,7 @@ NfsConnection::Read(struct nfsfh *fh, uint64_t offset, size_t size, ...@@ -192,7 +192,7 @@ NfsConnection::Read(struct nfsfh *fh, uint64_t offset, size_t size,
auto &c = callbacks.Add(callback, *this); auto &c = callbacks.Add(callback, *this);
if (!c.Read(context, fh, offset, size, error)) { if (!c.Read(context, fh, offset, size, error)) {
callbacks.RemoveLast(); callbacks.Remove(c);
return false; return false;
} }
......
...@@ -41,7 +41,7 @@ class NfsConnection : SocketMonitor, DeferredMonitor { ...@@ -41,7 +41,7 @@ class NfsConnection : SocketMonitor, DeferredMonitor {
NfsConnection &connection; NfsConnection &connection;
public: public:
explicit constexpr CancellableCallback(NfsCallback &_callback, explicit CancellableCallback(NfsCallback &_callback,
NfsConnection &_connection) NfsConnection &_connection)
:CancellablePointer<NfsCallback>(_callback), :CancellablePointer<NfsCallback>(_callback),
connection(_connection) {} connection(_connection) {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment