From ca47fc7efd41fdec7fa98d4f6a4758e1e735cfef Mon Sep 17 00:00:00 2001 From: m4ushold Date: Wed, 2 Oct 2024 13:25:48 +0900 Subject: [PATCH 1/2] optimize splay tree To prevent the tree from becoming skewed, I balanced it by splaying the first node of the sequence every 500 linear insert operations. The value 500 was determined experimentally. --- pkg/splay/splay.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pkg/splay/splay.go b/pkg/splay/splay.go index 8c6563aa1..d23023f5a 100644 --- a/pkg/splay/splay.go +++ b/pkg/splay/splay.go @@ -92,13 +92,16 @@ func (t *Node[V]) hasLinks() bool { // Tree is weighted binary search tree which is based on Splay tree. // original paper on Splay Trees: https://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf type Tree[V Value] struct { - root *Node[V] + root *Node[V] + linearCount int + firstNode *Node[V] } // NewTree creates a new instance of Tree. func NewTree[V Value](root *Node[V]) *Tree[V] { return &Tree[V]{ - root: root, + root: root, + linearCount: 0, } } @@ -114,6 +117,18 @@ func (t *Tree[V]) Insert(node *Node[V]) *Node[V] { // InsertAfter inserts the node after the given previous node. func (t *Tree[V]) InsertAfter(prev *Node[V], node *Node[V]) *Node[V] { + if prev == t.root { + t.linearCount++ + if t.linearCount == 1 { + t.firstNode = node + } else if t.linearCount > 500 { + t.Splay(t.firstNode) + t.linearCount = 0 + } + } else { + t.linearCount = 0 + } + t.Splay(prev) t.root = node node.right = prev.right From 9952737bdddae84a7d8e521e71647962cb36c9c6 Mon Sep 17 00:00:00 2001 From: raararaara Date: Fri, 21 Feb 2025 17:22:13 +0900 Subject: [PATCH 2/2] Trigger CI