Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sync@v0.0.0-20200625203802-6e8e738ad208 / semaphore / semaphore_example_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/sync@v0.0.0-20200625203802-6e8e738ad208/semaphore/semaphore_example_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/sync@v0.0.0-20200625203802-6e8e738ad208/semaphore/semaphore_example_test.go
new file mode 100644 (file)
index 0000000..e75cd79
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright 2017 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 semaphore_test
+
+import (
+       "context"
+       "fmt"
+       "log"
+       "runtime"
+
+       "golang.org/x/sync/semaphore"
+)
+
+// Example_workerPool demonstrates how to use a semaphore to limit the number of
+// goroutines working on parallel tasks.
+//
+// This use of a semaphore mimics a typical “worker pool” pattern, but without
+// the need to explicitly shut down idle workers when the work is done.
+func Example_workerPool() {
+       ctx := context.TODO()
+
+       var (
+               maxWorkers = runtime.GOMAXPROCS(0)
+               sem        = semaphore.NewWeighted(int64(maxWorkers))
+               out        = make([]int, 32)
+       )
+
+       // Compute the output using up to maxWorkers goroutines at a time.
+       for i := range out {
+               // When maxWorkers goroutines are in flight, Acquire blocks until one of the
+               // workers finishes.
+               if err := sem.Acquire(ctx, 1); err != nil {
+                       log.Printf("Failed to acquire semaphore: %v", err)
+                       break
+               }
+
+               go func(i int) {
+                       defer sem.Release(1)
+                       out[i] = collatzSteps(i + 1)
+               }(i)
+       }
+
+       // Acquire all of the tokens to wait for any remaining workers to finish.
+       //
+       // If you are already waiting for the workers by some other means (such as an
+       // errgroup.Group), you can omit this final Acquire call.
+       if err := sem.Acquire(ctx, int64(maxWorkers)); err != nil {
+               log.Printf("Failed to acquire semaphore: %v", err)
+       }
+
+       fmt.Println(out)
+
+       // Output:
+       // [0 1 7 2 5 8 16 3 19 6 14 9 9 17 17 4 12 20 20 7 7 15 15 10 23 10 111 18 18 18 106 5]
+}
+
+// collatzSteps computes the number of steps to reach 1 under the Collatz
+// conjecture. (See https://en.wikipedia.org/wiki/Collatz_conjecture.)
+func collatzSteps(n int) (steps int) {
+       if n <= 0 {
+               panic("nonpositive input")
+       }
+
+       for ; n > 1; steps++ {
+               if steps < 0 {
+                       panic("too many steps")
+               }
+
+               if n%2 == 0 {
+                       n /= 2
+                       continue
+               }
+
+               const maxInt = int(^uint(0) >> 1)
+               if n > (maxInt-1)/3 {
+                       panic("overflow")
+               }
+               n = 3*n + 1
+       }
+
+       return steps
+}