Optimize concurrent lists

This commit is contained in:
momo5502 2019-01-21 22:19:38 +01:00
parent c8ad7a687e
commit f497338f7b
2 changed files with 78 additions and 120 deletions

View File

@ -53,14 +53,14 @@ namespace steam
{ {
std::lock_guard _(mutex_); std::lock_guard _(mutex_);
for (auto result : results_) for (const auto& result : results_)
{ {
if (result_handlers_.find(result.call) != result_handlers_.end()) if (result_handlers_.find(result.call) != result_handlers_.end())
{ {
result_handlers_[result.call]->run(result.data, false, result.call); result_handlers_[result.call]->run(result.data, false, result.call);
} }
for (auto callback : callback_list_) for (const auto& callback : callback_list_)
{ {
if (callback && callback->get_i_callback() == result.type) if (callback && callback->get_i_callback() == result.type)
{ {

View File

@ -6,167 +6,125 @@ namespace utils
class concurrent_list final class concurrent_list final
{ {
public: public:
class entry final class element final
{ {
public: public:
explicit element(std::recursive_mutex* mutex, std::shared_ptr<T> entry = {}, std::shared_ptr<element> next = {}) :
bool has_next() mutex_(mutex),
entry_(std::move(entry)),
next_(std::move(next))
{ {
return this->next_.operator bool();
} }
bool is_valid() void remove(const std::shared_ptr<T>& element)
{ {
return this->object_.operator bool(); std::lock_guard _(*this->mutex_);
} if (!this->next_) return;
void set(const std::shared_ptr<T>& object) if (this->next_->entry_.get() == element.get())
{ {
this->object_ = object; this->next_ = this->next_->next_;
}
std::shared_ptr<T> get()
{
return this->object_;
}
entry get_next()
{
if (this->has_next())
{
return *this->next_;
} }
else else
{ {
return entry(); this->next_->remove(element);
} }
} }
std::shared_ptr<entry> get_next_entry() std::shared_ptr<element> get_next() const
{ {
std::lock_guard _(*this->mutex_);
return this->next_; return this->next_;
} }
void set_next_entry(std::shared_ptr<entry> entry) std::shared_ptr<T> operator*() const
{ {
this->next_ = entry; std::lock_guard _(*this->mutex_);
return this->entry_;
} }
T* operator->() element& operator++()
{ {
return this->object_.get(); std::lock_guard _(*this->mutex_);
} *this = this->next_ ? *this->next_ : element(this->mutex_);
std::shared_ptr<T> operator*()
{
return this->object_;
}
explicit operator bool()
{
return this->is_valid();
}
bool operator==(const entry& other)
{
return this->object_.get() == other.object_.get();
}
bool operator!=(const entry& other)
{
return !(*this == other);
}
entry& operator++()
{
*this = this->get_next();
return *this; return *this;
} }
entry operator++(int) element operator++(int)
{ {
entry result = *this; std::lock_guard _(*this->mutex_);
auto result = *this;
this->operator++(); this->operator++();
return result; return result;
} }
bool operator==(const element& other)
{
std::lock_guard _(*this->mutex_);
return this->entry_.get() == other.entry_.get();
}
bool operator!=(const element& other)
{
std::lock_guard _(*this->mutex_);
return !(*this == other);
}
private: private:
std::shared_ptr<T> object_; std::recursive_mutex* mutex_;
std::shared_ptr<entry> next_; std::shared_ptr<T> entry_;
std::shared_ptr<element> next_;
}; };
element begin()
{
std::lock_guard _(this->mutex_);
return this->entry_ ? *this->entry_ : this->end();
}
element end()
{
std::lock_guard _(this->mutex_);
return element(&this->mutex_);
}
void remove(const element& entry)
{
std::lock_guard _(this->mutex_);
this->remove(*entry);
}
void remove(const std::shared_ptr<T>& element)
{
std::lock_guard _(this->mutex_);
if (!this->entry_) return;
if ((**this->entry_).get() == element.get())
{
this->entry_ = this->entry_->get_next();
}
else
{
this->entry_->remove(element);
}
}
void add(const T& object) void add(const T& object)
{ {
std::lock_guard _(this->mutex_); std::lock_guard _(this->mutex_);
if (!this->empty()) const auto object_ptr = std::make_shared<T>(object);
{ this->entry_ = std::make_shared<element>(&this->mutex_, object_ptr, this->entry_);
std::shared_ptr<entry> current_object = std::make_shared<entry>();
current_object->set(this->object_.get());
this->object_ = entry();
this->object_.set_next_entry(current_object);
}
const auto obj_ptr = std::make_shared<T>(object);
this->object_.set(obj_ptr);
}
void remove(const std::shared_ptr<T>& object)
{
std::lock_guard _(this->mutex_);
if (!this->empty())
{
if (this->object_.get() == object)
{
this->object_ = this->object_.get_next();
}
else if (this->object_.has_next())
{
for (auto entry = this->object_; entry.is_valid(); ++entry)
{
auto next = entry.get_next();
if (next.is_valid() && next.get() == object)
{
entry.set_next_entry(next.get_next_entry());
}
}
}
}
}
void remove(entry entry)
{
if (entry.is_valid())
{
this->remove(entry.get());
}
}
bool empty()
{
return !this->object_;
}
entry begin()
{
return this->object_;
}
entry end()
{
return entry();
} }
void clear() void clear()
{ {
this->object_ = entry(); std::lock_guard _(this->mutex_);
this->entry_ = {};
} }
private: private:
std::mutex mutex_; std::recursive_mutex mutex_;
entry object_; std::shared_ptr<element> entry_;
}; };
} }