Skip to content

Instantly share code, notes, and snippets.

@alphazero
Created October 12, 2012 21:32
Show Gist options
  • Save alphazero/3881643 to your computer and use it in GitHub Desktop.
Save alphazero/3881643 to your computer and use it in GitHub Desktop.
explicit selection semantics - priority selector
package main
import (
"fmt"
"math/rand"
"time"
)
const clen = 3 // knob - needs to match parr below
// doesn't work in playground
func main() {
var counter = make([]int, clen)
var carr = make([]chan interface{}, clen)
// (clen) senders each in a tight send loop
send := func(out chan interface{}, idx int) {
for {
out <- idx
}
close(out)
}
// build the selector
// can have arbitrary priorities i.e. {10, 5, 1, 1, 1, 1}
parr := []int{80, 10, 10}
priority_select := selector(parr)
// reciever
receive := func() {
for {
_, v := priority_select(carr) // blocking
counter[v.(int)] += 1
}
}
go receive()
// start the clen senders
for i := 0; i < clen; i++ {
ch := make(chan interface{})
carr[i] = ch
go send(carr[i], i)
}
// wait a bit ..
<-time.NewTimer(time.Second * 1).C
debug(counter)
}
func selector(parr []int) func([]chan interface{}) (n int, v interface{}) {
prioritymap := make([]int, len(parr))
for i, p := range parr {
prioritymap[i] = p
if i > 0 {
prioritymap[i] += prioritymap[i-1]
}
}
rand_fn := func() int {
n := rand.Int() % prioritymap[len(prioritymap)-1]
for i, p := range prioritymap {
if n < p {
return i
}
}
panic(fmt.Errorf("\nparr:%s\nn:%d\nprioritymap:%d\n", parr, n, prioritymap))
}
ticker := time.NewTicker(time.Nanosecond)
select_fn := func(carr []chan interface{}) (int, interface{}) {
for {
n := rand_fn()
select {
case v := <-carr[n]:
return n, v
case <-ticker.C:
}
}
panic("bug * unreachable")
}
return select_fn
}
func debug(counter []int) {
sum := 0
for _, n := range counter {
sum += n
}
p := make([]int, clen)
for i, n := range counter {
p[i] = (n * 100) / sum
fmt.Printf("[%02d]: %09d %3d\n", i, n, p[i])
}
fmt.Println()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment