From fd01d3cc6c92f87d1018b0b54f8b49aade3224fa Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 14 Jul 2016 21:54:23 -0700 Subject: [PATCH] Fix race in patricia tree This commit fixes a major issue added in 703b087a. There are still wins on allocation though. benchmark old ns/op new ns/op delta BenchmarkCMuxConnHTTP1-4 783 836 +6.77% BenchmarkCMuxConnHTTP2-4 895 806 -9.94% BenchmarkCMuxConnHTTP1n2-4 1000 1026 +2.60% BenchmarkCMuxConnHTTP2n1-4 916 961 +4.91% benchmark old allocs new allocs delta BenchmarkCMuxConnHTTP1-4 3 4 +33.33% BenchmarkCMuxConnHTTP2-4 4 4 +0.00% BenchmarkCMuxConnHTTP1n2-4 4 5 +25.00% BenchmarkCMuxConnHTTP2n1-4 4 5 +25.00% benchmark old bytes new bytes delta BenchmarkCMuxConnHTTP1-4 272 280 +2.94% BenchmarkCMuxConnHTTP2-4 304 304 +0.00% BenchmarkCMuxConnHTTP1n2-4 304 312 +2.63% BenchmarkCMuxConnHTTP2n1-4 304 312 +2.63% --- patricia.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/patricia.go b/patricia.go index 0099e38..a38cae0 100644 --- a/patricia.go +++ b/patricia.go @@ -22,8 +22,8 @@ import ( // patriciaTree is a simple patricia tree that handles []byte instead of string // and cannot be changed after instantiation. type patriciaTree struct { - root *ptNode - buf []byte // preallocated buffer to read data while matching + root *ptNode + maxDepth int // max depth of the tree. } func newPatriciaTree(bs ...[]byte) *patriciaTree { @@ -34,8 +34,8 @@ func newPatriciaTree(bs ...[]byte) *patriciaTree { } } return &patriciaTree{ - root: newNode(bs), - buf: make([]byte, max+1), + root: newNode(bs), + maxDepth: max + 1, } } @@ -48,13 +48,15 @@ func newPatriciaTreeString(strs ...string) *patriciaTree { } func (t *patriciaTree) matchPrefix(r io.Reader) bool { - n, _ := io.ReadFull(r, t.buf) - return t.root.match(t.buf[:n], true) + buf := make([]byte, t.maxDepth) + n, _ := io.ReadFull(r, buf) + return t.root.match(buf[:n], true) } func (t *patriciaTree) match(r io.Reader) bool { - n, _ := io.ReadFull(r, t.buf) - return t.root.match(t.buf[:n], false) + buf := make([]byte, t.maxDepth) + n, _ := io.ReadFull(r, buf) + return t.root.match(buf[:n], false) } type ptNode struct {