context: reduce memory usage of context tree

Modifies context package to use map[]struct{} rather than map[]bool,
since the map is intended as a set object.  Also adds Benchmarks to
the context package switching between different types of root nodes
and a tree with different depths.

Included below are bytes deltas between the old and new code, using
these benchmarks.

benchmark                                                       old bytes     new bytes     delta
BenchmarkContextCancelTree/depth=1/Root=Background-8            176           176           +0.00%
BenchmarkContextCancelTree/depth=1/Root=OpenCanceler-8          560           544           -2.86%
BenchmarkContextCancelTree/depth=1/Root=ClosedCanceler-8        352           352           +0.00%
BenchmarkContextCancelTree/depth=10/Root=Background-8           3632          3488          -3.96%
BenchmarkContextCancelTree/depth=10/Root=OpenCanceler-8         4016          3856          -3.98%
BenchmarkContextCancelTree/depth=10/Root=ClosedCanceler-8       1936          1936          +0.00%
BenchmarkContextCancelTree/depth=100/Root=Background-8          38192         36608         -4.15%
BenchmarkContextCancelTree/depth=100/Root=OpenCanceler-8        38576         36976         -4.15%
BenchmarkContextCancelTree/depth=100/Root=ClosedCanceler-8      17776         17776         +0.00%
BenchmarkContextCancelTree/depth=1000/Root=Background-8         383792        367808        -4.16%
BenchmarkContextCancelTree/depth=1000/Root=OpenCanceler-8       384176        368176        -4.16%
BenchmarkContextCancelTree/depth=1000/Root=ClosedCanceler-8     176176        176176        +0.00%

Change-Id: I699ad704d9f7b461214e1651d24941927315b525
Reviewed-on: https://go-review.googlesource.com/25270
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/context/context.go b/src/context/context.go
index e40b63e..3afa3e9 100644
--- a/src/context/context.go
+++ b/src/context/context.go
@@ -252,9 +252,9 @@
 			child.cancel(false, p.err)
 		} else {
 			if p.children == nil {
-				p.children = make(map[canceler]bool)
+				p.children = make(map[canceler]struct{})
 			}
-			p.children[child] = true
+			p.children[child] = struct{}{}
 		}
 		p.mu.Unlock()
 	} else {
@@ -314,8 +314,8 @@
 	done chan struct{} // closed by the first cancel call.
 
 	mu       sync.Mutex
-	children map[canceler]bool // set to nil by the first cancel call
-	err      error             // set to non-nil by the first cancel call
+	children map[canceler]struct{} // set to nil by the first cancel call
+	err      error                 // set to non-nil by the first cancel call
 }
 
 func (c *cancelCtx) Done() <-chan struct{} {