mirror of
https://github.com/thunderbrewhq/squall.git
synced 2025-12-12 02:22:30 +00:00
feat(queue): add TSPriorityQueue and TSTimerPriority
This commit is contained in:
parent
2200aab4c2
commit
2e82693829
9 changed files with 264 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ check_cxx_compiler_flag(-Wno-invalid-offsetof HAS_NO_INVALID_OFFSETOF)
|
||||||
file(GLOB STORM_SOURCES
|
file(GLOB STORM_SOURCES
|
||||||
"*.cpp"
|
"*.cpp"
|
||||||
"hash/*.cpp"
|
"hash/*.cpp"
|
||||||
|
"queue/*.cpp"
|
||||||
"string/*.cpp"
|
"string/*.cpp"
|
||||||
"thread/*.cpp"
|
"thread/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
7
storm/Queue.hpp
Normal file
7
storm/Queue.hpp
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef STORM_QUEUE_HPP
|
||||||
|
#define STORM_QUEUE_HPP
|
||||||
|
|
||||||
|
#include "storm/queue/TSPriorityQueue.hpp"
|
||||||
|
#include "storm/queue/TSTimerPriority.hpp"
|
||||||
|
|
||||||
|
#endif
|
||||||
92
storm/queue/CSBasePriority.cpp
Normal file
92
storm/queue/CSBasePriority.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "storm/queue/CSBasePriority.hpp"
|
||||||
|
#include "storm/queue/CSBasePriorityQueue.hpp"
|
||||||
|
|
||||||
|
void CSBasePriority::Relink() {
|
||||||
|
CSBasePriorityQueue* queue = this->m_queue;
|
||||||
|
|
||||||
|
if (!queue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ptr = queue->operator[](this->m_index);
|
||||||
|
|
||||||
|
this->Unlink();
|
||||||
|
|
||||||
|
int32_t v18 = queue->Count();
|
||||||
|
queue->SetCount(v18 + 1);
|
||||||
|
|
||||||
|
while (v18) {
|
||||||
|
auto v19 = reinterpret_cast<CSBasePriority*>(
|
||||||
|
reinterpret_cast<uintptr_t>(ptr) + queue->m_linkOffset);
|
||||||
|
|
||||||
|
CSBasePriority* v20 = queue->Link((v18 - 1) >> 1);
|
||||||
|
|
||||||
|
if (v20->Compare(v19)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->operator[](v18) = queue->operator[]((v18 - 1) >> 1);
|
||||||
|
queue->SetLink(v18);
|
||||||
|
|
||||||
|
v18 = (v18 - 1) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->operator[](v18) = ptr;
|
||||||
|
queue->SetLink(v18);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSBasePriority::Unlink() {
|
||||||
|
CSBasePriorityQueue* queue = this->m_queue;
|
||||||
|
|
||||||
|
if (!queue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t index = this->m_index;
|
||||||
|
|
||||||
|
CSBasePriority* link = this->m_queue->Link(this->m_index);
|
||||||
|
link->m_queue = 0;
|
||||||
|
link->m_index = 0;
|
||||||
|
|
||||||
|
void* top = queue->Top();
|
||||||
|
|
||||||
|
int32_t v8 = queue->Count();
|
||||||
|
int32_t v9 = queue->Count() - 1;
|
||||||
|
|
||||||
|
queue->SetCount(v9);
|
||||||
|
|
||||||
|
if (index == v9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t hBound = v9 - 1;
|
||||||
|
int32_t lBound = (v9 - 2) >> 1;
|
||||||
|
|
||||||
|
if (index < hBound && index <= lBound >> 1) {
|
||||||
|
while (true) {
|
||||||
|
int32_t v11 = 2 * index + 1;
|
||||||
|
|
||||||
|
if (v11 < hBound) {
|
||||||
|
if (queue->Link(2 * index + 2)->Compare(queue->Link(v11))) {
|
||||||
|
v11 = 2 * index + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reinterpret_cast<CSBasePriority*>(reinterpret_cast<uintptr_t>(top) + queue->m_linkOffset)->Compare(queue->Link(v11))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->operator[](index) = queue->operator[](v11);
|
||||||
|
queue->SetLink(index);
|
||||||
|
|
||||||
|
index = v11;
|
||||||
|
|
||||||
|
if (v11 > lBound) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->operator[](index) = top;
|
||||||
|
queue->SetLink(index);
|
||||||
|
}
|
||||||
20
storm/queue/CSBasePriority.hpp
Normal file
20
storm/queue/CSBasePriority.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef STORM_QUEUE_CS_BASE_PRIORITY_HPP
|
||||||
|
#define STORM_QUEUE_CS_BASE_PRIORITY_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class CSBasePriorityQueue;
|
||||||
|
|
||||||
|
class CSBasePriority {
|
||||||
|
public:
|
||||||
|
// Member variables
|
||||||
|
CSBasePriorityQueue* m_queue;
|
||||||
|
uint32_t m_index;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
virtual bool Compare(CSBasePriority* a) = 0;
|
||||||
|
void Unlink();
|
||||||
|
void Relink();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
63
storm/queue/CSBasePriorityQueue.cpp
Normal file
63
storm/queue/CSBasePriorityQueue.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include "storm/queue/CSBasePriorityQueue.hpp"
|
||||||
|
#include "storm/queue/CSBasePriority.hpp"
|
||||||
|
|
||||||
|
void* CSBasePriorityQueue::Dequeue() {
|
||||||
|
if (this->Count()) {
|
||||||
|
void* bottom = this->operator[](0);
|
||||||
|
this->Remove(0);
|
||||||
|
return bottom;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSBasePriorityQueue::Enqueue(void* val) {
|
||||||
|
int32_t v3 = this->Count();
|
||||||
|
this->SetCount(v3 + 1);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int32_t v4 = (v3 - 1) >> 1;
|
||||||
|
|
||||||
|
if (!v3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->Link(v4)->Compare(reinterpret_cast<CSBasePriority*>(reinterpret_cast<uintptr_t>(val) + this->m_linkOffset))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->operator[](v3) = this->operator[](v4);
|
||||||
|
this->SetLink(v3);
|
||||||
|
|
||||||
|
v3 = (v3 - 1) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->operator[](v3) = val;
|
||||||
|
this->SetLink(v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSBasePriority* CSBasePriorityQueue::Link(uint32_t index) const {
|
||||||
|
return reinterpret_cast<CSBasePriority*>(
|
||||||
|
reinterpret_cast<uintptr_t>(this->m_data[index]) + this->m_linkOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSBasePriorityQueue::SetLink(uint32_t index) {
|
||||||
|
CSBasePriority* link = this->Link(index);
|
||||||
|
|
||||||
|
link->m_index = index;
|
||||||
|
link->m_queue = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CSBasePriorityQueue::Top() {
|
||||||
|
int32_t count = this->Count();
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
return this->m_data[count - 1];
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSBasePriorityQueue::Remove(uint32_t index) {
|
||||||
|
this->Link(index)->Unlink();
|
||||||
|
}
|
||||||
23
storm/queue/CSBasePriorityQueue.hpp
Normal file
23
storm/queue/CSBasePriorityQueue.hpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef STORM_QUEUE_CS_BASE_PRIORITY_QUEUE_HPP
|
||||||
|
#define STORM_QUEUE_CS_BASE_PRIORITY_QUEUE_HPP
|
||||||
|
|
||||||
|
#include "storm/Array.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class CSBasePriority;
|
||||||
|
|
||||||
|
class CSBasePriorityQueue : public TSGrowableArray<void*> {
|
||||||
|
public:
|
||||||
|
// Member variables
|
||||||
|
uint32_t m_linkOffset;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
void* Dequeue();
|
||||||
|
void Enqueue(void* val);
|
||||||
|
CSBasePriority* Link(uint32_t index) const;
|
||||||
|
void Remove(uint32_t index);
|
||||||
|
void SetLink(uint32_t index);
|
||||||
|
void* Top();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
26
storm/queue/TSPriorityQueue.hpp
Normal file
26
storm/queue/TSPriorityQueue.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef STORM_QUEUE_TS_PRIORITY_QUEUE_HPP
|
||||||
|
#define STORM_QUEUE_TS_PRIORITY_QUEUE_HPP
|
||||||
|
|
||||||
|
#include "storm/queue/CSBasePriorityQueue.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class TSPriorityQueue : public CSBasePriorityQueue {
|
||||||
|
public:
|
||||||
|
// Member functions
|
||||||
|
TSPriorityQueue(uint32_t linkOffset);
|
||||||
|
T* Dequeue();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
TSPriorityQueue<T>::TSPriorityQueue(uint32_t linkOffset)
|
||||||
|
: CSBasePriorityQueue() {
|
||||||
|
this->m_linkOffset = linkOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T* TSPriorityQueue<T>::Dequeue() {
|
||||||
|
return static_cast<T*>(CSBasePriorityQueue::Dequeue());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
16
storm/queue/TSTimerPriority.hpp
Normal file
16
storm/queue/TSTimerPriority.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "storm/queue/CSBasePriority.hpp"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class TSTimerPriority : public CSBasePriority {
|
||||||
|
public:
|
||||||
|
// Member variables
|
||||||
|
T m_val;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
virtual bool Compare(CSBasePriority* a);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool TSTimerPriority<T>::Compare(CSBasePriority* a) {
|
||||||
|
return this->m_val - static_cast<TSTimerPriority<T>*>(a)->m_val <= 0;
|
||||||
|
}
|
||||||
16
test/Queue.cpp
Normal file
16
test/Queue.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "storm/Queue.hpp"
|
||||||
|
#include "test/Test.hpp"
|
||||||
|
|
||||||
|
struct TestPriority : TSTimerPriority<uint32_t> {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestElement {
|
||||||
|
TestPriority m_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE("TSPriorityQueue", "[queue]") {
|
||||||
|
SECTION("constructs correctly") {
|
||||||
|
auto queue = TSPriorityQueue<TestElement>(offsetof(TestElement, m_priority));
|
||||||
|
REQUIRE(queue.Dequeue() == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue