-
-
Notifications
You must be signed in to change notification settings - Fork 658
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vector_sort is a container that contains sorted objects.
- Loading branch information
Showing
3 changed files
with
180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/** | ||
* Canary - A free and open-source MMORPG server emulator | ||
* Copyright (©) 2019-2022 OpenTibiaBR <[email protected]> | ||
* Repository: https://github.com/opentibiabr/canary | ||
* License: https://github.com/opentibiabr/canary/blob/main/LICENSE | ||
* Contributors: https://github.com/opentibiabr/canary/graphs/contributors | ||
* Website: https://docs.opentibiabr.com/ | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <vector> | ||
|
||
// # Mehah | ||
// vector_sort is a container that contains sorted objects. | ||
|
||
namespace stdext { | ||
template <typename T> | ||
class vector_sort { | ||
public: | ||
bool contains(const T &v) { | ||
update(); | ||
return std::ranges::binary_search(container, v); | ||
} | ||
|
||
bool erase(const T &v) { | ||
update(); | ||
|
||
const auto &it = std::ranges::lower_bound(container, v); | ||
if (it == container.end()) { | ||
return false; | ||
} | ||
container.erase(it); | ||
|
||
return true; | ||
} | ||
|
||
bool erase(const size_t begin, const size_t end) { | ||
update(); | ||
|
||
if (begin > size() || end > size()) { | ||
return false; | ||
} | ||
|
||
container.erase(container.begin() + begin, container.begin() + end); | ||
return true; | ||
} | ||
|
||
template <class F> | ||
bool erase_if(F fnc) { | ||
update(); | ||
return std::erase_if(container, std::move(fnc)) > 0; | ||
} | ||
|
||
auto &front() { | ||
update(); | ||
return container.front(); | ||
} | ||
|
||
void pop_back() { | ||
update(); | ||
container.pop_back(); | ||
} | ||
|
||
auto &back() { | ||
update(); | ||
return container.back(); | ||
} | ||
|
||
void push_back(const T &v) { | ||
needUpdate = true; | ||
container.push_back(v); | ||
} | ||
|
||
void push_back(T &&_Val) { | ||
needUpdate = true; | ||
container.push_back(std::move(_Val)); | ||
} | ||
|
||
// Copy all content list to this | ||
auto insert_all(const vector_sort<T> &list) { | ||
needUpdate = true; | ||
return container.insert(container.end(), list.begin(), list.end()); | ||
} | ||
|
||
// Copy all content list to this | ||
auto insert_all(const std::vector<T> &list) { | ||
needUpdate = true; | ||
return container.insert(container.end(), list.begin(), list.end()); | ||
} | ||
|
||
// Move all content list to this | ||
auto join(vector_sort<T> &list) { | ||
needUpdate = true; | ||
auto res = container.insert(container.end(), make_move_iterator(list.begin()), make_move_iterator(list.end())); | ||
list.clear(); | ||
return res; | ||
} | ||
|
||
// Move all content list to this | ||
auto join(std::vector<T> &list) { | ||
needUpdate = true; | ||
auto res = container.insert(container.end(), make_move_iterator(list.begin()), make_move_iterator(list.end())); | ||
list.clear(); | ||
return res; | ||
} | ||
|
||
template <class... _Valty> | ||
decltype(auto) emplace_back(_Valty &&... v) { | ||
needUpdate = true; | ||
return container.emplace_back(std::forward<_Valty>(v)...); | ||
} | ||
|
||
void partial_sort(size_t begin, size_t end = 0) { | ||
partial_begin = begin; | ||
if (end > begin) { | ||
partial_end = size() - end; | ||
} | ||
} | ||
|
||
void notify_sort() { | ||
needUpdate = true; | ||
} | ||
|
||
bool empty() const noexcept { | ||
return container.empty(); | ||
} | ||
|
||
size_t size() const noexcept { | ||
return container.size(); | ||
} | ||
|
||
auto begin() noexcept { | ||
update(); | ||
return container.begin(); | ||
} | ||
|
||
auto end() noexcept { | ||
return container.end(); | ||
} | ||
|
||
void clear() noexcept { | ||
partial_begin = partial_end = 0; | ||
return container.clear(); | ||
} | ||
|
||
void reserve(size_t newCap) noexcept { | ||
container.reserve(newCap); | ||
} | ||
|
||
const auto &data() noexcept { | ||
update(); | ||
return container.data(); | ||
} | ||
|
||
T &operator[](const size_t i) { | ||
update(); | ||
return container[i]; | ||
} | ||
|
||
private: | ||
inline void update() noexcept { | ||
if (!needUpdate) { | ||
return; | ||
} | ||
|
||
needUpdate = false; | ||
std::ranges::sort(container.begin() + partial_begin, container.end() - partial_end, std::less()); | ||
} | ||
|
||
std::vector<T> container; | ||
|
||
bool needUpdate = false; | ||
size_t partial_begin { 0 }; | ||
size_t partial_end { 0 }; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7f5fce1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't given a proper check to the lib, but correct me if I'm wrong:
This is applied only to vector structures, and the search method you are gonna use is "Binary Search", right?
Although this initially is a big improvement for canary, I don't think this is quite the best solution just yet. It might be way better to instead migrate into a tree structure, specifically an AVL structure, it'll be the optimal one given that the average complexity(not only for search, but for insertion and deletiona awell) NOT ONLY averages to log(n)(like it does with binary search), but the worst-case also is log(n).
7f5fce1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the world of coding, choosing between vector_sort and shifting towards an AVL tree boils down to the specific needs of the project. If you believe the proposed change makes sense for your particular use case, feel free to pitch in by submitting a pull request to put the idea into practice. The decision should be influenced by factors like how efficiently memory is used, how often you insert and delete data, and the unique search requirements of your project.
One of the beauties of open-source collaboration is the ability to consider and incorporate valuable suggestions from the community. So, if you think that embracing an AVL tree structure aligns better with your project's objectives, you can actively contribute by sharing your enhancements through a pull request. This collaborative spirit not only enriches the library but also benefits fellow developers in our community.
It's worth highlighting that discussions around implementations should ideally take place during the pull request phase, before the merge into the main branch. Post-merge comments on the primary branch commit might not be as effective in shaping the project's direction. Engaging in constructive conversations during the pull request review process allows for real-time feedback and ensures that the best decisions are made before code is merged, leading to a more cohesive and efficient development process.