Skip to content

Commit

Permalink
API change for Union()
Browse files Browse the repository at this point in the history
  • Loading branch information
gaissmai committed Jan 9, 2024
1 parent d87cc0c commit 7772023
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 83 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## !!! ATTENTION, API HAS CHANGED

The API has changed from v2.0.0 to v0.3.0.
The API has changed from v0.3.0 to v0.4.0.

## Overview

Expand All @@ -33,11 +33,11 @@ but explicit for CIDRs. It has a narrow focus with a specialized API for IP rout

func (t *Table) Insert(pfx netip.Prefix, val any)
func (t *Table) Delete(pfx netip.Prefix) bool
func (t *Table) Union(other *Table)
func (t *Table) Union(other Table)

func (t Table) InsertImmutable(pfx netip.Prefix, val any) *Table
func (t Table) DeleteImmutable(pfx netip.Prefix) (*Table, bool)
func (t Table) UnionImmutable(other *Table) *Table
func (t Table) UnionImmutable(other Table) *Table
func (t Table) Clone() *Table

func (t Table) String() string
Expand Down
88 changes: 15 additions & 73 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ import (
)

var intMap = map[int]string{
1: "1",
10: "10",
100: "100",
1_000: "1_000",
10_000: "10_000",
100_000: "100_000",
1_000_000: "1_000_000",
1: "1",
10: "10",
100: "100",
1_000: "1_000",
10_000: "10_000",
100_000: "100_000",
}

func BenchmarkLookup(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
for k := 1; k <= 100_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
Expand All @@ -45,7 +44,7 @@ func BenchmarkLookup(b *testing.B) {
}

func BenchmarkLookupPrefix(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
for k := 1; k <= 100_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
Expand All @@ -63,23 +62,8 @@ func BenchmarkLookupPrefix(b *testing.B) {
}
}

func BenchmarkInsertImmutable(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
cidrs := shuffleFullTable(k)
name := fmt.Sprintf("%10s", intMap[k])
b.Run(name, func(b *testing.B) {
for n := 0; n < b.N; n++ {
rt := new(cidrtree.Table)
for i := range cidrs {
rt = rt.InsertImmutable(cidrs[i], nil)
}
}
})
}
}

func BenchmarkClone(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
for k := 1; k <= 100_000; k *= 10 {
rt := new(cidrtree.Table)
for _, cidr := range shuffleFullTable(k) {
rt.Insert(cidr, nil)
Expand All @@ -95,25 +79,26 @@ func BenchmarkClone(b *testing.B) {
}

func BenchmarkInsert(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
for k := 1; k <= 100_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
rt.Insert(cidr, 0)
rt.Insert(cidr, nil)
}
probe := routes[mrand.Intn(len(routes))]
cidr := routes[mrand.Intn(len(routes))].cidr
name := fmt.Sprintf("Into%10s", intMap[k])

b.ResetTimer()
b.Run(name, func(b *testing.B) {
for n := 0; n < b.N; n++ {
rt.Insert(probe.cidr, 0)
rt.Insert(cidr, nil)
}
})
}
}

func BenchmarkDelete(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
for k := 1; k <= 100_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
Expand All @@ -131,49 +116,6 @@ func BenchmarkDelete(b *testing.B) {
}
}

func BenchmarkDeleteImmutable(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
rt.Insert(cidr, nil)
}
probe := routes[mrand.Intn(len(routes))]
name := fmt.Sprintf("From%10s", intMap[k])

b.ResetTimer()
b.Run(name, func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, _ = rt.DeleteImmutable(probe.cidr)
}
})
}
}

func BenchmarkWalk(b *testing.B) {
for k := 1; k <= 1_000_000; k *= 10 {
rt := new(cidrtree.Table)
cidrs := shuffleFullTable(k)
for _, cidr := range cidrs {
rt.Insert(cidr, nil)
}
name := fmt.Sprintf("Walk%10s", intMap[k])

c := 0
cb := func(netip.Prefix, any) bool {
c++
return true
}

b.ResetTimer()
b.Run(name, func(b *testing.B) {
for n := 0; n < b.N; n++ {
rt.Walk(cb)
}
})
}
}

// #####################################################
// helpers
// #####################################################
Expand Down
4 changes: 2 additions & 2 deletions treap.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ func (t *Table) Delete(pfx netip.Prefix) bool {

// UnionImmutable combines any two tables immutable and returns the combined table.
// If there are duplicate entries, the value is taken from the other table.
func (t Table) UnionImmutable(other *Table) *Table {
func (t Table) UnionImmutable(other Table) *Table {
t.root4 = t.root4.union(other.root4, true, true)
t.root6 = t.root6.union(other.root6, true, true)
return &t
}

// Union combines two tables, changing the receiver table.
// If there are duplicate entries, the value is taken from the other table.
func (t *Table) Union(other *Table) {
func (t *Table) Union(other Table) {
t.root4 = t.root4.union(other.root4, true, false)
t.root6 = t.root6.union(other.root6, true, false)
}
Expand Down
10 changes: 5 additions & 5 deletions treap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func TestZeroValue(t *testing.T) {
t.Errorf("LookupCIDR(), got: %v, want: false", ok)
}

if rtbl := zeroTable.UnionImmutable(&zeroTable); *rtbl != zeroTable {
if rtbl := zeroTable.UnionImmutable(zeroTable); *rtbl != zeroTable {
t.Errorf("Union(), got: %#v, want: %#v", rtbl, &zeroTable)
}
}
Expand Down Expand Up @@ -533,18 +533,18 @@ func TestUnion(t *testing.T) {
rtbl2.Insert(route.cidr, route.nextHop)
}

rtbl.Union(rtbl2)
rtbl.Union(*rtbl2)
if rtbl.String() != asTopoStr {
t.Errorf("Fprint()\nwant:\n%sgot:\n%s", asTopoStr, rtbl.String())
}

clone := rtbl.Clone()
rtbl.Union(new(cidrtree.Table))
rtbl.Union(cidrtree.Table{})
if !reflect.DeepEqual(rtbl, clone) {
t.Fatal("UnionMutable with zero value changed original")
}

rtbl3 := rtbl.UnionImmutable(rtbl2)
rtbl3 := rtbl.UnionImmutable(*rtbl2)
if rtbl3.String() != asTopoStr {
t.Errorf("Fprint()\nwant:\n%sgot:\n%s", asTopoStr, rtbl.String())
}
Expand All @@ -561,7 +561,7 @@ func TestUnionDupe(t *testing.T) {
}
// both tables have identical CIDRs but with different values
// overwrite all values with value=2
rtbl1.Union(rtbl2)
rtbl1.Union(*rtbl2)

var wrongValue bool

Expand Down

0 comments on commit 7772023

Please sign in to comment.