diff --git a/common/image.go b/common/image.go index 86e57a6..e9e2c7a 100644 --- a/common/image.go +++ b/common/image.go @@ -16,22 +16,22 @@ import ( "time" ) -var rand uint32 -var randmu sync.Mutex +var rrand uint32 +var rrandmu sync.Mutex func reseed() uint32 { return uint32(time.Now().UnixNano() + int64(os.Getpid())) } func nextSuffix() string { - randmu.Lock() - r := rand + rrandmu.Lock() + r := rrand if r == 0 { r = reseed() } r = r*1664525 + 1013904223 // constants from Numerical Recipes - rand = r - randmu.Unlock() + rrand = r + rrandmu.Unlock() return strconv.Itoa(int(1e9 + r%1e9))[1:] } @@ -60,7 +60,7 @@ func tmpName(tmpl string) (string, error) { } if nconflict++; nconflict > 10 { nconflict = 0 - rand = reseed() + rrand = reseed() } } return "", errors.New("Cannot create temp name") diff --git a/common/spans.go b/common/spans.go index b192de2..265d2ab 100644 --- a/common/spans.go +++ b/common/spans.go @@ -4,6 +4,11 @@ package common +import ( + "bytes" + "fmt" +) + const chunkSize = 1024 type Span struct { @@ -184,3 +189,31 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { return head } + +func (s *Span) Visit(v func(*Span)) { + for ; s != nil; s = s.Next { + v(s) + } +} + +func (s *Span) Len() int { + n := 0 + for ; s != nil; s = s.Next { + n++ + } + return n +} + +func (s *Span) String() string { + var buf bytes.Buffer + first := true + s.Visit(func(s1 *Span) { + if !first { + buf.WriteString(", ") + } else { + first = false + } + buf.WriteString(fmt.Sprintf("(%d, %d)", s1.From, s1.To)) + }) + return buf.String() +} diff --git a/common/spans_test.go b/common/spans_test.go new file mode 100644 index 0000000..0144ccf --- /dev/null +++ b/common/spans_test.go @@ -0,0 +1,36 @@ +// Copyright 2014 by Sascha L. Teichmann +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +package common + +import ( + "math/rand" + "testing" +) + +func TestSpans(t *testing.T) { + + inp := make([]int32, 3000) + for i, n := 0, len(inp); i < n; i++ { + inp[i] = int32(i) + } + for i, n := 0, len(inp); i < n; i++ { + i1 := rand.Int31n(int32(n)) + i2 := rand.Int31n(int32(n)) + inp[i1], inp[i2] = inp[i2], inp[i1] + } + + sp := NewSpanPool() + var s *Span + for i, n := 0, len(inp); i < n; i++ { + s = sp.Insert(s, inp[i], 42) + } + + if n := s.Len(); n != 1 { + t.Errorf("Span length %d expected 1\n", n) + t.Errorf("spans: %s\n", s) + } + + sp.FreeAll(s) +}