-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: interval tree complete implemention based on red-black tree #10881
Conversation
@@ -425,14 +475,14 @@ func (ivt *IntervalTree) find(ivl Interval) (ret *intervalNode) { | |||
ret = n | |||
return false | |||
} | |||
ivt.root.visit(&ivl, f) | |||
ivt.root.visit(&ivl, ivt.nilNode, f) | |||
return ret | |||
} | |||
|
|||
// Find gets the IntervalValue for the node matching the given interval | |||
func (ivt *IntervalTree) Find(ivl Interval) (ret *IntervalValue) { | |||
n := ivt.find(ivl) |
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.
If not found, does find() return nil or nilNode?
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.
find() function return is nilNode, it is private function, I think its ok.
please help me check the code
Codecov Report
@@ Coverage Diff @@
## master #10881 +/- ##
==========================================
+ Coverage 62.14% 63.86% +1.72%
==========================================
Files 398 401 +3
Lines 37483 37483
==========================================
+ Hits 23293 23939 +646
+ Misses 12597 11930 -667
- Partials 1593 1614 +21
Continue to review full report at Codecov.
|
@jingyih I had change the find function bugs, but Travis CI failed, please help see it. |
https://travis-ci.com/etcd-io/etcd/jobs/215119452 https://travis-ci.com/etcd-io/etcd/jobs/215119455 |
Thank for your help. This PR CI had passed. |
The interval tree code visit() will call a node visitor on each node that overlaps the given interval. can your optimize the function performance |
@xiang90 PTAL. |
@@ -34,3 +34,5 @@ vendor/**/* | |||
vendor/**/*_test.go | |||
|
|||
*.bak | |||
|
|||
.vscode/ |
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.
new line
@@ -171,45 +171,60 @@ type IntervalValue struct { | |||
type IntervalTree struct { | |||
root *intervalNode | |||
count int | |||
|
|||
// red-black NIL node, can not use golang nil instead |
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.
can you explain why we cannot use golang nil to represent the NIL node? If we do need a NIL node instance for comparison, shall we make it a package global variable so that we do not need to pass it around?
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.
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.
@xiang90
Because of the tree is also Binary Search Tree, so the code all cases are right.
The Introduction to algorithms tell us when delete leaf black node
, then NIL node will be double black
.
Red-black tree nature 5: For each node, the same number of black nodes are included on the path of the node nodes after reaching the node.
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.
@xiang90 The NIL node can not a package global variable. It's a pointer variable, there are many trees.
@xkeyideal @xiang90 @jingyih I am writing a test case to validate the fix. Will cherry-pick this patch with some clean up + documentation. |
pkg/adt/interval_tree.go
Outdated
@@ -353,45 +367,54 @@ func (ivt *IntervalTree) insertFixup(z *intervalNode) { | |||
|
|||
// rotateLeft moves x so it is left of its right child | |||
func (ivt *IntervalTree) rotateLeft(x *intervalNode) { | |||
|
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.
remove this empty line
pkg/adt/interval_tree.go
Outdated
func (ivt *IntervalTree) rotateRight(x *intervalNode) { | ||
if x == nil { | ||
|
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.
remove
pkg/adt/interval_tree.go
Outdated
if n.iv.Ivl != ivl { | ||
return true | ||
func (ivt *IntervalTree) find(ivl Interval) *intervalNode { | ||
|
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.
remove
pkg/adt/interval_tree.go
Outdated
f := func(n *IntervalValue) bool { | ||
ivt.Insert(n.Ivl, n.Val) | ||
return true | ||
} | ||
inIvt.Visit(ivl, f) | ||
} | ||
|
||
func (ivt *IntervalTree) LevelOrder() [][]*intervalNode { |
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.
is this only used by test? if so, move this to test file.
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.
Yes, I will change.
pkg/adt/interval_tree.go
Outdated
f := func(n *IntervalValue) bool { | ||
ivt.Insert(n.Ivl, n.Val) | ||
return true | ||
} | ||
inIvt.Visit(ivl, f) | ||
} | ||
|
||
func (ivt *IntervalTree) LevelOrder() [][]*intervalNode { | ||
|
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.
remove empty line
pkg/adt/interval_tree_test.go
Outdated
{&intervalNode{iv: IntervalValue{NewInt64Interval(953, 954), 12}}, red}, | ||
} | ||
|
||
/* |
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.
use go style comment. do not use /*
, use //
instead.
} | ||
ivt.root.visit(&ivl, f) |
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.
why not just call visit as before?
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.
the visit function maybe visit all nodes for find one node, the new find function use BST nature can prune, but when find left interval same, the must use visit function visit the subtree all nodes for find the node
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.
if this is an optimization, can we move this to a separate PR?
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 think it is just make it better, not optimization
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.
OK. Then can we not include this enhancement in this PR?
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.
OK, the change the find function just use visit
@xiang90 Please help me see the Travis CI why not build failed. |
This doesn't seem to fix the issue. Let me rework on this. |
@xkeyideal I tried your patch with sentinel node. It fixes the delete operation maintaining the black-height properties, but it breaks visit operation thus breaking contains and stab methods. Could you take a look #10965 and try again with latest changes? I refactored the code with failure test cases from this PR. Thanks! |
#10877
Fixed interval tree