mirror-chatterino2/messages/limitedqueue.h

101 lines
2.4 KiB
C
Raw Normal View History

2017-02-02 20:35:12 +01:00
#ifndef LIMITEDQUEUE_H
#define LIMITEDQUEUE_H
#include "messages/limitedqueuesnapshot.h"
#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:
LimitedQueue(int limit = 100, int buffer = 25)
2017-04-26 19:53:12 +02:00
: _offset(0)
, _limit(limit)
, _buffer(buffer)
2017-02-02 20:35:12 +01:00
{
2017-04-26 19:53:12 +02:00
_vector = std::make_shared<std::vector<T>>();
_vector->reserve(_limit + _buffer);
}
2017-04-12 17:46:44 +02:00
void clear()
{
2017-04-26 19:53:12 +02:00
std::lock_guard<std::mutex> lock(_mutex);
2017-04-26 19:53:12 +02:00
_vector = std::make_shared<std::vector<T>>();
_vector->reserve(_limit + _buffer);
2017-04-26 19:53:12 +02:00
_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-04-26 19:53:12 +02:00
std::lock_guard<std::mutex> lock(_mutex);
2017-02-02 20:35:12 +01:00
2017-04-26 19:53:12 +02:00
if (_vector->size() >= _limit) {
2017-02-02 20:35:12 +01:00
// vector is full
2017-04-26 19:53:12 +02:00
if (_offset == _buffer) {
deleted = _vector->at(_offset);
2017-02-02 20:35:12 +01:00
// create new vector
auto newVector = std::make_shared<std::vector<T>>();
2017-04-26 19:53:12 +02:00
newVector->reserve(_limit + _buffer);
2017-02-02 20:35:12 +01:00
2017-04-26 19:53:12 +02:00
for (unsigned int i = 0; i < _limit - 1; i++) {
newVector->push_back(_vector->at(i + _offset));
2017-02-02 20:35:12 +01:00
}
newVector->push_back(item);
2017-02-02 20:35:12 +01:00
2017-04-26 19:53:12 +02:00
_offset = 0;
_vector = newVector;
2017-02-02 20:35:12 +01:00
return true;
} else {
2017-04-26 19:53:12 +02:00
deleted = _vector->at(_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-04-26 19:53:12 +02:00
_vector->push_back(item);
_offset++;
2017-02-02 20:35:12 +01:00
return true;
}
} else {
// append item
2017-04-26 19:53:12 +02:00
_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-04-26 19:53:12 +02:00
std::lock_guard<std::mutex> lock(_mutex);
2017-02-02 20:35:12 +01:00
2017-04-26 19:53:12 +02:00
if (_vector->size() < _limit) {
return LimitedQueueSnapshot<T>(_vector, _offset, _vector->size());
} else {
2017-04-26 19:53:12 +02:00
return LimitedQueueSnapshot<T>(_vector, _offset, _limit);
}
2017-02-02 20:35:12 +01:00
}
private:
2017-04-26 19:53:12 +02:00
std::shared_ptr<std::vector<T>> _vector;
std::mutex _mutex;
2017-02-02 20:35:12 +01:00
2017-04-26 19:53:12 +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
2017-02-02 20:35:12 +01:00
#endif // LIMITEDQUEUE_H