Skip to content

Commit

Permalink
Add DB cache
Browse files Browse the repository at this point in the history
  • Loading branch information
minkezhang committed Jan 17, 2023
1 parent 8af7c1e commit 956e82a
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 16 deletions.
71 changes: 62 additions & 9 deletions boids/boids.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package boids

import (
"fmt"
"math"
"sync"
"time"

Expand All @@ -14,13 +15,24 @@ import (
"github.com/downflux/go-boids/constraint/utils"
"github.com/downflux/go-database/agent"
"github.com/downflux/go-database/database"
"github.com/downflux/go-database/database/cache"
"github.com/downflux/go-database/feature"
"github.com/downflux/go-geometry/2d/vector"
"github.com/downflux/go-geometry/nd/hyperrectangle"

vnd "github.com/downflux/go-geometry/nd/vector"
)

var (
DefaultO = O{
PoolSize: 24,

// Optionally instruct the simulation to do a single BroadPhase
// query per tick. This query will use the largest radius
// available. This is used when the simulation is expected to
// incur a large BVH query penalty.
EnableCache: false,

AvoidanceWeight: 5,
AvoidanceHorizon: 1.5,

Expand All @@ -46,7 +58,8 @@ var (
)

type O struct {
PoolSize int
PoolSize int
EnableCache bool

AvoidanceWeight float64
AvoidanceHorizon float64
Expand All @@ -63,8 +76,9 @@ type O struct {
}

type B struct {
db *database.DB
poolSize int
db *database.DB
poolSize int
enableCache bool

avoidanceWeight float64
avoidanceHorizon float64
Expand All @@ -85,8 +99,9 @@ func New(db *database.DB, o O) *B {
}

return &B{
db: db,
poolSize: o.PoolSize,
db: db,
poolSize: o.PoolSize,
enableCache: o.EnableCache,

avoidanceWeight: o.AvoidanceWeight,
avoidanceHorizon: o.AvoidanceHorizon,
Expand All @@ -102,6 +117,32 @@ func New(db *database.DB, o O) *B {
}
}

func (b *B) cache(a agent.RO, rs ...float64) database.RO {
r := math.Inf(-1)
for _, x := range rs {
if x > r {
r = x
}
}

p := a.Position()
aabb := hyperrectangle.New(
vnd.V{
p.X() - r,
p.Y() - r,
},
vnd.V{
p.X() + r,
p.Y() + r,
},
)

return cache.New(cache.O{
Agents: b.db.QueryAgents(*aabb, func(a agent.RO) bool { return true }),
Features: b.db.QueryFeatures(*aabb, func(f feature.RO) bool { return true }),
})
}

func (b *B) generate() []result {
agents := b.db.ListAgents()
ch := make(chan result, 1024)
Expand All @@ -119,18 +160,30 @@ func (b *B) generate() []result {
separationR := b.separationHorizon * a.Radius()
cohesionR := b.cohesionHorizon * a.Radius()

var c database.RO = b.db
if b.enableCache {
c = b.cache(
a,
arrivalR,
alignmentR,
avoidanceR,
separationR,
cohesionR,
)
}

// First term in this clamped velocity allows collision
// avoidance to take precedent.
collision := utils.Scale(b.avoidanceWeight, avoidance.Avoid(b.db, avoidanceR))
collision := utils.Scale(b.avoidanceWeight, avoidance.Avoid(c, avoidanceR))

// Second term in this clamped velocity allows contribution from
// all sources.
weighted := []constraint.Steer{
utils.Scale(b.seekWeight, seek.SLSDO(a.TargetPosition())),
utils.Scale(b.arrivalWeight, arrival.SLSDO(a.TargetPosition(), arrivalR)),
utils.Scale(b.alignmentWeight, alignment.Align(b.db, alignmentR)),
utils.Scale(b.separationWeight, separation.Separation(b.db, separationR)),
utils.Scale(-b.cohesionWeight, separation.Separation(b.db, cohesionR)),
utils.Scale(b.alignmentWeight, alignment.Align(c, alignmentR)),
utils.Scale(b.separationWeight, separation.Separation(c, separationR)),
utils.Scale(-b.cohesionWeight, separation.Separation(c, cohesionR)),
}

ch <- result{
Expand Down
25 changes: 18 additions & 7 deletions boids/boids_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,25 @@ func rv(min, max float64) vector.V {

func BenchmarkTick(b *testing.B) {
type config struct {
name string
n int
coverage float64
name string
n int
coverage float64
enableCache bool
}

configs := []config{}
for _, n := range []int{1e3, 1e4, 1e5} {
for _, coverage := range []float64{0.01, 0.05, 0.1} {
configs = append(configs, config{
name: fmt.Sprintf("N=%v/ρ=%v", n, coverage),
n: n,
coverage: coverage,
name: fmt.Sprintf("N=%v/ρ=%v/Cached=%v", n, coverage, true),
n: n,
coverage: coverage,
enableCache: true,
}, config{
name: fmt.Sprintf("N=%v/ρ=%v/Cached=%v", n, coverage, false),
n: n,
coverage: coverage,
enableCache: false,
})
}
}
Expand All @@ -54,7 +61,11 @@ func BenchmarkTick(b *testing.B) {
max := math.Sqrt(area)

db := database.New(database.DefaultO)
boids := New(db, DefaultO)
opts := DefaultO
if c.enableCache {
opts.EnableCache = true
}
boids := New(db, opts)
for i := 0; i < c.n; i++ {
db.InsertAgent(agent.O{
Radius: R,
Expand Down

0 comments on commit 956e82a

Please sign in to comment.