Formatting code

This commit is contained in:
Ilusha 2023-06-30 14:02:55 +00:00
parent 6dc64ce76b
commit 13a8f07e32
37 changed files with 2242 additions and 2281 deletions

View file

@ -9,88 +9,88 @@ namespace tp {
NumericType val;
AvlNumericKey() = default;
AvlNumericKey(NumericType val) : val(val) {}
AvlNumericKey() = default;
AvlNumericKey(NumericType val) : val(val) {}
inline bool descentRight(AvlNumericKey in) const { return in.val > val; }
inline bool descentLeft(AvlNumericKey in) const { return in.val < val; }
inline bool exactNode(AvlNumericKey in) const { return in.val == val; }
inline bool descentLeft(AvlNumericKey in) const { return in.val < val; }
inline bool exactNode(AvlNumericKey in) const { return in.val == val; }
inline AvlNumericKey getFindKey(/**/) const { return *this; }
inline AvlNumericKey keyInRightSubtree(AvlNumericKey in) const { return in; }
inline AvlNumericKey keyInLeftSubtree(AvlNumericKey in) const { return in; }
inline AvlNumericKey getFindKey(/**/) const { return *this; }
inline AvlNumericKey keyInRightSubtree(AvlNumericKey in) const { return in; }
inline AvlNumericKey keyInLeftSubtree(AvlNumericKey in) const { return in; }
inline void updateTreeCacheCallBack() {}
inline void updateTreeCacheCallBack() {}
};
template <typename Key, typename Data, class Allocator = DefaultAllocator>
class AvlTree {
typedef SelCopyArg<Key> KeyArg;
typedef SelCopyArg<Data> DataArg;
typedef SelCopyArg<Key> KeyArg;
typedef SelCopyArg<Data> DataArg;
public:
class Node {
friend AvlTree;
public:
class Node {
friend AvlTree;
private:
Node(KeyArg aKey, DataArg aData) : key(aKey), data(aData) {}
private:
Node(KeyArg aKey, DataArg aData) : key(aKey), data(aData) {}
public:
Data data;
Key key;
public:
Data data;
Key key;
private:
Node* mLeft = nullptr;
Node* mRight = nullptr;
Node* mParent = nullptr;
ualni mHeight = 0;
private:
Node* mLeft = nullptr;
Node* mRight = nullptr;
Node* mParent = nullptr;
ualni mHeight = 0;
private:
inline bool descentRight(KeyArg aKey) const { return key.descentRight(aKey); }
inline bool descentLeft(KeyArg aKey) const { return key.descentLeft(aKey); }
inline bool exactNode(KeyArg aKey) const { return key.exactNode(aKey); }
private:
inline bool descentRight(KeyArg aKey) const { return key.descentRight(aKey); }
inline bool descentLeft(KeyArg aKey) const { return key.descentLeft(aKey); }
inline bool exactNode(KeyArg aKey) const { return key.exactNode(aKey); }
inline KeyArg getFindKey(const Node* node = nullptr) const { return key.getFindKey(/*node*/); }
inline KeyArg keyInRightSubtree(KeyArg aKey) const { return key.keyInRightSubtree(aKey); }
inline KeyArg keyInLeftSubtree(KeyArg aKey) const { return key.keyInLeftSubtree(aKey); }
inline KeyArg getFindKey(const Node* node = nullptr) const { return key.getFindKey(/*node*/); }
inline KeyArg keyInRightSubtree(KeyArg aKey) const { return key.keyInRightSubtree(aKey); }
inline KeyArg keyInLeftSubtree(KeyArg aKey) const { return key.keyInLeftSubtree(aKey); }
inline void updateTreeCacheCallBack() { key.updateTreeCacheCallBack(); }
};
inline void updateTreeCacheCallBack() { key.updateTreeCacheCallBack(); }
};
private:
Node* mRoot = nullptr;
ualni mSize = 0;
private:
Node* mRoot = nullptr;
ualni mSize = 0;
Allocator mAlloc;
private:
inline void deleteNode(Node* node) {
node->~Node();
mAlloc.deallocate(node);
}
private:
inline void deleteNode(Node* node) {
node->~Node();
mAlloc.deallocate(node);
}
inline Node* newNode(KeyArg key, DataArg data) {
return new (mAlloc.allocate(sizeof(Node))) Node(key, data);
}
inline Node* newNode(KeyArg key, DataArg data) {
return new (mAlloc.allocate(sizeof(Node))) Node(key, data);
}
inline void injectNodeInstead(Node* place, Node* inject) {
// TODO : swap instead of copy
place->data = inject->data;
place->key = inject->key;
}
inline void injectNodeInstead(Node* place, Node* inject) {
// TODO : swap instead of copy
place->data = inject->data;
place->key = inject->key;
}
inline alni getNodeHeight(const Node* node) const {
return node ? node->mHeight : -1;
}
// returns new head
Node* rotateLeft(Node* pivot) {
DEBUG_ASSERT(pivot);
Node* rotateLeft(Node* pivot) {
DEBUG_ASSERT(pivot);
Node* const head = pivot;
Node* const right = pivot->mRight;
Node* const right_left = right->mLeft;
Node* const parent = pivot->mParent;
Node* const head = pivot;
Node* const right = pivot->mRight;
Node* const right_left = right->mLeft;
Node* const parent = pivot->mParent;
// parents
if (right_left) right_left->mParent = head;
@ -112,13 +112,13 @@ namespace tp {
return right;
}
Node* rotateRight(Node* pivot) {
DEBUG_ASSERT(pivot);
Node* rotateRight(Node* pivot) {
DEBUG_ASSERT(pivot);
Node* const head = pivot;
Node* const left = pivot->mLeft;
Node* const left_right = left->mRight;
Node* const parent = pivot->mParent;
Node* const head = pivot;
Node* const left = pivot->mLeft;
Node* const left_right = left->mRight;
Node* const parent = pivot->mParent;
// parents
if (left_right) left_right->mParent = head;
@ -141,12 +141,12 @@ namespace tp {
}
// recursively returns valid left or right child or root
Node* insertUtil(Node* head, KeyArg key, DataArg data) {
Node* insertUtil(Node* head, KeyArg key, DataArg data) {
Node* insertedNode;
Node* insertedNode;
if (head == nullptr) {
mSize++;
mSize++;
Node* out = newNode(key, data);
out->updateTreeCacheCallBack();
return out;
@ -155,14 +155,14 @@ namespace tp {
return head;
}
else if (head->descentRight(key)) {
insertedNode = insertUtil(head->mRight, head->keyInRightSubtree(key), data);
insertedNode = insertUtil(head->mRight, head->keyInRightSubtree(key), data);
head->mRight = insertedNode;
insertedNode->mParent = head;
insertedNode->mParent = head;
}
else {
insertedNode = insertUtil(head->mLeft, head->keyInLeftSubtree(key), data);
insertedNode = insertUtil(head->mLeft, head->keyInLeftSubtree(key), data);
head->mLeft = insertedNode;
insertedNode->mParent = head;
insertedNode->mParent = head;
}
// update height
@ -194,31 +194,31 @@ namespace tp {
return head;
}
Node* removeUtil(Node* head, KeyArg key) {
Node* removeUtil(Node* head, KeyArg key) {
if (head == nullptr) return head;
if (head->exactNode(key)) {
if (head->mRight && head->mLeft) {
Node* min = minNode(head->mRight);
auto const& newKey = min->getFindKey(head->mRight);
injectNodeInstead(head, min);
Node* min = minNode(head->mRight);
auto const& newKey = min->getFindKey(head->mRight);
injectNodeInstead(head, min);
head->mRight = removeUtil(head->mRight, newKey);
}
else if (head->mRight) {
injectNodeInstead(head, head->mRight);
injectNodeInstead(head, head->mRight);
deleteNode(head->mRight);
head->mRight = nullptr;
mSize--;
mSize--;
}
else if (head->mLeft) {
injectNodeInstead(head, head->mLeft);
deleteNode(head->mLeft);
injectNodeInstead(head, head->mLeft);
deleteNode(head->mLeft);
head->mLeft = nullptr;
mSize--;
mSize--;
}
else {
deleteNode(head);
mSize--;
deleteNode(head);
mSize--;
head = nullptr;
}
}
@ -229,7 +229,7 @@ namespace tp {
head->mLeft = removeUtil(head->mLeft, head->keyInLeftSubtree(key));
}
if (head == nullptr) return head;
if (head == nullptr) return head;
head->mHeight = 1 + max(getNodeHeight(head->mRight), getNodeHeight(head->mLeft));
alni balance = getNodeHeight(head->mRight) - getNodeHeight(head->mLeft);
@ -268,7 +268,7 @@ namespace tp {
return mSize;
}
Node* head() const {
Node* head() const {
return this->mRoot;
}
@ -282,24 +282,24 @@ namespace tp {
if (mRoot) mRoot->mParent = nullptr;
}
Node* maxNode(Node* head) const {
if (!head) return nullptr;
while (head->mRight != nullptr) {
head = head->mRight;
}
return head;
}
Node* minNode(Node* head) const {
Node* maxNode(Node* head) const {
if (!head) return nullptr;
while (head->mLeft != nullptr) {
head = head->mLeft;
}
while (head->mRight != nullptr) {
head = head->mRight;
}
return head;
}
Node* find(KeyArg key) const {
Node* iter = mRoot;
Node* minNode(Node* head) const {
if (!head) return nullptr;
while (head->mLeft != nullptr) {
head = head->mLeft;
}
return head;
}
Node* find(KeyArg key) const {
Node* iter = mRoot;
while (true) {
if (!iter) return nullptr;
if (iter->exactNode(key)) return iter;
@ -313,61 +313,61 @@ namespace tp {
}
}
Node* findLessOrEq(KeyArg key) const {
Node* iter = mRoot;
while (true) {
if (!iter) return nullptr;
if (iter->exactNode(key)) return iter;
if (iter->descentLeft(key)) {
if (iter->mLeft) {
key = iter->keyInLeftSubtree(key);
iter = iter->mLeft;
} else {
return iter;
}
} else {
if (iter->mRight) {
key = iter->keyInRightSubtree(key);
iter = iter->mRight;
} else {
return iter;
}
}
}
}
Node* findLessOrEq(KeyArg key) const {
Node* iter = mRoot;
while (true) {
if (!iter) return nullptr;
if (iter->exactNode(key)) return iter;
if (iter->descentLeft(key)) {
if (iter->mLeft) {
key = iter->keyInLeftSubtree(key);
iter = iter->mLeft;
} else {
return iter;
}
} else {
if (iter->mRight) {
key = iter->keyInRightSubtree(key);
iter = iter->mRight;
} else {
return iter;
}
}
}
}
// returns first invalid node
const Node* findInvalidNode(const Node* head) const {
const Node* findInvalidNode(const Node* head) const {
if (head == nullptr) return nullptr;
if (head->mLeft) {
// TODO: incomplete test
if (!head->descentLeft(head->mLeft->getFindKey(head))) return head;
if (head->mLeft->mParent != head) return head;
if (!head->mRight && head->mLeft->mHeight != head->mHeight - 1) return head;
if (!head->mRight && head->mLeft->mHeight != head->mHeight - 1) return head;
}
if (head->mRight) {
if (!head->descentRight(head->mRight->getFindKey(head))) return head;
if (head->mRight->mParent != head) return head;
if (!head->mLeft && head->mRight->mHeight != head->mHeight - 1) return head;
if (!head->mLeft && head->mRight->mHeight != head->mHeight - 1) return head;
}
if (head->mLeft && head->mRight) {
if (max(head->mLeft->mHeight, head->mRight->mHeight) != head->mHeight - 1) return head;
}
if (head->mLeft && head->mRight) {
if (max(head->mLeft->mHeight, head->mRight->mHeight) != head->mHeight - 1) return head;
}
int balance = getNodeHeight(head->mRight) - getNodeHeight(head->mLeft);
if (balance > 1 || balance < -1) return head;
const Node* ret = findInvalidNode(head->mRight);
const Node* ret = findInvalidNode(head->mRight);
if (ret) return ret;
return findInvalidNode(head->mLeft);
}
bool isValid() { return findInvalidNode(head()) == nullptr; }
bool isValid() { return findInvalidNode(head()) == nullptr; }
};
}

View file

@ -4,23 +4,23 @@
#include "Module.hpp"
namespace tp {
extern ModuleManifest gModuleContainers;
extern ModuleManifest gModuleContainers;
class DefaultAllocator {
public:
DefaultAllocator() = default;
static void *allocate(ualni);
static void deallocate(void *);
};
class DefaultAllocator {
public:
DefaultAllocator() = default;
static void *allocate(ualni);
static void deallocate(void *);
};
class DefaultSaverLoader {
public:
DefaultSaverLoader() = default;
class DefaultSaverLoader {
public:
DefaultSaverLoader() = default;
template<typename Type>
static void write(const Type&) {}
template<typename Type>
static void write(const Type&) {}
template<typename Type>
static void read(Type&) {}
};
template<typename Type>
static void read(Type&) {}
};
}

View file

@ -7,92 +7,92 @@
namespace tp {
template <typename Type, class Allocator = DefaultAllocator>
template <typename Type, class Allocator = DefaultAllocator>
class List {
typedef SelCopyArg<Type> TypeArg;
typedef ualni Index;
typedef SelCopyArg<Type> TypeArg;
typedef ualni Index;
public:
public:
struct Node {
Type data;
Node* next = nullptr;
Node* prev = nullptr;
Node() = default;
explicit Node(TypeArg p_data) : data(p_data) {}
Type& operator->() { return data; }
};
struct Node {
Type data;
Node* next = nullptr;
Node* prev = nullptr;
Node() = default;
explicit Node(TypeArg p_data) : data(p_data) {}
Type& operator->() { return data; }
};
class IteratorPointer {
protected:
Node* mIter;
public:
IteratorPointer() = default;
Type& operator->() { return (mIter->data); }
const Type& operator->() const { return (mIter->data); }
};
class IteratorPointer {
protected:
Node* mIter;
public:
IteratorPointer() = default;
Type& operator->() { return (mIter->data); }
const Type& operator->() const { return (mIter->data); }
};
class IteratorReference {
protected:
Node* mIter;
public:
IteratorReference() = default;
Type* operator->() { return &(mIter->data); }
const Type* operator->() const { return &(mIter->data); }
};
class IteratorReference {
protected:
Node* mIter;
public:
IteratorReference() = default;
Type* operator->() { return &(mIter->data); }
const Type* operator->() const { return &(mIter->data); }
};
class Iterator : public TypeSelect<TypeTraits<Type>::isPointer, IteratorPointer, IteratorReference>::Result {
public:
class Iterator : public TypeSelect<TypeTraits<Type>::isPointer, IteratorPointer, IteratorReference>::Result {
public:
explicit Iterator(Node* iter) { this->mIter = iter; }
explicit Iterator(Node* iter) { this->mIter = iter; }
Node* node() { return this->mIter; }
Type& data() { return this->mIter->data; }
const Node* node() const { return this->mIter; }
const Type& data() const { return this->mIter->data; }
Node* node() { return this->mIter; }
Type& data() { return this->mIter->data; }
const Node* node() const { return this->mIter; }
const Type& data() const { return this->mIter->data; }
const Iterator& operator*() const { return *this; }
const Iterator& operator*() const { return *this; }
Iterator& operator++() {
this->mIter = this->mIter->next;
return *this;
}
Iterator& operator++() {
this->mIter = this->mIter->next;
return *this;
}
bool operator==(const Iterator& left) const { return left.mIter == this->mIter; }
bool operator!=(const Iterator& left) const { return left.mIter != this->mIter; }
};
bool operator==(const Iterator& left) const { return left.mIter == this->mIter; }
bool operator!=(const Iterator& left) const { return left.mIter != this->mIter; }
};
private:
private:
Node* mFirst = nullptr;
Node* mLast = nullptr;
Index mLength = 0;
Allocator mAlloc;
public:
public:
List() = default;
List(const init_list<Type>& list) { operator=(list); }
[[nodiscard]] inline Node* first() const { return mFirst; }
[[nodiscard]] inline Node* last() const { return mLast; }
[[nodiscard]] inline Node* first() const { return mFirst; }
[[nodiscard]] inline Node* last() const { return mLast; }
[[nodiscard]] inline Index length() const { return mLength; }
[[nodiscard]] Node* newNode() { return new (mAlloc.allocate(sizeof(Node))) Node(); }
[[nodiscard]] Node* newNode(TypeArg arg) { return new (mAlloc.allocate(sizeof(Node))) Node(arg); }
[[nodiscard]] Node* newNodeNotConstructed() {
auto node = (Node*) mAlloc.allocate(sizeof(Node));
node->next = node->prev = nullptr;
return node;
}
[[nodiscard]] Node* newNode() { return new (mAlloc.allocate(sizeof(Node))) Node(); }
[[nodiscard]] Node* newNode(TypeArg arg) { return new (mAlloc.allocate(sizeof(Node))) Node(arg); }
[[nodiscard]] Node* newNodeNotConstructed() {
auto node = (Node*) mAlloc.allocate(sizeof(Node));
node->next = node->prev = nullptr;
return node;
}
[[nodiscard]] const Allocator& getAllocator() const { return mAlloc; }
[[nodiscard]] const Allocator& getAllocator() const { return mAlloc; }
void deleteNode(Node* node) {
node->~Node();
mAlloc.deallocate(node);
}
void deleteNode(Node* node) {
node->~Node();
mAlloc.deallocate(node);
}
Node* addNodeBack() {
auto const out = newNode();
@ -145,7 +145,7 @@ namespace tp {
mLength--;
}
[[nodiscard]] Node* findIdx(Index idx) const {
[[nodiscard]] Node* findIdx(Index idx) const {
DEBUG_ASSERT(!mFirst || idx > mLength - 1)
Node* found = mFirst;
for (int i = 0; i != idx; i++) {
@ -154,7 +154,7 @@ namespace tp {
return found;
}
[[nodiscard]] Node* find(const TypeArg data) const {
[[nodiscard]] Node* find(const TypeArg data) const {
Node* found = mFirst;
for (alni i = 0; data != found->data; i++) {
if (!found->next) {
@ -165,33 +165,33 @@ namespace tp {
return found;
}
[[nodiscard]] inline const Type& operator[](Index idx) const {
[[nodiscard]] inline const Type& operator[](Index idx) const {
DEBUG_ASSERT(idx < mLength)
return find(idx)->data;
}
void pushBack(Node* new_node) { attach(new_node, mLast); }
void pushFront(Node* new_node) { attach(new_node, nullptr); }
void pushFront(Node* new_node) { attach(new_node, nullptr); }
void pushBack(TypeArg data) { pushBack(newNode(data)); }
void pushFront(TypeArg data) { pushFront(newNode(data)); }
void popBack() {
DEBUG_ASSERT(mLast)
detach(mLast);
deleteNode(mLast);
DEBUG_ASSERT(mLast)
detach(mLast);
deleteNode(mLast);
}
void popFront() {
DEBUG_ASSERT(mFirst)
auto temp = mFirst;
detach(mFirst);
deleteNode(temp);
auto temp = mFirst;
detach(mFirst);
deleteNode(temp);
}
void insert(Node* node, Index idx) {
if (!mLength) {
attach(node, mLast);
} else if (idx >= mLength) {
attach(node, mLast);
} else if (idx >= mLength) {
attach(node, nullptr);
} else {
attach(node, find(idx)->prev);
@ -209,11 +209,11 @@ namespace tp {
void removeAll() {
while (mFirst) {
popFront();
}
popFront();
}
}
// copies data
// copies data
List& operator+=(const List& in) {
for (auto node : in) {
pushBack(node.data());
@ -229,38 +229,38 @@ namespace tp {
}
List& operator=(const List& in) {
if (this == &in) { return *this; }
if (this == &in) { return *this; }
removeAll();
(*this) += in;
(*this) += in;
return *this;
}
List& operator=(const init_list<Type>& list) {
removeAll();
removeAll();
*this += list;
return *this;
}
[[nodiscard]] bool operator==(const List& in) const {
if (in == *this) { return true; }
if (in.length() != length()) {
return false;
}
Node* left = in.first();
Node* right = first();
while (left && right) {
if (left->data != right->data) {
return false;
}
}
if (left != right) {
return false;
}
return true;
}
[[nodiscard]] bool operator==(const List& in) const {
if (in == *this) { return true; }
if (in.length() != length()) {
return false;
}
Node* left = in.first();
Node* right = first();
while (left && right) {
if (left->data != right->data) {
return false;
}
}
if (left != right) {
return false;
}
return true;
}
template <typename compare_val>
[[nodiscard]] Node* find(bool (*found)(Node* node, compare_val val), compare_val value) const {
[[nodiscard]] Node* find(bool (*found)(Node* node, compare_val val), compare_val value) const {
for (Node* node = mFirst; node; node = node->next) {
if (found(node, value)) {
return node;
@ -269,12 +269,12 @@ namespace tp {
return nullptr;
}
[[nodiscard]] Iterator begin() const {
[[nodiscard]] Iterator begin() const {
Iterator out(mFirst);
return out;
}
[[nodiscard]] Iterator end() const {
[[nodiscard]] Iterator end() const {
return Iterator(nullptr);
}
@ -290,33 +290,33 @@ namespace tp {
}
void detachAll() {
while (mFirst) {
detach(mFirst);
}
while (mFirst) {
detach(mFirst);
}
}
template<class Saver>
void write(Saver& file) const {
file.write(mLength);
for (auto item : *this) {
file.write(item.data());
}
}
template<class Saver>
void write(Saver& file) const {
file.write(mLength);
for (auto item : *this) {
file.write(item.data());
}
}
template<class Loader>
void read(Loader& file) {
removeAll();
ualni len;
file.read(len);
for (auto i = len; i; i--) {
auto node = newNodeNotConstructed();
file.read(node->data);
pushBack(node);
}
}
template<class Loader>
void read(Loader& file) {
removeAll();
ualni len;
file.read(len);
for (auto i = len; i; i--) {
auto node = newNodeNotConstructed();
file.read(node->data);
pushBack(node);
}
}
~List() {
removeAll();
}
~List() {
removeAll();
}
};
}

View file

@ -11,12 +11,7 @@ namespace tp {
return hash(key);
}
template<
typename tKey, typename tVal,
class tAllocator = DefaultAllocator,
ualni(*tHashFunc)(SelCopyArg<tKey>) = DefaultHashFunc<tKey>,
int tTableInitialSize = 4
>
template<typename tKey, typename tVal, class tAllocator = DefaultAllocator, ualni(*tHashFunc)(SelCopyArg<tKey>) = DefaultHashFunc<tKey>, int tTableInitialSize = 4>
class Map {
enum {
@ -25,23 +20,23 @@ namespace tp {
MAP_MAX_LOAD_PERCENTAGE = 66,
};
typedef SelCopyArg<tKey> KeyArg;
typedef SelCopyArg<tVal> ValArg;
typedef SelCopyArg<tKey> KeyArg;
typedef SelCopyArg<tVal> ValArg;
public:
class Node {
friend Map;
Node(KeyArg aKey, ValArg aVal) : key(aKey), val(aVal) {}
public:
friend Map;
Node(KeyArg aKey, ValArg aVal) : key(aKey), val(aVal) {}
public:
tKey key;
tVal val;
};
struct Idx {
alni idx = -1;
operator bool() { return idx != -1; }
};
struct Idx {
alni idx = -1;
operator bool() { return idx != -1; }
};
private:
tAllocator mAlloc;
@ -49,160 +44,160 @@ namespace tp {
ualni mNSlots = 0;
ualni mNEntries = 0;
private:
private:
constexpr halnf maxLoadFactor() { return halnf(MAP_MAX_LOAD_PERCENTAGE) / 100.f; }
inline Node** newTable(const ualni len) {
return new(mAlloc.allocate(sizeof(Node*) * len)) Node*[len]();
}
inline Node** newTable(const ualni len) {
return new(mAlloc.allocate(sizeof(Node*) * len)) Node*[len]();
}
inline Node* newNode(KeyArg key, ValArg val) {
return new(mAlloc.allocate(sizeof(Node))) Node(key, val);
}
inline Node* newNode(KeyArg key, ValArg val) {
return new(mAlloc.allocate(sizeof(Node))) Node(key, val);
}
inline Node* newNodeNotConstructed() {
return (Node*) mAlloc.allocate(sizeof(Node));
}
inline Node* newNodeNotConstructed() {
return (Node*) mAlloc.allocate(sizeof(Node));
}
inline void deleteTable(Node** table) {
mAlloc.deallocate(table);
}
inline void deleteTable(Node** table) {
mAlloc.deallocate(table);
}
inline void deleteNode(Node* p) {
p->~Node();
mAlloc.deallocate(p);
}
inline void deleteNode(Node* p) {
p->~Node();
mAlloc.deallocate(p);
}
void markDeletedSlot(ualni idx) const {
mTable[idx] = (Node*)-1;
}
void markDeletedSlot(ualni idx) const {
mTable[idx] = (Node*)-1;
}
static bool isDeletedNode(Node* node) {
return node == (Node*)-1;
}
static bool isDeletedNode(Node* node) {
return node == (Node*)-1;
}
void rehash() {
alni nSlotsOld = mNSlots;
Node** tableOld = mTable;
void rehash() {
alni nSlotsOld = mNSlots;
Node** tableOld = mTable;
mNSlots = next2pow((uhalni)((1.f / (maxLoadFactor())) * mNEntries + 1));
mTable = newTable(mNSlots);
mNEntries = 0;
mNSlots = next2pow((uhalni)((1.f / (maxLoadFactor())) * mNEntries + 1));
mTable = newTable(mNSlots);
mNEntries = 0;
for (alni i = 0; i < nSlotsOld; i++) {
if (!tableOld[i] || isDeletedNode(tableOld[i])) {
continue;
}
for (alni i = 0; i < nSlotsOld; i++) {
if (!tableOld[i] || isDeletedNode(tableOld[i])) {
continue;
}
alni idx = findSlotWrite(tableOld[i]->key);
mTable[idx] = tableOld[i];
mNEntries++;
}
alni idx = findSlotWrite(tableOld[i]->key);
mTable[idx] = tableOld[i];
mNEntries++;
}
deleteTable(tableOld);
}
deleteTable(tableOld);
}
alni findSlotRead(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
alni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx])) {
goto SKIP;
}
if (!mTable[idx]) {
return -1;
}
if (mTable[idx]->key == key) {
return idx;
}
SKIP:
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
alni findSlotRead(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
alni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx])) {
goto SKIP;
}
if (!mTable[idx]) {
return -1;
}
if (mTable[idx]->key == key) {
return idx;
}
SKIP:
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
// compares keys only when collisions occur
alni findSlotReadExisting(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
alni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx])) {
goto SKIP;
}
if (!mTable[idx]) {
return -1;
}
if (mTable[((5 * idx) + 1 + shift) & mask] == nullptr) {
return idx;
}
if (mTable[idx]->key == key) {
return idx;
}
SKIP:
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
// compares keys only when collisions occur
alni findSlotReadExisting(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
alni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx])) {
goto SKIP;
}
if (!mTable[idx]) {
return -1;
}
if (mTable[((5 * idx) + 1 + shift) & mask] == nullptr) {
return idx;
}
if (mTable[idx]->key == key) {
return idx;
}
SKIP:
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
ualni findSlotWrite(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
ualni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx]) || !mTable[idx]) {
return idx;
}
if (mTable[idx]->key == key) {
return idx;
}
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
ualni findSlotWrite(KeyArg key) const {
ualni const hashed_key = tHashFunc(key);
ualni const mask = mNSlots - 1;
ualni const shift = (hashed_key >> MAP_PERTURB_SHIFT) & ~1;
ualni idx = hashed_key & mask;
NEXT:
if (isDeletedNode(mTable[idx]) || !mTable[idx]) {
return idx;
}
if (mTable[idx]->key == key) {
return idx;
}
idx = ((5 * idx) + 1 + shift) & mask;
goto NEXT;
}
void put(Node* node) {
const ualni idx = findSlotWrite(node->key);
void put(Node* node) {
const ualni idx = findSlotWrite(node->key);
if (!mTable[idx] || isDeletedNode(mTable[idx])) {
mNEntries++;
}
if (!mTable[idx] || isDeletedNode(mTable[idx])) {
mNEntries++;
}
mTable[idx] = node;
mTable[idx] = node;
if ((halnf)mNEntries / mNSlots > maxLoadFactor()) {
rehash();
}
}
if ((halnf)mNEntries / mNSlots > maxLoadFactor()) {
rehash();
}
}
public:
Map() {
MODULE_SANITY_CHECK(gModuleContainers)
mNSlots = next2pow(uhalni(tTableInitialSize - 1));
mTable = newTable(mNSlots);
}
Map() {
MODULE_SANITY_CHECK(gModuleContainers)
mNSlots = next2pow(uhalni(tTableInitialSize - 1));
mTable = newTable(mNSlots);
}
Node** buff() const {
return mTable;
}
Node** buff() const {
return mTable;
}
[[nodiscard]] ualni size() const {
return mNEntries;
}
[[nodiscard]] ualni size() const {
return mNEntries;
}
[[nodiscard]] ualni slotsSize() const {
return mNEntries;
}
[[nodiscard]] ualni slotsSize() const {
return mNEntries;
}
[[nodiscard]] const tAllocator& getAllocator() const {
return mAlloc;
}
[[nodiscard]] const tAllocator& getAllocator() const {
return mAlloc;
}
void put(KeyArg key, ValArg val) {
const ualni idx = findSlotWrite(key);
const ualni idx = findSlotWrite(key);
if (!mTable[idx] || isDeletedNode(mTable[idx])) {
mTable[idx] = newNode(key, val);
mNEntries++;
@ -215,22 +210,22 @@ namespace tp {
// undefined behavior if item is not presents
tVal& get(KeyArg key) {
DEBUG_ASSERT(findSlotRead(key) != -1 && "Key Error")
DEBUG_ASSERT(findSlotRead(key) != -1 && "Key Error")
return mTable[findSlotReadExisting(key)]->val;
}
const tVal& get(KeyArg key) const {
DEBUG_ASSERT(findSlotRead(key) != -1 && "Key Error")
return mTable[findSlotReadExisting(key)]->val;
return mTable[findSlotReadExisting(key)]->val;
}
[[nodiscard]] Idx presents(KeyArg key) const { return { findSlotRead(key) }; }
[[nodiscard]] Idx presents(KeyArg key) const { return { findSlotRead(key) }; }
void remove(KeyArg key) {
DEBUG_ASSERT(findSlotRead(key) != -1 && "Key Error")
auto idx = findSlotReadExisting(key);
DEBUG_ASSERT(findSlotRead(key) != -1 && "Key Error")
auto idx = findSlotReadExisting(key);
deleteNode(mTable[idx]);
deleteNode(mTable[idx]);
markDeletedSlot(idx);
@ -241,30 +236,30 @@ namespace tp {
}
const tVal& getSlotVal(ualni slot) const {
DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error")
return mTable[slot]->val;
}
DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error")
return mTable[slot]->val;
}
tVal& getSlotVal(ualni slot) {
DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error")
return mTable[slot]->val;
}
DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error")
return mTable[slot]->val;
}
const tVal& getSlotVal(Idx slot) const {
DEBUG_ASSERT(slot.idx < mNSlots && (mTable[slot.idx] && !isDeletedNode(mTable[slot.idx])) && "Key Error")
DEBUG_ASSERT(slot.idx < mNSlots && (mTable[slot.idx] && !isDeletedNode(mTable[slot.idx])) && "Key Error")
return mTable[slot]->val;
}
tVal& getSlotVal(Idx slot) {
DEBUG_ASSERT(slot.idx < mNSlots && (mTable[slot.idx] && !isDeletedNode(mTable[slot.idx])) && "Key Error")
DEBUG_ASSERT(slot.idx < mNSlots && (mTable[slot.idx] && !isDeletedNode(mTable[slot.idx])) && "Key Error")
return mTable[slot.idx]->val;
}
Map& operator=(const Map& in) {
if (this == &in) {
return *this;
}
removeAll();
if (this == &in) {
return *this;
}
removeAll();
mNSlots = in.mNSlots;
mTable = newTable(mNSlots);
for (alni i = 0; i < mNSlots; i++) {
@ -272,31 +267,31 @@ namespace tp {
put(in.mTable[i]->key, in.mTable[i]->val);
}
}
return *this;
return *this;
}
[[nodiscard]] bool operator==(const Map& in) const {
if (this == &in) {
return true;
}
if (in.mNEntries != mNEntries) {
return false;
}
for (auto i : in) {
if (!presents(i->key) || get(i->key) != i->val) {
return false;
}
}
return true;
}
[[nodiscard]] bool operator==(const Map& in) const {
if (this == &in) {
return true;
}
if (in.mNEntries != mNEntries) {
return false;
}
for (auto i : in) {
if (!presents(i->key) || get(i->key) != i->val) {
return false;
}
}
return true;
}
void removeAll() {
for (ualni i = 0; i < mNSlots; i++) {
if (mTable[i] && !isDeletedNode(mTable[i])) {
deleteNode(mTable[i]);
deleteNode(mTable[i]);
}
}
deleteTable(mTable);
deleteTable(mTable);
mTable = newTable(tTableInitialSize);
mNSlots = tTableInitialSize;
mNEntries = 0;
@ -323,74 +318,74 @@ namespace tp {
const Node* GetEntry(ualni idx) const {
auto slot = slotIdx(idx);
DEBUG_ASSERT(slot != -1 && "Key error")
DEBUG_ASSERT(slot != -1 && "Key error")
return mTable[slot];
}
public:
public:
class Iterator {
const Map* map;
Node* mIter;
alni mSlot;
alni mEntry;
class Iterator {
const Map* map;
Node* mIter;
alni mSlot;
alni mEntry;
friend Map;
explicit Iterator(const Map* _map) {
mSlot = -1;
mEntry = -1;
map = _map;
this->operator++();
}
friend Map;
explicit Iterator(const Map* _map) {
mSlot = -1;
mEntry = -1;
map = _map;
this->operator++();
}
public:
Node* operator->() { return mIter; }
const Node* operator->() const { return mIter; }
const Iterator& operator*() const { return *this; }
public:
Node* operator->() { return mIter; }
const Node* operator->() const { return mIter; }
const Iterator& operator*() const { return *this; }
bool operator!=(ualni idx) const { return mSlot != idx; }
bool operator!=(ualni idx) const { return mSlot != idx; }
void operator++() {
mSlot++;
while ((map->isDeletedNode(map->mTable[mSlot]) || !map->mTable[mSlot]) && (mSlot != map->mNSlots)) {
mSlot++;
}
if (mSlot != map->mNSlots) {
mIter = map->mTable[mSlot];
mEntry++;
}
}
};
void operator++() {
mSlot++;
while ((map->isDeletedNode(map->mTable[mSlot]) || !map->mTable[mSlot]) && (mSlot != map->mNSlots)) {
mSlot++;
}
if (mSlot != map->mNSlots) {
mIter = map->mTable[mSlot];
mEntry++;
}
}
};
[[nodiscard]] Iterator begin() const {
return Iterator(this);
}
[[nodiscard]] Iterator begin() const {
return Iterator(this);
}
[[nodiscard]] ualni end() const {
return mNSlots;
}
return mNSlots;
}
template<class Saver>
void write(Saver& file) {
file.write(mNEntries);
for (auto item : *this) {
file.write(item->val);
file.write(item->key);
}
}
template<class Saver>
void write(Saver& file) {
file.write(mNEntries);
for (auto item : *this) {
file.write(item->val);
file.write(item->key);
}
}
template<class Loader>
void read(Loader& file) {
removeAll();
ualni len;
file.read(len);
for (auto i = len; i; i--) {
auto node = newNodeNotConstructed();
file.read(node->val);
file.read(node->key);
put(node);
}
}
template<class Loader>
void read(Loader& file) {
removeAll();
ualni len;
file.read(len);
for (auto i = len; i; i--) {
auto node = newNodeNotConstructed();
file.read(node->val);
file.read(node->key);
put(node);
}
}
~Map() { removeAll(); }
};