From f14d65d21b2583798feca40b7075c5a2419f72f5 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 16 Sep 2008 11:00:11 -0700 Subject: replace 235 with sieve - less problematic add programs, not yet described, to demonstrate servers. R=gri DELTA=279 (177 added, 16 deleted, 86 changed) OCL=15380 CL=15389 --- doc/progs/cat_rot13.go | 5 ++--- doc/progs/server.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ doc/progs/server1.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/progs/sieve.go | 36 +++++++++++++++++++++++++++++++++ doc/progs/sieve1.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 doc/progs/server.go create mode 100644 doc/progs/server1.go create mode 100644 doc/progs/sieve.go create mode 100644 doc/progs/sieve1.go (limited to 'doc/progs') diff --git a/doc/progs/cat_rot13.go b/doc/progs/cat_rot13.go index d5050155d..a8c570add 100644 --- a/doc/progs/cat_rot13.go +++ b/doc/progs/cat_rot13.go @@ -11,15 +11,14 @@ import ( var rot13_flag = Flag.Bool("rot13", false, nil, "rot13 the input") -func rot13(bb byte) byte { - var b int = int(bb) /// BUG: until byte division is fixed +func rot13(b byte) byte { if 'a' <= b && b <= 'z' { b = 'a' + ((b - 'a') + 13) % 26; } if 'A' <= b && b <= 'Z' { b = 'A' + ((b - 'A') + 13) % 26 } - return byte(b) + return b } type Reader interface { diff --git a/doc/progs/server.go b/doc/progs/server.go new file mode 100644 index 000000000..3f64e9df0 --- /dev/null +++ b/doc/progs/server.go @@ -0,0 +1,49 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +type BinOp (a, b int) int; + +type Request struct { + a, b int; + replyc *chan int; +} + +func Run(op *BinOp, request *Request) { + result := op(request.a, request.b); + request.replyc -< result; +} + +func Server(op *BinOp, service *chan *Request) { + for { + request := <-service; + go Run(op, request); // don't wait for it + } +} + +func StartServer(op *BinOp) *chan *Request { + req := new(chan *Request); + go Server(op, req); + return req; +} + +func main() { + adder := StartServer(func(a, b int) int { return a + b }); + const N = 100; + var reqs [N]Request; + for i := 0; i < N; i++ { + req := &reqs[i]; + req.a = i; + req.b = i + N; + req.replyc = new(chan int); + adder -< req; + } + for i := N-1; i >= 0; i-- { // doesn't matter what order + if <-reqs[i].replyc != N + 2*i { + print("fail at ", i, "\n"); + } + } + print("done\n"); +} diff --git a/doc/progs/server1.go b/doc/progs/server1.go new file mode 100644 index 000000000..5d24d8a4a --- /dev/null +++ b/doc/progs/server1.go @@ -0,0 +1,55 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +type BinOp (a, b int) int; + +type Request struct { + a, b int; + replyc *chan int; +} + +func Run(op *BinOp, request *Request) { + result := op(request.a, request.b); + request.replyc -< result; +} + +func Server(op *BinOp, service *chan *Request, quit *chan bool) { + for { + var request *Request; + select { + case request <- service: // can't say request := <-service here yet + go Run(op, request); // don't wait for it + case <-quit: + return; + } + } +} + +func StartServer(op *BinOp) (servch *chan *Request, quitch *chan bool) { + service := new(chan *Request); + quit := new(chan bool); + go Server(op, service, quit); + return service, quit; +} + +func main() { + adder, quit := StartServer(func(a, b int) int { return a + b }); + const N = 100; + var reqs [N]Request; + for i := 0; i < N; i++ { + req := &reqs[i]; + req.a = i; + req.b = i + N; + req.replyc = new(chan int); + adder -< req; + } + for i := N-1; i >= 0; i-- { // doesn't matter what order + if <-reqs[i].replyc != N + 2*i { + print("fail at ", i, "\n"); + } + } + quit -< true; +} diff --git a/doc/progs/sieve.go b/doc/progs/sieve.go new file mode 100644 index 000000000..60760cf4e --- /dev/null +++ b/doc/progs/sieve.go @@ -0,0 +1,36 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Send the sequence 2, 3, 4, ... to channel 'ch'. +func Generate(ch *chan int) { + for i := 2; ; i++ { + ch -< i // Send 'i' to channel 'ch'. + } +} + +// Copy the values from channel 'in' to channel 'out', +// removing those divisible by 'prime'. +func Filter(in *chan int, out *chan int, prime int) { + for { + i := <-in // Receive value of new variable 'i' from 'in'. + if i % prime != 0 { + out -< i // Send 'i' to channel 'out'. + } + } +} + +// The prime sieve: Daisy-chain Filter processes together. +func main() { + ch := new(chan int); // Create a new channel. + go Generate(ch); // Start Generate() as a goroutine. + for { + prime := <-ch; + print(prime, "\n"); + ch1 := new(chan int); + go Filter(ch, ch1, prime); + ch = ch1 + } +} diff --git a/doc/progs/sieve1.go b/doc/progs/sieve1.go new file mode 100644 index 000000000..2cb90600b --- /dev/null +++ b/doc/progs/sieve1.go @@ -0,0 +1,49 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Send the sequence 2, 3, 4, ... to returned channel +func Generate() *chan int { + ch := new(chan int); + go func(ch *chan int){ + for i := 2; ; i++ { + ch -< i + } + }(ch); + return ch; +} + +// Filter out input values divisible by 'prime', send rest to returned channel +func Filter(in *chan int, prime int) *chan int{ + out := new(chan int); + go func(in *chan int, out *chan int, prime int) { + for { + if i := <-in; i % prime != 0 { + out -< i + } + } + }(in, out, prime); + return out; +} + +func Sieve() *chan int { + out := new(chan int); + go func(out *chan int) { + ch := Generate(); + for { + prime := <-ch; + out -< prime; + ch = Filter(ch, prime); + } + }(out); + return out; +} + +func main() { + primes := Sieve(); + for { + print(<-primes, "\n"); + } +} -- cgit v1.2.3