aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/containers
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/yt/containers
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'library/cpp/yt/containers')
-rw-r--r--library/cpp/yt/containers/intrusive_linked_list-inl.h122
-rw-r--r--library/cpp/yt/containers/intrusive_linked_list.h51
2 files changed, 173 insertions, 0 deletions
diff --git a/library/cpp/yt/containers/intrusive_linked_list-inl.h b/library/cpp/yt/containers/intrusive_linked_list-inl.h
new file mode 100644
index 0000000000..2b0a0c01c9
--- /dev/null
+++ b/library/cpp/yt/containers/intrusive_linked_list-inl.h
@@ -0,0 +1,122 @@
+#pragma once
+#ifndef INTRUSIVE_LINKED_LIST_INL_H_
+#error "Direct inclusion of this file is not allowed, include intrusive_linked_list.h"
+// For the sake of sane code completion.
+#include "intrusive_linked_list.h"
+#endif
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TItem, class TItemToNode>
+TIntrusiveLinkedList<TItem, TItemToNode>::TIntrusiveLinkedList(TItemToNode itemToNode)
+ : ItemToNode_(itemToNode)
+{ }
+
+template <class TItem, class TItemToNode>
+TItem* TIntrusiveLinkedList<TItem, TItemToNode>::GetFront() const
+{
+ return Front_;
+}
+
+template <class TItem, class TItemToNode>
+TItem* TIntrusiveLinkedList<TItem, TItemToNode>::GetBack() const
+{
+ return Back_;
+}
+
+template <class TItem, class TItemToNode>
+int TIntrusiveLinkedList<TItem, TItemToNode>::GetSize() const
+{
+ return Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::PushBack(TItem* item)
+{
+ auto* node = ItemToNode_(item);
+ if (Back_) {
+ ItemToNode_(Back_)->Next = item;
+ } else {
+ Front_ = item;
+ }
+ node->Next = nullptr;
+ node->Prev = Back_;
+ Back_ = item;
+ ++Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::PopBack()
+{
+ Y_ASSERT(Back_);
+ if (Front_ == Back_) {
+ Front_ = Back_ = nullptr;
+ } else {
+ Back_ = ItemToNode_(Back_)->Prev;
+ ItemToNode_(Back_)->Next = nullptr;
+ }
+ --Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::PushFront(TItem* item)
+{
+ auto* node = ItemToNode_(item);
+ if (Front_) {
+ ItemToNode_(Front_)->Prev = item;
+ } else {
+ Back_ = item;
+ }
+ node->Next = Front_;
+ node->Prev = nullptr;
+ Front_ = item;
+ ++Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::PopFront()
+{
+ Y_ASSERT(Front_);
+ if (Front_ == Back_) {
+ Front_ = Back_ = nullptr;
+ } else {
+ Front_ = ItemToNode_(Front_)->Next;
+ ItemToNode_(Front_)->Prev = nullptr;
+ }
+ --Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::Remove(TItem* item)
+{
+ YT_ASSERT(Front_);
+ auto* node = ItemToNode_(item);
+ if (node->Next) {
+ ItemToNode_(node->Next)->Prev = node->Prev;
+ }
+ if (node->Prev) {
+ ItemToNode_(node->Prev)->Next = node->Next;
+ }
+ if (Front_ == item) {
+ Front_ = node->Next;
+ }
+ if (Back_ == item) {
+ Back_ = node->Prev;
+ }
+ --Size_;
+}
+
+template <class TItem, class TItemToNode>
+void TIntrusiveLinkedList<TItem, TItemToNode>::Clear()
+{
+ Front_ = Back_ = nullptr;
+ Size_ = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/containers/intrusive_linked_list.h b/library/cpp/yt/containers/intrusive_linked_list.h
new file mode 100644
index 0000000000..0c19a9ca39
--- /dev/null
+++ b/library/cpp/yt/containers/intrusive_linked_list.h
@@ -0,0 +1,51 @@
+#pragma once
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TItem>
+struct TIntrusiveLinkedListNode
+{
+ TItem* Next = nullptr;
+ TItem* Prev = nullptr;
+};
+
+template <class TItem, class TItemToNode>
+class TIntrusiveLinkedList
+{
+public:
+ explicit TIntrusiveLinkedList(TItemToNode itemToNode = TItemToNode());
+
+ TItem* GetFront() const;
+ TItem* GetBack() const;
+
+ int GetSize() const;
+
+ void PushFront(TItem* item);
+ void PopFront();
+
+ void PushBack(TItem* item);
+ void PopBack();
+
+ void Remove(TItem* item);
+
+ void Clear();
+
+private:
+ const TItemToNode ItemToNode_;
+
+ TItem* Front_ = nullptr;
+ TItem* Back_ = nullptr;
+ int Size_ = 0;
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define INTRUSIVE_LINKED_LIST_INL_H_
+#include "intrusive_linked_list-inl.h"
+#undef INTRUSIVE_LINKED_LIST_INL_H_
+