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_);
for (auto result : results_)
for (const auto& result : results_)
{
if (result_handlers_.find(result.call) != result_handlers_.end())
{
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)
{

View File

@ -6,167 +6,125 @@ namespace utils
class concurrent_list final
{
public:
class entry final
class element final
{
public:
bool has_next()
explicit element(std::recursive_mutex* mutex, std::shared_ptr<T> entry = {}, std::shared_ptr<element> 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)
{
this->object_ = object;
}
std::shared_ptr<T> get()
{
return this->object_;
}
entry get_next()
{
if (this->has_next())
if (this->next_->entry_.get() == element.get())
{
return *this->next_;
this->next_ = this->next_->next_;
}
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_;
}
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::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();
std::lock_guard _(*this->mutex_);
*this = this->next_ ? *this->next_ : element(this->mutex_);
return *this;
}
entry operator++(int)
element operator++(int)
{
entry result = *this;
std::lock_guard _(*this->mutex_);
auto result = *this;
this->operator++();
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:
std::shared_ptr<T> object_;
std::shared_ptr<entry> next_;
std::recursive_mutex* mutex_;
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)
{
std::lock_guard _(this->mutex_);
if (!this->empty())
{
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();
const auto object_ptr = std::make_shared<T>(object);
this->entry_ = std::make_shared<element>(&this->mutex_, object_ptr, this->entry_);
}
void clear()
{
this->object_ = entry();
std::lock_guard _(this->mutex_);
this->entry_ = {};
}
private:
std::mutex mutex_;
entry object_;
std::recursive_mutex mutex_;
std::shared_ptr<element> entry_;
};
}