Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Q: how do I delete a range? #18

@glycerine

Description

@glycerine

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:

package main

import (
	"fmt"

	"github.com/google/btree"
)

type job struct {
	endx  int64
	user  string
	jobid string
}

func (a *job) Less(than btree.Item) bool {
	b := than.(*job)
	if a.endx == b.endx {
		// simply distinguish the order,
		// so we get to keep both in the tree.
		return a.jobid < b.jobid
	}
	return a.endx < b.endx
}

func main() {
	tree := btree.New(2)

	tree.ReplaceOrInsert(&job{endx: 1, jobid: "hij"})
	tree.ReplaceOrInsert(&job{endx: 1, jobid: "abc"})
	tree.ReplaceOrInsert(&job{endx: 1, jobid: "def"})

	tree.ReplaceOrInsert(&job{endx: 2, jobid: "hij"})
	tree.ReplaceOrInsert(&job{endx: 2, jobid: "abc"})
	tree.ReplaceOrInsert(&job{endx: 2, jobid: "def"})

	tree.ReplaceOrInsert(&job{endx: 3, jobid: "hij"})
	tree.ReplaceOrInsert(&job{endx: 3, jobid: "abc"})
	tree.ReplaceOrInsert(&job{endx: 3, jobid: "def"})

	fmt.Printf("len = %v\n", tree.Len())

	// delete through the 2s
	tree.AscendGreaterOrEqual(&job{endx: 0}, func(item btree.Item) bool {
		j := item.(*job)
		if j.endx <= 2 {
			fmt.Printf("delete pass deletes %#v\n", item)
			tree.Delete(j)
			return true
		}
		fmt.Printf("delete pass ignores %#v\n", item)
		return false
	})

	fmt.Printf("\n\n tree after deleting everything with "+
		"endx <=2, is size %v; should be size 3\n",
		tree.Len())
	tree.AscendGreaterOrEqual(&job{endx: 0}, func(item btree.Item) bool {

		fmt.Printf("%#v\n", item)
		return true
	})

}

here's what I get. This strange result presents in the upstream petar/gollrb as well.

                                                                                                  
go run ex1.go                                                                                      
len = 9                                                                                            
delete pass deletes &main.job{endx:1, user:"", jobid:"abc"}                                        
delete pass deletes &main.job{endx:1, user:"", jobid:"hij"}                                        
delete pass deletes &main.job{endx:2, user:"", jobid:"abc"}                                        
delete pass ignores &main.job{endx:3, user:"", jobid:"abc"}                                        
                                                                                                   
                                                                                                   
 tree after deleting everything with endx <=2, is size 6; should be size 3                         
&main.job{endx:1, user:"", jobid:"def"}                                                            
&main.job{endx:2, user:"", jobid:"def"}                                                            
&main.job{endx:2, user:"", jobid:"hij"}                                                            
&main.job{endx:3, user:"", jobid:"abc"}                                                            
&main.job{endx:3, user:"", jobid:"def"}                                                            
&main.job{endx:3, user:"", jobid:"hij"}                                                            

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions