mirror-chatterino2/src/messages/limitedqueue.hpp

98 lines
2.5 KiB
C++
Raw Normal View History

#pragma once
2017-02-02 20:35:12 +01:00
2017-06-11 09:31:45 +02:00
#include "messages/limitedqueuesnapshot.hpp"
2017-02-02 20:35:12 +01:00
#include <memory>
#include <mutex>
#include <vector>
2017-04-14 17:52:22 +02:00
namespace chatterino {
namespace messages {
2017-02-02 20:35:12 +01:00
template <typename T>
class LimitedQueue
{
public:
2017-09-21 12:15:01 +02:00
LimitedQueue(int _limit = 1000, int _buffer = 250)
: offset(0)
, limit(_limit)
, buffer(_buffer)
2017-02-02 20:35:12 +01:00
{
2017-09-21 12:15:01 +02:00
this->vector = std::make_shared<std::vector<T>>();
this->vector->reserve(this->limit + this->buffer);
}
2017-04-12 17:46:44 +02:00
void clear()
{
2017-09-21 12:15:01 +02:00
std::lock_guard<std::mutex> lock(this->mutex);
2017-09-21 12:15:01 +02:00
this->vector = std::make_shared<std::vector<T>>();
this->vector->reserve(this->limit + this->buffer);
2017-09-21 12:15:01 +02:00
this->offset = 0;
2017-02-02 20:35:12 +01:00
}
// return true if an item was deleted
// deleted will be set if the item was deleted
2017-04-12 17:46:44 +02:00
bool appendItem(const T &item, T &deleted)
2017-02-02 20:35:12 +01:00
{
2017-09-21 12:15:01 +02:00
std::lock_guard<std::mutex> lock(this->mutex);
2017-02-02 20:35:12 +01:00
2017-09-21 12:15:01 +02:00
if (this->vector->size() >= this->limit) {
2017-02-02 20:35:12 +01:00
// vector is full
2017-09-21 12:15:01 +02:00
if (this->offset == this->buffer) {
deleted = this->vector->at(this->offset);
2017-02-02 20:35:12 +01:00
// create new vector
auto newVector = std::make_shared<std::vector<T>>();
2017-09-21 12:15:01 +02:00
newVector->reserve(this->limit + this->buffer);
2017-02-02 20:35:12 +01:00
2017-09-21 12:15:01 +02:00
for (unsigned int i = 0; i < this->limit; ++i) {
newVector->push_back(this->vector->at(i + this->offset));
2017-02-02 20:35:12 +01:00
}
newVector->push_back(item);
2017-02-02 20:35:12 +01:00
2017-09-21 12:15:01 +02:00
this->offset = 0;
this->vector = newVector;
2017-02-02 20:35:12 +01:00
return true;
} else {
2017-09-21 12:15:01 +02:00
deleted = this->vector->at(this->offset);
2017-02-02 20:35:12 +01:00
2017-04-12 17:46:44 +02:00
// append item and increment offset("deleting" first element)
2017-09-21 12:15:01 +02:00
this->vector->push_back(item);
this->offset++;
2017-02-02 20:35:12 +01:00
return true;
}
} else {
// append item
2017-09-21 12:15:01 +02:00
this->vector->push_back(item);
2017-02-02 20:35:12 +01:00
return false;
}
}
2017-04-12 17:46:44 +02:00
messages::LimitedQueueSnapshot<T> getSnapshot()
2017-02-02 20:35:12 +01:00
{
2017-09-21 12:15:01 +02:00
std::lock_guard<std::mutex> lock(this->mutex);
2017-02-02 20:35:12 +01:00
2017-09-21 12:15:01 +02:00
if (this->vector->size() < this->limit) {
return LimitedQueueSnapshot<T>(this->vector, this->offset, this->vector->size());
} else {
2017-09-21 12:15:01 +02:00
return LimitedQueueSnapshot<T>(this->vector, this->offset, this->limit);
}
2017-02-02 20:35:12 +01:00
}
private:
2017-09-21 12:15:01 +02:00
std::shared_ptr<std::vector<T>> vector;
std::mutex mutex;
2017-02-02 20:35:12 +01:00
2017-09-21 12:15:01 +02:00
unsigned int offset;
unsigned int limit;
unsigned int buffer;
2017-02-02 20:35:12 +01:00
};
2017-04-14 17:52:22 +02:00
} // namespace messages
} // namespace chatterino