Basically, you define a type that you want to store as an interval and
provide the necessary methods for that type to satisfy the
interval.IntInterface[1] (if using integral position data since the
general interval.Interface is much slower).
Since Get and the other methods on the Tree types return interface
values, you need to assert to the concrete type. This part is what you
were not doing.
So for example:
// Integer-specific intervals
type IntInterval struct {
Start, End int
UID uintptr
Name string
}
func (i IntInterval) Overlap(b interval.IntRange) bool {
// Half-open interval indexing.
return i.End > b.Start && i.Start < b.End
}
func (i IntInterval) ID() uintptr { return i.UID }
func (i IntInterval) Range() interval.IntRange { return
interval.IntRange{i.Start, i.End} }
func (i IntInterval) String() string { return fmt.Sprintf("[%
d,%d)#%d %q", i.Start, i.End, i.UID, i.Name) }
var intIvs = []IntInterval{
{Start: 0, End: 2, Name: "a"},
{Start: 2, End: 4, Name: "b"},
{Start: 1, End: 6, Name: "c"},
{Start: 3, End: 4, Name: "d"},
{Start: 1, End: 3, Name: "e"},
{Start: 4, End: 6, Name: "f"},
{Start: 5, End: 8, Name: "g"},
{Start: 6, End: 8, Name: "h"},
{Start: 5, End: 7, Name: "i"},
{Start: 8, End: 9, Name: "j"},
}
func Example_2() {
t := &interval.IntTree{}
for i, iv := range intIvs {
iv.UID = uintptr(i)
err := t.Insert(iv, false)
if err != nil {
fmt.Println(err)
}
}
fmt.Println("Integer-specific interval tree:")
matched := t.Get(IntInterval{Start: 3, End: 6})
fmt.Println(matched)
for _, i := range matched {
fmt.Println(i.(IntInterval).Name)
}
}
A much more detailed example is provided in the biogo.talks repo for
kdtree (different store, but the same general principle)[2]. The code in
biogo/align/pals/piler.go is also probably worth reading, since it does
all this with interval.IntInterface using a number of the idiomatic
approaches.
Dan
[1]
http://godoc.org/code.google.com/p/biogo.store/interval#IntInterface
[2]
http://go-talks.appspot.com/code.google.com/p/biogo.talks/illumination/illumina.article