-
Notifications
You must be signed in to change notification settings - Fork 422
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
Q: how do I delete a range? #18
Comments
For the sake of generating API ideas, consider how this works in a another red-black tree package. I can advance the iterator before deleting behind me:
output:
|
Great question, and sorry I didn't see this sooner. As you've found, currently our iterator functions aren't resilient to mutations during iteration. We might work on this later (and happy to accept pull requests ;), but to get things going right away, you could do this: todelete := []btree.Item{}
tree.Ascend(..., func(x btree.Item) bool {
todelete = append(todelete, x)
return true
})
for _, x := range todelete {
tree.Delete(x)
} It's not as efficient as it could be, and it requires extra storage, but it also actually works right now :) |
For efficiency, the DeleteMin() method turned out to work well. This is isn't a general solution if you want to delete a range that starts in the middle of you elements, but it worked for the case above. As in the example above, where you want to delete all elements belong some time threshold, with a callback for each deletion, I'm doing:
At least I think (hope) this is efficient. If its not, please let me know! :-) Typically a tree will keep a pointer to its minimum element... but if its log(n) to find the smallest element, this might be a problem... |
Actually its worse than I expected. https://github.com/google/btree/blob/master/btree.go#L153 makes it look like every delete is O(n) in the size of the tree n, as it does a full copy of the entire tree. This is really, really, not what I would expect from a balanced binary tree implementation. Deleting the entire tree becomes an O(n*n) operation. This is important. I'll make a separate issue. |
Nope, your original supposition was correct: it's O(logn) for a delete. https://github.com/google/btree/blob/master/btree.go#L153 is the code called to delete an item from a single node, which is O(degree) of the btree (items will be max 'degree' in length, one itemset per node). Your code is nicely efficient, but could be slightly moreso if you expect to delete more than 2 entries in your loop. In that case, you could blindly issue the delete, then put it back when you get to the one you care about. var item btree.Item
for item = t.DeleteMin(); item.(*mjob).endx <= x {}
t.Insert(item) Calling Min, which is O(logn), then Delete, which is O(logn) effectively doubles your processing time, unless you expect to only delete zero or one element each time. |
I ran into having to clear the tree myself today, created #20 which if it's not accepted it's small enough to copy pasta if it will help you. |
Suppose I have a simple set of intervals whose end time (endx) is stored in a btree. Lets say the interval represents the time a user's compute job completed, so I store the userid and a jobid with it too. I'll use the jobid (assume they are all unique) to break ties so that all records stick around.
Then I want to delete all those records with time <= some end time. Here's what I try:
here's what I get. This strange result presents in the upstream petar/gollrb as well.
The text was updated successfully, but these errors were encountered: