<commit_before>/*
 * Copyright 2019 Dgraph Labs, Inc. and Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ristretto

import (
	"sync"
	"sync/atomic"
	"time"
)

const (
	ringLossy byte = iota
	ringLossless
)

// ringConsumer is the user-defined object responsible for receiving and
// processing items in batches when buffers are drained.
type ringConsumer interface {
	Push([]string)
}

// ringStripe is a singular ring buffer that is not concurrent safe.
type ringStripe struct {
	consumer ringConsumer
	data     []string
	head     int
	capacity int
	busy     int32
}

func newRingStripe(config *ringConfig) *ringStripe {
	return &ringStripe{
		consumer: config.Consumer,
		data:     make([]string, config.Capacity),
		capacity: int(config.Capacity),
	}
}

// Push appends an item in the ring buffer and drains (copies items and
// sends to Consumer) if full.
func (s *ringStripe) Push(item string) {
	s.data[s.head] = item
	s.head++
	// if we should drain
	if s.head >= s.capacity {
		// copy elements and send to consumer
		s.consumer.Push(append(s.data[:0:0], s.data...))
		s.head = 0
	}
}

// ringConfig is passed to newRingBuffer with parameters.
type ringConfig struct {
	Consumer ringConsumer
	Stripes  int64
	Capacity int64
}

// ringBuffer stores multiple buffers (stripes) and distributes Pushed items
// between them to lower contention.
//
// This implements the "batching" process described in the BP-Wrapper paper
// (section III part A).
type ringBuffer struct {
	stripes []*ringStripe
	pool    *sync.Pool
	push    func(*ringBuffer, string)
	rand    int
	mask    int
}

// newRingBuffer returns a striped ring buffer. The Type can be either LOSSY or
// LOSSLESS. LOSSY should provide better performance. The Consumer in ringConfig
// will be called when individual stripes are full and need to drain their
// elements.
func newRingBuffer(ringType byte, config *ringConfig) *ringBuffer {
	if ringType == ringLossy {
		// LOSSY buffers use a very simple sync.Pool for concurrently reusing
		// stripes. We do lose some stripes due to GC (unheld items in sync.Pool
		// are cleared), but the performance gains generally outweigh the small
		// percentage of elements lost. The performance primarily comes from
		// low-level runtime functions used in the standard library that aren't
		// available to us (such as runtime_procPin()).
		return &ringBuffer{
			pool: &sync.Pool{
				New: func() interface{} { return newRingStripe(config) },
			},
			push: pushLossy,
		}
	}
	// begin LOSSLESS buffer handling
	//
	// unlike lossy, lossless manually handles all stripes
	stripes := make([]*ringStripe, config.Stripes)
	for i := range stripes {
		stripes[i] = newRingStripe(config)
	}
	return &ringBuffer{
		stripes: stripes,
		mask:    int(config.Stripes - 1),
		rand:    int(time.Now().UnixNano()), // random seed for picking stripes
		push:    pushLossless,
	}
}

// Push adds an element to one of the internal stripes and possibly drains if
// the stripe becomes full.
func (b *ringBuffer) Push(item string) { b.push(b, item) }

func pushLossy(b *ringBuffer, item string) {
	// reuse or create a new stripe
	stripe := b.pool.Get().(*ringStripe)
	stripe.Push(item)
	b.pool.Put(stripe)
}

func pushLossless(b *ringBuffer, item string) {
	// try to find an available stripe
	for i := 0; ; i = (i + 1) & b.mask {
		if atomic.CompareAndSwapInt32(&b.stripes[i].busy, 0, 1) {
			// try to get exclusive lock on the stripe
			b.stripes[i].Push(item)
			// unlock
			atomic.StoreInt32(&b.stripes[i].busy, 0)
			return
		}
	}
}
<commit_msg>Remove head from ringStripe. Instead just use slice better.<commit_after>/*
 * Copyright 2019 Dgraph Labs, Inc. and Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ristretto

import (
	"sync"
	"sync/atomic"
	"time"
)

const (
	ringLossy byte = iota
	ringLossless
)

// ringConsumer is the user-defined object responsible for receiving and
// processing items in batches when buffers are drained.
type ringConsumer interface {
	Push([]string)
}

// ringStripe is a singular ring buffer that is not concurrent safe.
type ringStripe struct {
	consumer ringConsumer
	data     []string
	capacity int
	busy     int32
}

func newRingStripe(config *ringConfig) *ringStripe {
	return &ringStripe{
		consumer: config.Consumer,
		data:     make([]string, 0, config.Capacity),
		capacity: int(config.Capacity),
	}
}

// Push appends an item in the ring buffer and drains (copies items and
// sends to Consumer) if full.
func (s *ringStripe) Push(item string) {
	s.data = append(s.data, item)
	// if we should drain
	if len(s.data) >= s.capacity {
		// copy elements and send to consumer
		s.consumer.Push(append(s.data[:0:0], s.data...))
		s.data = s.data[:0]
	}
}

// ringConfig is passed to newRingBuffer with parameters.
type ringConfig struct {
	Consumer ringConsumer
	Stripes  int64
	Capacity int64
}

// ringBuffer stores multiple buffers (stripes) and distributes Pushed items
// between them to lower contention.
//
// This implements the "batching" process described in the BP-Wrapper paper
// (section III part A).
type ringBuffer struct {
	stripes []*ringStripe
	pool    *sync.Pool
	push    func(*ringBuffer, string)
	rand    int
	mask    int
}

// newRingBuffer returns a striped ring buffer. The Type can be either LOSSY or
// LOSSLESS. LOSSY should provide better performance. The Consumer in ringConfig
// will be called when individual stripes are full and need to drain their
// elements.
func newRingBuffer(ringType byte, config *ringConfig) *ringBuffer {
	if ringType == ringLossy {
		// LOSSY buffers use a very simple sync.Pool for concurrently reusing
		// stripes. We do lose some stripes due to GC (unheld items in sync.Pool
		// are cleared), but the performance gains generally outweigh the small
		// percentage of elements lost. The performance primarily comes from
		// low-level runtime functions used in the standard library that aren't
		// available to us (such as runtime_procPin()).
		return &ringBuffer{
			pool: &sync.Pool{
				New: func() interface{} { return newRingStripe(config) },
			},
			push: pushLossy,
		}
	}
	// begin LOSSLESS buffer handling
	//
	// unlike lossy, lossless manually handles all stripes
	stripes := make([]*ringStripe, config.Stripes)
	for i := range stripes {
		stripes[i] = newRingStripe(config)
	}
	return &ringBuffer{
		stripes: stripes,
		mask:    int(config.Stripes - 1),
		rand:    int(time.Now().UnixNano()), // random seed for picking stripes
		push:    pushLossless,
	}
}

// Push adds an element to one of the internal stripes and possibly drains if
// the stripe becomes full.
func (b *ringBuffer) Push(item string) { b.push(b, item) }

func pushLossy(b *ringBuffer, item string) {
	// reuse or create a new stripe
	stripe := b.pool.Get().(*ringStripe)
	stripe.Push(item)
	b.pool.Put(stripe)
}

func pushLossless(b *ringBuffer, item string) {
	// try to find an available stripe
	for i := 0; ; i = (i + 1) & b.mask {
		if atomic.CompareAndSwapInt32(&b.stripes[i].busy, 0, 1) {
			// try to get exclusive lock on the stripe
			b.stripes[i].Push(item)
			// unlock
			atomic.StoreInt32(&b.stripes[i].busy, 0)
			return
		}
	}
}
<|endoftext|>


<commit_before>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     September 05, 2019
;       related version of root zone:     2019090501
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     199.9.14.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<commit_msg>auto-update<commit_after>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     September 19, 2019
;       related version of root zone:     2019091901
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     199.9.14.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<|endoftext|>


<commit_before>package rope

import (
	"bytes"
	"fmt"
	"io"
)

const small = 128

// A rope is a heavy-weight string. They are useful for manipulating very
// long strings.
//
// Like Go strings, ropes are immutable sequences of bytes.
type Rope struct {
	root tree
}

// Make a new rope with contents s.
func New(s string) Rope {
	return Rope{leaf(s)}
}

// Concatenate zero or more ropes.
func Concat(rs ...Rope) Rope {
	switch n := len(rs); n {
	case 0:
		return Rope{leaf("")}
	case 1:
		return rs[0]
	default:
		n2 := n / 2
		r1, r2 := Concat(rs[:n2]...), Concat(rs[n2:]...)
		return Rope{r1.root.concat(r2.root)}
	}
}

// Returns the i'th byte in the rope.
func (r Rope) Index(i int) byte {
	return r.root.index(i)
}

// The length of the rope, in bytes.
func (r Rope) Len() int {
	return r.root.length()
}

// Slice of a rope. Equivalent to New(r.String())[i:j].
func (r Rope) Slice(i, j int) Rope {
	if i == j {
		return Rope{leaf("")}
	}
	return Rope{r.root.slice(i, j)}
}

// Returns the contents of r as a string.
func (r Rope) String() string {
	var buf bytes.Buffer
	r.WriteTo(&buf)
	return buf.String()
}

// Write the contents of r to w. Returns the number of bytes written and
// possibly an error.
func (r Rope) WriteTo(w io.Writer) (n int64, err error) {
	return r.root.writeTo(w)
}

type tree interface {
	concat(tree) tree
	index(int) byte
	length() int
	slice(int, int) tree
	writeTo(w io.Writer) (int64, error)
}

type leaf string

func (s leaf) concat(t tree) tree {
	if s2, ok := t.(leaf); ok && len(string(s))+len(string(s2)) <= small {
		return leaf(string(s) + string(s2))
	}
	return &node{s, t, len(string(s)) + t.length()}
}

func (s leaf) index(i int) byte {
	return string(s)[i]
}

func (s leaf) length() int {
	return len(string(s))
}

func (s leaf) slice(i, j int) tree {
	return leaf(string(s)[i:j])
}

func (s leaf) writeTo(w io.Writer) (int64, error) {
	n, err := io.WriteString(w, string(s))
	return int64(n), err
}

type node struct {
	left, right tree
	nbytes      int
}

func (n *node) concat(right tree) tree {
	var left tree
	s1, ok1 := n.right.(leaf)
	s2, ok2 := right.(leaf)
	if ok1 && ok2 && len(string(s1))+len(string(s2)) <= small {
		right = leaf(string(s1) + string(s2))
		left = n.left
	} else {
		left = n
	}
	return &node{left, right, left.length() + right.length()}
}

func (n *node) index(i int) byte {
	if i > n.nbytes {
		panic(fmt.Sprintf("%d out of bounds for length-%d rope", i, n.length))
	}
	leftlength := n.left.length()
	if i < leftlength {
		return n.left.index(i)
	}
	return n.right.index(i - leftlength)
}

func (n *node) length() int {
	return n.nbytes
}

func (n *node) slice(i, j int) tree {
	leftlen := n.left.length()
	switch {
	case j <= leftlen:
		return n.left.slice(i, j)
	case i >= leftlen:
		return n.right.slice(i-leftlen, j-leftlen)
	}

	var left, right tree
	if i == 0 {
		left = n.left
	} else {
		left = n.left.slice(i, leftlen)
	}
	if j == leftlen+n.right.length() {
		right = n.right
	} else {
		right = n.right.slice(0, j-leftlen)
	}
	return left.concat(right)
}

func (n *node) writeTo(w io.Writer) (nw int64, err error) {
	nw, err = n.left.writeTo(w)
	if err != nil {
		return
	}
	nright, err := n.right.writeTo(w)
	nw += nright
	return
}
<commit_msg>faster Concat<commit_after>package rope

import (
	"bytes"
	"fmt"
	"io"
)

const small = 128

// A rope is a heavy-weight string. They are useful for manipulating very
// long strings.
//
// Like Go strings, ropes are immutable sequences of bytes.
type Rope struct {
	root tree
}

// Make a new rope with contents s.
func New(s string) Rope {
	return Rope{leaf(s)}
}

// Concatenate zero or more ropes.
func Concat(ropes ...Rope) Rope {
	switch len(ropes) {
	case 0:
		return Rope{leaf("")}
	default:
		return Rope{concat(ropes)}
	}
}

func concat(ropes []Rope) tree {
	switch n := len(ropes); n {
	case 1:
		return ropes[0].root
	case 2:
		return ropes[0].root.concat(ropes[1].root)
	default:
		n2 := n / 2
		r1, r2 := concat(ropes[:n2]), concat(ropes[n2:])
		return r1.concat(r2)
	}
}

// Returns the i'th byte in the rope.
func (r Rope) Index(i int) byte {
	return r.root.index(i)
}

// The length of the rope, in bytes.
func (r Rope) Len() int {
	return r.root.length()
}

// Slice of a rope. Equivalent to New(r.String())[i:j].
func (r Rope) Slice(i, j int) Rope {
	if i == j {
		return Rope{leaf("")}
	}
	return Rope{r.root.slice(i, j)}
}

// Returns the contents of r as a string.
func (r Rope) String() string {
	var buf bytes.Buffer
	r.WriteTo(&buf)
	return buf.String()
}

// Write the contents of r to w. Returns the number of bytes written and
// possibly an error.
func (r Rope) WriteTo(w io.Writer) (n int64, err error) {
	return r.root.writeTo(w)
}

type tree interface {
	concat(tree) tree
	index(int) byte
	length() int
	slice(int, int) tree
	writeTo(w io.Writer) (int64, error)
}

type leaf string

func (s leaf) concat(t tree) tree {
	if s2, ok := t.(leaf); ok && len(string(s))+len(string(s2)) <= small {
		return leaf(string(s) + string(s2))
	}
	return &node{s, t, len(string(s)) + t.length()}
}

func (s leaf) index(i int) byte {
	return string(s)[i]
}

func (s leaf) length() int {
	return len(string(s))
}

func (s leaf) slice(i, j int) tree {
	return leaf(string(s)[i:j])
}

func (s leaf) writeTo(w io.Writer) (int64, error) {
	n, err := io.WriteString(w, string(s))
	return int64(n), err
}

type node struct {
	left, right tree
	nbytes      int
}

func (n *node) concat(right tree) tree {
	var left tree
	s1, ok1 := n.right.(leaf)
	s2, ok2 := right.(leaf)
	if ok1 && ok2 && len(string(s1))+len(string(s2)) <= small {
		right = leaf(string(s1) + string(s2))
		left = n.left
	} else {
		left = n
	}
	return &node{left, right, left.length() + right.length()}
}

func (n *node) index(i int) byte {
	if i > n.nbytes {
		panic(fmt.Sprintf("%d out of bounds for length-%d rope", i, n.length))
	}
	leftlength := n.left.length()
	if i < leftlength {
		return n.left.index(i)
	}
	return n.right.index(i - leftlength)
}

func (n *node) length() int {
	return n.nbytes
}

func (n *node) slice(i, j int) tree {
	leftlen := n.left.length()
	switch {
	case j <= leftlen:
		return n.left.slice(i, j)
	case i >= leftlen:
		return n.right.slice(i-leftlen, j-leftlen)
	}

	var left, right tree
	if i == 0 {
		left = n.left
	} else {
		left = n.left.slice(i, leftlen)
	}
	if j == leftlen+n.right.length() {
		right = n.right
	} else {
		right = n.right.slice(0, j-leftlen)
	}
	return left.concat(right)
}

func (n *node) writeTo(w io.Writer) (nw int64, err error) {
	nw, err = n.left.writeTo(w)
	if err != nil {
		return
	}
	nright, err := n.right.writeTo(w)
	nw += nright
	return
}
<|endoftext|>


<commit_before>// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

package mysql

import (
	"database/sql/driver"
	"io"
)

type mysqlField struct {
	name      string
	fieldType byte
	flags     fieldFlag
}

type mysqlRows struct {
	mc      *mysqlConn
	binary  bool
	columns []mysqlField
	eof     bool
}

func (rows *mysqlRows) Columns() []string {
	columns := make([]string, len(rows.columns))
	for i := range columns {
		columns[i] = rows.columns[i].name
	}
	return columns
}

func (rows *mysqlRows) Close() (err error) {
	// Remove unread packets from stream
	if !rows.eof {
		if rows.mc == nil || rows.mc.netConn == nil {
			return errInvalidConn
		}

		err = rows.mc.readUntilEOF()

		// explicitly set because readUntilEOF might return early in case of an
		// error
		rows.eof = true
	}

	rows.mc = nil

	return
}

func (rows *mysqlRows) Next(dest []driver.Value) (err error) {
	if rows.eof {
		return io.EOF
	}

	if rows.mc == nil || rows.mc.netConn == nil {
		return errInvalidConn
	}

	// Fetch next row from stream
	if rows.binary {
		err = rows.readBinaryRow(dest)
	} else {
		err = rows.readRow(dest)
	}

	if err == io.EOF {
		rows.eof = true
	}
	return err
}
<commit_msg>rows: reorder struct fields<commit_after>// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

package mysql

import (
	"database/sql/driver"
	"io"
)

type mysqlField struct {
	fieldType byte
	flags     fieldFlag
	name      string
}

type mysqlRows struct {
	mc      *mysqlConn
	columns []mysqlField
	binary  bool
	eof     bool
}

func (rows *mysqlRows) Columns() []string {
	columns := make([]string, len(rows.columns))
	for i := range columns {
		columns[i] = rows.columns[i].name
	}
	return columns
}

func (rows *mysqlRows) Close() (err error) {
	// Remove unread packets from stream
	if !rows.eof {
		if rows.mc == nil || rows.mc.netConn == nil {
			return errInvalidConn
		}

		err = rows.mc.readUntilEOF()

		// explicitly set because readUntilEOF might return early in case of an
		// error
		rows.eof = true
	}

	rows.mc = nil

	return
}

func (rows *mysqlRows) Next(dest []driver.Value) (err error) {
	if rows.eof {
		return io.EOF
	}

	if rows.mc == nil || rows.mc.netConn == nil {
		return errInvalidConn
	}

	// Fetch next row from stream
	if rows.binary {
		err = rows.readBinaryRow(dest)
	} else {
		err = rows.readRow(dest)
	}

	if err == io.EOF {
		rows.eof = true
	}
	return err
}
<|endoftext|>


<commit_before>// Copyright 2019 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/golang/glog"
	"github.com/google/go-licenses/licenses"
	"github.com/otiai10/copy"
	"github.com/spf13/cobra"
)

var (
	saveCmd = &cobra.Command{
		Use:   "save <package>",
		Short: "Saves licenses, copyright notices and source code, as required by a Go package's dependencies, to a directory.",
		Args:  cobra.MinimumNArgs(1),
		RunE:  saveMain,
	}

	noticeRegexp = regexp.MustCompile(`^NOTICE(\.(txt|md))?$`)

	// savePath is where the output of the command is written to.
	savePath string
	// overwriteSavePath controls behaviour when the directory indicated by savePath already exists.
	// If true, the directory will be replaced. If false, the command will fail.
	overwriteSavePath bool
)

func init() {
	saveCmd.Flags().StringVar(&savePath, "save_path", "", "Directory into which files should be saved that are required by license terms")
	if err := saveCmd.MarkFlagRequired("save_path"); err != nil {
		glog.Fatal(err)
	}
	if err := saveCmd.MarkFlagFilename("save_path"); err != nil {
		glog.Fatal(err)
	}

	saveCmd.Flags().BoolVar(&overwriteSavePath, "force", false, "Delete the destination directory if it already exists.")

	rootCmd.AddCommand(saveCmd)
}

func saveMain(_ *cobra.Command, args []string) error {

	classifier, err := licenses.NewClassifier(confidenceThreshold)
	if err != nil {
		return err
	}

	libs, err := licenses.Libraries(context.Background(), classifier, args...)
	if err != nil {
		return err
	}

	if overwriteSavePath {
		if err := os.RemoveAll(savePath); err != nil {
			return err
		}
	}

	// Check that the save path doesn't exist, otherwise it'd end up with a mix of
	// existing files and the output of this command.
	if d, err := os.Open(savePath); err == nil {
		d.Close()
		return fmt.Errorf("%s already exists", savePath)
	} else if !os.IsNotExist(err) {
		return err
	}

	libsWithBadLicenses := make(map[licenses.Type][]*licenses.Library)
	for _, lib := range libs {
		libSaveDir := filepath.Join(savePath, unvendor(lib.Name()))
		// Detect what type of license this library has and fulfill its requirements, e.g. copy license, copyright notice, source code, etc.
		_, licenseType, err := classifier.Identify(lib.LicensePath)
		if err != nil {
			return err
		}
		switch licenseType {
		case licenses.Restricted, licenses.Reciprocal:
			// Copy the entire source directory for the library.
			libDir := filepath.Dir(lib.LicensePath)
			if err := copySrc(libDir, libSaveDir); err != nil {
				return err
			}
		case licenses.Notice, licenses.Permissive, licenses.Unencumbered:
			// Just copy the license and copyright notice.
			if err := copyNotices(lib.LicensePath, libSaveDir); err != nil {
				return err
			}
		default:
			libsWithBadLicenses[licenseType] = append(libsWithBadLicenses[licenseType], lib)
		}
	}
	if len(libsWithBadLicenses) > 0 {
		return fmt.Errorf("one or more libraries have an incompatible/unknown license: %q", libsWithBadLicenses)
	}
	return nil
}

func copySrc(src, dest string) error {
	// Skip the .git directory for copying, if it exists, since we don't want to save the user's
	// local Git config along with the source code.
	opt := copy.Options{
		Skip: func(src string) (bool, error) {
			return strings.HasSuffix(src, ".git"), nil
		},
		AddPermission: 0600,
	}
	if err := copy.Copy(src, dest, opt); err != nil {
		return err
	}
	return nil
}

func copyNotices(licensePath, dest string) error {
	if err := copy.Copy(licensePath, filepath.Join(dest, filepath.Base(licensePath))); err != nil {
		return err
	}

	src := filepath.Dir(licensePath)
	files, err := ioutil.ReadDir(src)
	if err != nil {
		return err
	}
	for _, f := range files {
		if fName := f.Name(); !f.IsDir() && noticeRegexp.MatchString(fName) {
			if err := copy.Copy(filepath.Join(src, fName), filepath.Join(dest, fName)); err != nil {
				return err
			}
		}
	}
	return nil
}
<commit_msg>Remove savePath before looking for packages<commit_after>// Copyright 2019 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/golang/glog"
	"github.com/google/go-licenses/licenses"
	"github.com/otiai10/copy"
	"github.com/spf13/cobra"
)

var (
	saveCmd = &cobra.Command{
		Use:   "save <package>",
		Short: "Saves licenses, copyright notices and source code, as required by a Go package's dependencies, to a directory.",
		Args:  cobra.MinimumNArgs(1),
		RunE:  saveMain,
	}

	noticeRegexp = regexp.MustCompile(`^NOTICE(\.(txt|md))?$`)

	// savePath is where the output of the command is written to.
	savePath string
	// overwriteSavePath controls behaviour when the directory indicated by savePath already exists.
	// If true, the directory will be replaced. If false, the command will fail.
	overwriteSavePath bool
)

func init() {
	saveCmd.Flags().StringVar(&savePath, "save_path", "", "Directory into which files should be saved that are required by license terms")
	if err := saveCmd.MarkFlagRequired("save_path"); err != nil {
		glog.Fatal(err)
	}
	if err := saveCmd.MarkFlagFilename("save_path"); err != nil {
		glog.Fatal(err)
	}

	saveCmd.Flags().BoolVar(&overwriteSavePath, "force", false, "Delete the destination directory if it already exists.")

	rootCmd.AddCommand(saveCmd)
}

func saveMain(_ *cobra.Command, args []string) error {

	if overwriteSavePath {
		if err := os.RemoveAll(savePath); err != nil {
			return err
		}
	}

	classifier, err := licenses.NewClassifier(confidenceThreshold)
	if err != nil {
		return err
	}

	libs, err := licenses.Libraries(context.Background(), classifier, args...)
	if err != nil {
		return err
	}

	// Check that the save path doesn't exist, otherwise it'd end up with a mix of
	// existing files and the output of this command.
	if d, err := os.Open(savePath); err == nil {
		d.Close()
		return fmt.Errorf("%s already exists", savePath)
	} else if !os.IsNotExist(err) {
		return err
	}

	libsWithBadLicenses := make(map[licenses.Type][]*licenses.Library)
	for _, lib := range libs {
		libSaveDir := filepath.Join(savePath, unvendor(lib.Name()))
		// Detect what type of license this library has and fulfill its requirements, e.g. copy license, copyright notice, source code, etc.
		_, licenseType, err := classifier.Identify(lib.LicensePath)
		if err != nil {
			return err
		}
		switch licenseType {
		case licenses.Restricted, licenses.Reciprocal:
			// Copy the entire source directory for the library.
			libDir := filepath.Dir(lib.LicensePath)
			if err := copySrc(libDir, libSaveDir); err != nil {
				return err
			}
		case licenses.Notice, licenses.Permissive, licenses.Unencumbered:
			// Just copy the license and copyright notice.
			if err := copyNotices(lib.LicensePath, libSaveDir); err != nil {
				return err
			}
		default:
			libsWithBadLicenses[licenseType] = append(libsWithBadLicenses[licenseType], lib)
		}
	}
	if len(libsWithBadLicenses) > 0 {
		return fmt.Errorf("one or more libraries have an incompatible/unknown license: %q", libsWithBadLicenses)
	}
	return nil
}

func copySrc(src, dest string) error {
	// Skip the .git directory for copying, if it exists, since we don't want to save the user's
	// local Git config along with the source code.
	opt := copy.Options{
		Skip: func(src string) (bool, error) {
			return strings.HasSuffix(src, ".git"), nil
		},
		AddPermission: 0600,
	}
	if err := copy.Copy(src, dest, opt); err != nil {
		return err
	}
	return nil
}

func copyNotices(licensePath, dest string) error {
	if err := copy.Copy(licensePath, filepath.Join(dest, filepath.Base(licensePath))); err != nil {
		return err
	}

	src := filepath.Dir(licensePath)
	files, err := ioutil.ReadDir(src)
	if err != nil {
		return err
	}
	for _, f := range files {
		if fName := f.Name(); !f.IsDir() && noticeRegexp.MatchString(fName) {
			if err := copy.Copy(filepath.Join(src, fName), filepath.Join(dest, fName)); err != nil {
				return err
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package segygo

import (
	"bytes"
	"encoding/binary"
	"io/ioutil"
	//"log"
	"os"
	"unsafe"
	"reflect"
	"github.com/op/go-logging"
)

var log = logging.MustGetLogger("segygo")
var format = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                               int32
	Tracer                                                               int32
	Fldr                                                                 int32
	Tracf                                                                int32
	Ep                                                                   int32
	CDP                                                                  int32
	CDPT                                                                 int32
	Trid                                                                 int16
	Nvs                                                                  int16
	Nhs                                                                  int16
	Duse                                                                 int16
	Offset                                                               int32
	Gelev                                                                int32
	Selev                                                                int32
	Sdepth                                                               int32
	Gdel                                                                 int32
	Sdel                                                                 int32
	SwDep                                                                int32
	GwDep                                                                int32
	Scalel                                                               int16
	Scalco                                                               int16
	Sx                                                                   int32
	Sy                                                                   int32
	Gx                                                                   int32
	Gy                                                                   int32
	CoUnit                                                               int16
	WeVel                                                                int16
	SweVel                                                               int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute         int16
	Ns, Dt                                                               uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp        int16
	Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day          int16
	Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                      float32
	Ntr                                                                  int32
	Mark, Shortpad                                                       int16
	Unass                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
	Position int64
	LogLevel logging.Level
}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename
	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(logging.WARNING, "")

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	log.Debugf("Number of bytes: %d", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		log.Errorf("Error reading segy file (bigendian). %s", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) SetVerbose(verbose bool) {

	if verbose {
		s.LogLevel = logging.DEBUG
		logging.SetLevel(s.LogLevel, "")
	} else {
		s.LogLevel = logging.WARNING
		logging.SetLevel(s.LogLevel, "")
	}

}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		log.Warning("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) GetHeader() map[string]interface{} {
	m := make(map[string]interface{})
	v := reflect.ValueOf(s.Header)
	for i := 0; i < v.NumField(); i++ {
		key := v.Type().Field(i).Name
		val := v.Field(i).Interface()
		log.Debugf("name = %s, value = %d", key, val)
		m[key] = val
	}

	return m
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	if bytesRead == 0 {
		log.Infof("No bytes read for trace #", s.Position)
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	//log.Println("ReadTrace read ", bytesRead, " bytes")

	// Then figure out the size of the data, and read it
	return trace, nil
}
<commit_msg>Started on the write capability, ref #1<commit_after>package segygo

import (
	"bytes"
	"encoding/binary"
	"io/ioutil"
	//"log"
	"os"
	"unsafe"
	"reflect"
	"github.com/op/go-logging"
)

var log = logging.MustGetLogger("segygo")
var format = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                               int32
	Tracer                                                               int32
	Fldr                                                                 int32
	Tracf                                                                int32
	Ep                                                                   int32
	CDP                                                                  int32
	CDPT                                                                 int32
	Trid                                                                 int16
	Nvs                                                                  int16
	Nhs                                                                  int16
	Duse                                                                 int16
	Offset                                                               int32
	Gelev                                                                int32
	Selev                                                                int32
	Sdepth                                                               int32
	Gdel                                                                 int32
	Sdel                                                                 int32
	SwDep                                                                int32
	GwDep                                                                int32
	Scalel                                                               int16
	Scalco                                                               int16
	Sx                                                                   int32
	Sy                                                                   int32
	Gx                                                                   int32
	Gy                                                                   int32
	CoUnit                                                               int16
	WeVel                                                                int16
	SweVel                                                               int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute         int16
	Ns, Dt                                                               uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp        int16
	Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day          int16
	Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                      float32
	Ntr                                                                  int32
	Mark, Shortpad                                                       int16
	Unass                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
	Position int64
	LogLevel logging.Level
}

func CreateFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := os.Create(filename)

	if err != nil {
		return s, err
	}

	s.Filename = filename
	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	s.Header = binHdr
	s.NrTraces = 0

	return s, err

}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename
	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	log.Debugf("Number of bytes: %d", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		log.Errorf("Error reading segy file (bigendian). %s", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) SetVerbose(verbose bool) {

	if verbose {
		s.LogLevel = logging.DEBUG
		logging.SetLevel(s.LogLevel, "")
	} else {
		s.LogLevel = logging.WARNING
		logging.SetLevel(s.LogLevel, "")
	}

}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		log.Warning("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) GetHeader() map[string]interface{} {
	m := make(map[string]interface{})
	v := reflect.ValueOf(s.Header)
	for i := 0; i < v.NumField(); i++ {
		key := v.Type().Field(i).Name
		val := v.Field(i).Interface()
		log.Debugf("name = %s, value = %d", key, val)
		m[key] = val
	}

	return m
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	if bytesRead == 0 {
		log.Infof("No bytes read for trace #", s.Position)
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	// Then figure out the size of the data, and read it
	return trace, nil
}
<|endoftext|>


<commit_before>package gomail

import (
	"errors"
	"fmt"
	"io"
	"net/mail"
)

// Sender is the interface that wraps the Send method.
//
// Send sends an email to the given addresses.
type Sender interface {
	Send(from string, to []string, msg io.WriterTo) error
}

// SendCloser is the interface that groups the Send and Close methods.
type SendCloser interface {
	Sender
	Close() error
}

// A SendFunc is a function that sends emails to the given adresses.
//
// The SendFunc type is an adapter to allow the use of ordinary functions as
// email senders. If f is a function with the appropriate signature, SendFunc(f)
// is a Sender object that calls f.
type SendFunc func(from string, to []string, msg io.WriterTo) error

// Send calls f(from, to, msg).
func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
	return f(from, to, msg)
}

// Send sends emails using the given Sender.
func Send(s Sender, msg ...*Message) error {
	for i, m := range msg {
		if err := send(s, m); err != nil {
			return fmt.Errorf("gomail: could not send email %d: %v", i+1, err)
		}
	}

	return nil
}

func send(s Sender, m *Message) error {
	from, err := m.getFrom()
	if err != nil {
		return err
	}

	to, err := m.getRecipients()
	if err != nil {
		return err
	}

	if err := s.Send(from, to, m); err != nil {
		return err
	}

	return nil
}

func (m *Message) getFrom() (string, error) {
	from := m.header["Sender"]
	if len(from) == 0 {
		from = m.header["From"]
		if len(from) == 0 {
			return "", errors.New(`gomail: invalid message, "From" field is absent`)
		}
	}

	return parseAddress(from[0])
}

func (m *Message) getRecipients() ([]string, error) {
	n := 0
	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			n += len(addresses)
		}
	}
	list := make([]string, 0, n)

	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			for _, a := range addresses {
				addr, err := parseAddress(a)
				if err != nil {
					return nil, err
				}
				list = addAddress(list, addr)
			}
		}
	}

	return list, nil
}

func addAddress(list []string, addr string) []string {
	for _, a := range list {
		if addr == a {
			return list
		}
	}

	return append(list, addr)
}

func parseAddress(field string) (string, error) {
	addr, err := mail.ParseAddress(field)
	if err != nil {
		return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
	}
	return addr.Address, nil
}
<commit_msg>Fixed a typo<commit_after>package gomail

import (
	"errors"
	"fmt"
	"io"
	"net/mail"
)

// Sender is the interface that wraps the Send method.
//
// Send sends an email to the given addresses.
type Sender interface {
	Send(from string, to []string, msg io.WriterTo) error
}

// SendCloser is the interface that groups the Send and Close methods.
type SendCloser interface {
	Sender
	Close() error
}

// A SendFunc is a function that sends emails to the given addresses.
//
// The SendFunc type is an adapter to allow the use of ordinary functions as
// email senders. If f is a function with the appropriate signature, SendFunc(f)
// is a Sender object that calls f.
type SendFunc func(from string, to []string, msg io.WriterTo) error

// Send calls f(from, to, msg).
func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
	return f(from, to, msg)
}

// Send sends emails using the given Sender.
func Send(s Sender, msg ...*Message) error {
	for i, m := range msg {
		if err := send(s, m); err != nil {
			return fmt.Errorf("gomail: could not send email %d: %v", i+1, err)
		}
	}

	return nil
}

func send(s Sender, m *Message) error {
	from, err := m.getFrom()
	if err != nil {
		return err
	}

	to, err := m.getRecipients()
	if err != nil {
		return err
	}

	if err := s.Send(from, to, m); err != nil {
		return err
	}

	return nil
}

func (m *Message) getFrom() (string, error) {
	from := m.header["Sender"]
	if len(from) == 0 {
		from = m.header["From"]
		if len(from) == 0 {
			return "", errors.New(`gomail: invalid message, "From" field is absent`)
		}
	}

	return parseAddress(from[0])
}

func (m *Message) getRecipients() ([]string, error) {
	n := 0
	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			n += len(addresses)
		}
	}
	list := make([]string, 0, n)

	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			for _, a := range addresses {
				addr, err := parseAddress(a)
				if err != nil {
					return nil, err
				}
				list = addAddress(list, addr)
			}
		}
	}

	return list, nil
}

func addAddress(list []string, addr string) []string {
	for _, a := range list {
		if addr == a {
			return list
		}
	}

	return append(list, addr)
}

func parseAddress(field string) (string, error) {
	addr, err := mail.ParseAddress(field)
	if err != nil {
		return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
	}
	return addr.Address, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package loads

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/go-openapi/analysis"
	"github.com/go-openapi/spec"
	"github.com/go-openapi/swag"
)

// JSONDoc loads a json document from either a file or a remote url
func JSONDoc(path string) (json.RawMessage, error) {
	data, err := swag.LoadFromFileOrHTTP(path)
	if err != nil {
		return nil, err
	}
	return json.RawMessage(data), nil
}

// DocLoader represents a doc loader type
type DocLoader func(string) (json.RawMessage, error)

// DocMatcher represents a predicate to check if a loader matches
type DocMatcher func(string) bool

var (
	loaders       *loader
	defaultLoader *loader
)

func init() {
	defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
	loaders = defaultLoader
	spec.PathLoader = loaders.Fn
	AddLoader(swag.YAMLMatcher, swag.YAMLDoc)
}

// AddLoader for a document
func AddLoader(predicate DocMatcher, load DocLoader) {
	prev := loaders
	loaders = &loader{
		Match: predicate,
		Fn:    load,
		Next:  prev,
	}
	spec.PathLoader = loaders.Fn
}

type loader struct {
	Fn    DocLoader
	Match DocMatcher
	Next  *loader
}

// JSONSpec loads a spec from a json document
func JSONSpec(path string) (*Document, error) {
	data, err := JSONDoc(path)
	if err != nil {
		return nil, err
	}
	// convert to json
	return Analyzed(json.RawMessage(data), "")
}

// Document represents a swagger spec document
type Document struct {
	// specAnalyzer
	Analyzer     *analysis.Spec
	spec         *spec.Swagger
	specFilePath string
	origSpec     *spec.Swagger
	schema       *spec.Schema
	raw          json.RawMessage
}

// Embedded returns a Document based on embedded specs. No analysis is required
func Embedded(orig, flat json.RawMessage) (*Document, error) {
	var origSpec, flatSpec spec.Swagger
	if err := json.Unmarshal(orig, &origSpec); err != nil {
		return nil, err
	}
	if err := json.Unmarshal(flat, &flatSpec); err != nil {
		return nil, err
	}
	return &Document{
		origSpec: &origSpec,
		spec:     &flatSpec,
	}, nil
}

// Spec loads a new spec document
func Spec(path string) (*Document, error) {
	specURL, err := url.Parse(path)
	if err != nil {
		return nil, err
	}
	var lastErr error
	for l := loaders.Next; l != nil; l = l.Next {
		if loaders.Match(specURL.Path) {
			b, err2 := loaders.Fn(path)
			if err2 != nil {
				lastErr = err2
				continue
			}
			doc, err := Analyzed(b, "")
			if err != nil {
				return nil, err
			}
			if doc != nil {
				doc.specFilePath = path
			}
			return doc, nil
		}
	}
	if lastErr != nil {
		return nil, lastErr
	}
	b, err := defaultLoader.Fn(path)
	if err != nil {
		return nil, err
	}

	document, err := Analyzed(b, "")
	if document != nil {
		document.specFilePath = path
	}

	return document, err
}

// Analyzed creates a new analyzed spec document
func Analyzed(data json.RawMessage, version string) (*Document, error) {
	if version == "" {
		version = "2.0"
	}
	if version != "2.0" {
		return nil, fmt.Errorf("spec version %q is not supported", version)
	}

	raw := data
	trimmed := bytes.TrimSpace(data)
	if len(trimmed) > 0 {
		if trimmed[0] != '{' && trimmed[0] != '[' {
			yml, err := swag.BytesToYAMLDoc(trimmed)
			if err != nil {
				return nil, fmt.Errorf("analyzed: %v", err)
			}
			d, err := swag.YAMLToJSON(yml)
			if err != nil {
				return nil, fmt.Errorf("analyzed: %v", err)
			}
			raw = d
		}
	}

	swspec := new(spec.Swagger)
	if err := json.Unmarshal(raw, swspec); err != nil {
		return nil, err
	}

	origsqspec := new(spec.Swagger)
	if err := json.Unmarshal(raw, origsqspec); err != nil {
		return nil, err
	}

	d := &Document{
		Analyzer: analysis.New(swspec),
		schema:   spec.MustLoadSwagger20Schema(),
		spec:     swspec,
		raw:      raw,
		origSpec: origsqspec,
	}
	return d, nil
}

// Expanded expands the ref fields in the spec document and returns a new spec document
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
	swspec := new(spec.Swagger)
	if err := json.Unmarshal(d.raw, swspec); err != nil {
		return nil, err
	}

	var expandOptions *spec.ExpandOptions
	if len(options) > 0 {
		expandOptions = options[0]
	} else {
		expandOptions = &spec.ExpandOptions{
			RelativeBase: d.specFilePath,
		}
	}

	if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
		return nil, err
	}

	dd := &Document{
		Analyzer: analysis.New(swspec),
		spec:     swspec,
		schema:   spec.MustLoadSwagger20Schema(),
		raw:      d.raw,
		origSpec: d.origSpec,
	}
	return dd, nil
}

// BasePath the base path for this spec
func (d *Document) BasePath() string {
	return d.spec.BasePath
}

// Version returns the version of this spec
func (d *Document) Version() string {
	return d.spec.Swagger
}

// Schema returns the swagger 2.0 schema
func (d *Document) Schema() *spec.Schema {
	return d.schema
}

// Spec returns the swagger spec object model
func (d *Document) Spec() *spec.Swagger {
	return d.spec
}

// Host returns the host for the API
func (d *Document) Host() string {
	return d.spec.Host
}

// Raw returns the raw swagger spec as json bytes
func (d *Document) Raw() json.RawMessage {
	return d.raw
}

func (d *Document) OrigSpec() *spec.Swagger {
	return d.origSpec
}

// ResetDefinitions gives a shallow copy with the models reset
func (d *Document) ResetDefinitions() *Document {
	defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
	for k, v := range d.origSpec.Definitions {
		defs[k] = v
	}

	d.spec.Definitions = defs
	return d
}

// Pristine creates a new pristine document instance based on the input data
func (d *Document) Pristine() *Document {
	dd, _ := Analyzed(d.Raw(), d.Version())
	return dd
}

// SpecFilePath returns the file path of the spec if one is defined
func (d *Document) SpecFilePath() string {
	return d.specFilePath
}
<commit_msg>put raw spec in Embedded() to allow retreival via the default spec endpoint (#16)<commit_after>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package loads

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/go-openapi/analysis"
	"github.com/go-openapi/spec"
	"github.com/go-openapi/swag"
)

// JSONDoc loads a json document from either a file or a remote url
func JSONDoc(path string) (json.RawMessage, error) {
	data, err := swag.LoadFromFileOrHTTP(path)
	if err != nil {
		return nil, err
	}
	return json.RawMessage(data), nil
}

// DocLoader represents a doc loader type
type DocLoader func(string) (json.RawMessage, error)

// DocMatcher represents a predicate to check if a loader matches
type DocMatcher func(string) bool

var (
	loaders       *loader
	defaultLoader *loader
)

func init() {
	defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
	loaders = defaultLoader
	spec.PathLoader = loaders.Fn
	AddLoader(swag.YAMLMatcher, swag.YAMLDoc)
}

// AddLoader for a document
func AddLoader(predicate DocMatcher, load DocLoader) {
	prev := loaders
	loaders = &loader{
		Match: predicate,
		Fn:    load,
		Next:  prev,
	}
	spec.PathLoader = loaders.Fn
}

type loader struct {
	Fn    DocLoader
	Match DocMatcher
	Next  *loader
}

// JSONSpec loads a spec from a json document
func JSONSpec(path string) (*Document, error) {
	data, err := JSONDoc(path)
	if err != nil {
		return nil, err
	}
	// convert to json
	return Analyzed(json.RawMessage(data), "")
}

// Document represents a swagger spec document
type Document struct {
	// specAnalyzer
	Analyzer     *analysis.Spec
	spec         *spec.Swagger
	specFilePath string
	origSpec     *spec.Swagger
	schema       *spec.Schema
	raw          json.RawMessage
}

// Embedded returns a Document based on embedded specs. No analysis is required
func Embedded(orig, flat json.RawMessage) (*Document, error) {
	var origSpec, flatSpec spec.Swagger
	if err := json.Unmarshal(orig, &origSpec); err != nil {
		return nil, err
	}
	if err := json.Unmarshal(flat, &flatSpec); err != nil {
		return nil, err
	}
	return &Document{
		raw:      orig,
		origSpec: &origSpec,
		spec:     &flatSpec,
	}, nil
}

// Spec loads a new spec document
func Spec(path string) (*Document, error) {
	specURL, err := url.Parse(path)
	if err != nil {
		return nil, err
	}
	var lastErr error
	for l := loaders.Next; l != nil; l = l.Next {
		if loaders.Match(specURL.Path) {
			b, err2 := loaders.Fn(path)
			if err2 != nil {
				lastErr = err2
				continue
			}
			doc, err := Analyzed(b, "")
			if err != nil {
				return nil, err
			}
			if doc != nil {
				doc.specFilePath = path
			}
			return doc, nil
		}
	}
	if lastErr != nil {
		return nil, lastErr
	}
	b, err := defaultLoader.Fn(path)
	if err != nil {
		return nil, err
	}

	document, err := Analyzed(b, "")
	if document != nil {
		document.specFilePath = path
	}

	return document, err
}

// Analyzed creates a new analyzed spec document
func Analyzed(data json.RawMessage, version string) (*Document, error) {
	if version == "" {
		version = "2.0"
	}
	if version != "2.0" {
		return nil, fmt.Errorf("spec version %q is not supported", version)
	}

	raw := data
	trimmed := bytes.TrimSpace(data)
	if len(trimmed) > 0 {
		if trimmed[0] != '{' && trimmed[0] != '[' {
			yml, err := swag.BytesToYAMLDoc(trimmed)
			if err != nil {
				return nil, fmt.Errorf("analyzed: %v", err)
			}
			d, err := swag.YAMLToJSON(yml)
			if err != nil {
				return nil, fmt.Errorf("analyzed: %v", err)
			}
			raw = d
		}
	}

	swspec := new(spec.Swagger)
	if err := json.Unmarshal(raw, swspec); err != nil {
		return nil, err
	}

	origsqspec := new(spec.Swagger)
	if err := json.Unmarshal(raw, origsqspec); err != nil {
		return nil, err
	}

	d := &Document{
		Analyzer: analysis.New(swspec),
		schema:   spec.MustLoadSwagger20Schema(),
		spec:     swspec,
		raw:      raw,
		origSpec: origsqspec,
	}
	return d, nil
}

// Expanded expands the ref fields in the spec document and returns a new spec document
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
	swspec := new(spec.Swagger)
	if err := json.Unmarshal(d.raw, swspec); err != nil {
		return nil, err
	}

	var expandOptions *spec.ExpandOptions
	if len(options) > 0 {
		expandOptions = options[0]
	} else {
		expandOptions = &spec.ExpandOptions{
			RelativeBase: d.specFilePath,
		}
	}

	if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
		return nil, err
	}

	dd := &Document{
		Analyzer: analysis.New(swspec),
		spec:     swspec,
		schema:   spec.MustLoadSwagger20Schema(),
		raw:      d.raw,
		origSpec: d.origSpec,
	}
	return dd, nil
}

// BasePath the base path for this spec
func (d *Document) BasePath() string {
	return d.spec.BasePath
}

// Version returns the version of this spec
func (d *Document) Version() string {
	return d.spec.Swagger
}

// Schema returns the swagger 2.0 schema
func (d *Document) Schema() *spec.Schema {
	return d.schema
}

// Spec returns the swagger spec object model
func (d *Document) Spec() *spec.Swagger {
	return d.spec
}

// Host returns the host for the API
func (d *Document) Host() string {
	return d.spec.Host
}

// Raw returns the raw swagger spec as json bytes
func (d *Document) Raw() json.RawMessage {
	return d.raw
}

func (d *Document) OrigSpec() *spec.Swagger {
	return d.origSpec
}

// ResetDefinitions gives a shallow copy with the models reset
func (d *Document) ResetDefinitions() *Document {
	defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
	for k, v := range d.origSpec.Definitions {
		defs[k] = v
	}

	d.spec.Definitions = defs
	return d
}

// Pristine creates a new pristine document instance based on the input data
func (d *Document) Pristine() *Document {
	dd, _ := Analyzed(d.Raw(), d.Version())
	return dd
}

// SpecFilePath returns the file path of the spec if one is defined
func (d *Document) SpecFilePath() string {
	return d.specFilePath
}
<|endoftext|>


<commit_before>package ssgo

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"strconv"
)

type Client struct {
	sock     *net.TCPConn
	recv_buf bytes.Buffer
	pool     *ConPool
	netErr   error
}

func Connect(ip string, port int) (*Client, error) {
	addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
	if err != nil {
		return nil, err
	}
	sock, err := net.DialTCP("tcp", nil, addr)
	if err != nil {
		return nil, err
	}
	var c Client
	c.sock = sock
	return &c, nil
}

func (c *Client) Do(args ...interface{}) (Reply, error) {

	if err := c.send(args); err != nil {
		return nil, err
	}

	resp, err := c.recv()
	if err != nil || len(resp) < 1 {
		return nil, err
	}
	if resp[0] != "ok" {
		return nil, errors.New(resp[0])
	}
	return resp[1:], nil
}

func (c *Client) Set(key string, val string) (interface{}, error) {
	resp, err := c.Do("set", key, val)
	if err != nil {
		return nil, err
	}
	if len(resp) == 2 && resp[0] == "ok" {
		return true, nil
	}
	return nil, fmt.Errorf("bad response")
}

// TODO: Will somebody write addition semantic methods?
func (c *Client) Get(key string) (interface{}, error) {
	resp, err := c.Do("get", key)
	if err != nil {
		return nil, err
	}
	if len(resp) == 2 && resp[0] == "ok" {
		return resp[1], nil
	}
	if resp[0] == "not_found" {
		return nil, nil
	}
	return nil, fmt.Errorf("bad response")
}

func (c *Client) Del(key string) (interface{}, error) {
	resp, err := c.Do("del", key)
	if err != nil {
		return nil, err
	}

	//response looks like this: [ok 1]
	if len(resp) > 0 && resp[0] == "ok" {
		return true, nil
	}
	return nil, fmt.Errorf("bad response:resp:%v:", resp)
}

func (c *Client) MultiHSet(name string, obj interface{}, keys ...string) error {
	args := Args{"multi_hset", name}.AddFlat(obj, keys...)
	_, e := c.Do(args...)
	return e
}

func (c *Client) MultiHGet(name string, obj interface{}, keys ...string) error {
	var (
		rep Reply
		e   error
	)
	if len(keys) > 0 {
		args := []interface{}{"multi_hget", name}
		for _, v := range keys {
			args = append(args, v)
		}
		rep, e = c.Do(args...)
	} else {
		rep, e = c.Do("hgetall", name)
	}
	if e != nil {
		return e
	}
	return ScanStruct(rep, obj)
}

func (c *Client) GenAutoIncId(name string) int64{
	rep, e := c.Do("incr", name)
	if e != nil {
		return 0
	}
	return rep.Int64()
}

func (c *Client) Send(args ...interface{}) error {
	return c.send(args)
}

func (c *Client) send(args []interface{}) error {
	var buf bytes.Buffer
	for _, arg := range args {
		var s string
		switch arg := arg.(type) {
		case string:
			s = arg
		case []byte:
			s = string(arg)
		case []string:
			for _, s := range arg {
				buf.WriteString(fmt.Sprintf("%d", len(s)))
				buf.WriteByte('\n')
				buf.WriteString(s)
				buf.WriteByte('\n')
			}
			continue
		case int:
			s = fmt.Sprintf("%d", arg)
		case int64:
			s = fmt.Sprintf("%d", arg)
		case float64:
			s = fmt.Sprintf("%f", arg)
		case bool:
			if arg {
				s = "1"
			} else {
				s = "0"
			}
		case nil:
			s = ""
		default:
			buf, e := json.Marshal(arg)
			if e != nil {
				return fmt.Errorf("bad arguments")
			}
			s = string(buf)
		}
		buf.WriteString(fmt.Sprintf("%d", len(s)))
		buf.WriteByte('\n')
		buf.WriteString(s)
		buf.WriteByte('\n')
	}
	buf.WriteByte('\n')
	_, err := c.sock.Write(buf.Bytes())
	if err != nil {
		c.netErr = err
	}
	return err
}

func (c *Client) Recv() ([]string, error) {
	return c.recv()
}

func (c *Client) recv() ([]string, error) {
	var tmp [1]byte
	for {
		resp := c.parse()
		if resp == nil || len(resp) > 0 {
			return resp, nil
		}
		n, err := c.sock.Read(tmp[0:])
		if err != nil {
			c.netErr = err
			return nil, err
		}
		c.recv_buf.Write(tmp[0:n])
	}
}

func (c *Client) parse() []string {
	resp := []string{}
	buf := c.recv_buf.Bytes()
	var idx, offset int
	idx = 0
	offset = 0

	for {
		idx = bytes.IndexByte(buf[offset:], '\n')
		if idx == -1 {
			break
		}
		p := buf[offset : offset+idx]
		offset += idx + 1
		//fmt.Printf("> [%s]\n", p);
		if len(p) == 0 || (len(p) == 1 && p[0] == '\r') {
			if len(resp) == 0 {
				continue
			} else {
				c.recv_buf.Next(offset)
				return resp
			}
		}

		size, err := strconv.Atoi(string(p))
		if err != nil || size < 0 {
			return nil
		}
		if offset+size >= c.recv_buf.Len() {
			break
		}

		v := buf[offset : offset+size]
		resp = append(resp, string(v))
		offset += size + 1
	}

	//fmt.Printf("buf.size: %d packet not ready...\n", len(buf))
	return []string{}
}

// Close The Client Connection
func (c *Client) close() error {
	return c.sock.Close()
}

func (c *Client) Release() error {
	if c.netErr != nil {
		// if client have net error, try to close it
		return c.close()
	} else if c.pool != nil {
		c.pool.push(c)
		return nil
	}
	return c.close()
}
<commit_msg>add  DoIgnoreErr<commit_after>package ssgo

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"strconv"
)

type Client struct {
	sock     *net.TCPConn
	recv_buf bytes.Buffer
	pool     *ConPool
	netErr   error
}

func Connect(ip string, port int) (*Client, error) {
	addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
	if err != nil {
		return nil, err
	}
	sock, err := net.DialTCP("tcp", nil, addr)
	if err != nil {
		return nil, err
	}
	var c Client
	c.sock = sock
	return &c, nil
}

func (c *Client) Do(args ...interface{}) (Reply, error) {

	if err := c.send(args); err != nil {
		return nil, err
	}

	resp, err := c.recv()
	if err != nil || len(resp) < 1 {
		return nil, err
	}
	if resp[0] != "ok" {
		return nil, errors.New(resp[0])
	}
	return resp[1:], nil
}

func (c *Client)DoIgnoreErr(args ...interface{}) Reply {
	r, e := c.Do(args...)
	if e != nil {
		return Reply{}
	}
	return r
}

func (c *Client) Set(key string, val string) (interface{}, error) {
	resp, err := c.Do("set", key, val)
	if err != nil {
		return nil, err
	}
	if len(resp) == 2 && resp[0] == "ok" {
		return true, nil
	}
	return nil, fmt.Errorf("bad response")
}

// TODO: Will somebody write addition semantic methods?
func (c *Client) Get(key string) (interface{}, error) {
	resp, err := c.Do("get", key)
	if err != nil {
		return nil, err
	}
	if len(resp) == 2 && resp[0] == "ok" {
		return resp[1], nil
	}
	if resp[0] == "not_found" {
		return nil, nil
	}
	return nil, fmt.Errorf("bad response")
}

func (c *Client) Del(key string) (interface{}, error) {
	resp, err := c.Do("del", key)
	if err != nil {
		return nil, err
	}

	//response looks like this: [ok 1]
	if len(resp) > 0 && resp[0] == "ok" {
		return true, nil
	}
	return nil, fmt.Errorf("bad response:resp:%v:", resp)
}

func (c *Client) MultiHSet(name string, obj interface{}, keys ...string) error {
	args := Args{"multi_hset", name}.AddFlat(obj, keys...)
	_, e := c.Do(args...)
	return e
}

func (c *Client) MultiHGet(name string, obj interface{}, keys ...string) error {
	var (
		rep Reply
		e   error
	)
	if len(keys) > 0 {
		args := []interface{}{"multi_hget", name}
		for _, v := range keys {
			args = append(args, v)
		}
		rep, e = c.Do(args...)
	} else {
		rep, e = c.Do("hgetall", name)
	}
	if e != nil {
		return e
	}
	return ScanStruct(rep, obj)
}

func (c *Client) GenAutoIncId(name string) int64{
	rep, e := c.Do("incr", name)
	if e != nil {
		return 0
	}
	return rep.Int64()
}

func (c *Client) Send(args ...interface{}) error {
	return c.send(args)
}

func (c *Client) send(args []interface{}) error {
	var buf bytes.Buffer
	for _, arg := range args {
		var s string
		switch arg := arg.(type) {
		case string:
			s = arg
		case []byte:
			s = string(arg)
		case []string:
			for _, s := range arg {
				buf.WriteString(fmt.Sprintf("%d", len(s)))
				buf.WriteByte('\n')
				buf.WriteString(s)
				buf.WriteByte('\n')
			}
			continue
		case int:
			s = fmt.Sprintf("%d", arg)
		case int64:
			s = fmt.Sprintf("%d", arg)
		case float64:
			s = fmt.Sprintf("%f", arg)
		case bool:
			if arg {
				s = "1"
			} else {
				s = "0"
			}
		case nil:
			s = ""
		default:
			buf, e := json.Marshal(arg)
			if e != nil {
				return fmt.Errorf("bad arguments")
			}
			s = string(buf)
		}
		buf.WriteString(fmt.Sprintf("%d", len(s)))
		buf.WriteByte('\n')
		buf.WriteString(s)
		buf.WriteByte('\n')
	}
	buf.WriteByte('\n')
	_, err := c.sock.Write(buf.Bytes())
	if err != nil {
		c.netErr = err
	}
	return err
}

func (c *Client) Recv() ([]string, error) {
	return c.recv()
}

func (c *Client) recv() ([]string, error) {
	var tmp [1]byte
	for {
		resp := c.parse()
		if resp == nil || len(resp) > 0 {
			return resp, nil
		}
		n, err := c.sock.Read(tmp[0:])
		if err != nil {
			c.netErr = err
			return nil, err
		}
		c.recv_buf.Write(tmp[0:n])
	}
}

func (c *Client) parse() []string {
	resp := []string{}
	buf := c.recv_buf.Bytes()
	var idx, offset int
	idx = 0
	offset = 0

	for {
		idx = bytes.IndexByte(buf[offset:], '\n')
		if idx == -1 {
			break
		}
		p := buf[offset : offset+idx]
		offset += idx + 1
		//fmt.Printf("> [%s]\n", p);
		if len(p) == 0 || (len(p) == 1 && p[0] == '\r') {
			if len(resp) == 0 {
				continue
			} else {
				c.recv_buf.Next(offset)
				return resp
			}
		}

		size, err := strconv.Atoi(string(p))
		if err != nil || size < 0 {
			return nil
		}
		if offset+size >= c.recv_buf.Len() {
			break
		}

		v := buf[offset : offset+size]
		resp = append(resp, string(v))
		offset += size + 1
	}

	//fmt.Printf("buf.size: %d packet not ready...\n", len(buf))
	return []string{}
}

// Close The Client Connection
func (c *Client) close() error {
	return c.sock.Close()
}

func (c *Client) Release() error {
	if c.netErr != nil {
		// if client have net error, try to close it
		return c.close()
	} else if c.pool != nil {
		c.pool.push(c)
		return nil
	}
	return c.close()
}
<|endoftext|>


<commit_before>package congo

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

// Term struct representing a console manager
type Term struct {
	cmds map[string]func([]string)
	done chan bool
	_prompt string
	unknownHandler func(string)
}

// NewTerm creates a new initialized Term struct
func NewTerm(prompt string) *Term {
	t:= &Term{make(map[string]func([]string), 1), make(chan bool),prompt,nil}
	return t
}

// AddCommand adds a function handler for this command
func (t *Term) AddCommand(name string, funct func([]string)) {
	t.cmds[name] = funct
}

// RemoveCommand removes a command/handler entry
func (t *Term) RemoveCommand(name string) {
	delete(t.cmds, name)
}

// AddUnknownHandler adds a function handler for unknown command
func (t *Term) AddUnknownHandler(funct func(string)) {
	t.unknownHandler = funct
}

// Prompt set the prompt
func (t *Term) Prompt(prompt string) {
	t._prompt=prompt
}

// Display the prompt and listen for new commands
// Add them with .AddCommand(command name, function implementing it)
func (t *Term) listen() {
	scanner := bufio.NewScanner(os.Stdin)
	running := true
	fmt.Print(t._prompt + " ")
	for running && scanner.Scan() {
		tokens := strings.Split(strings.TrimSpace(scanner.Text()), " ")
		command := tokens[0]
		if command == "quit" || command == "exit" {
			running = false
		} else {
			f, found := t.cmds[command]
			switch {
			case found && len(tokens) > 1:
				f(tokens[1:])
			case found:
				f([]string{})
			default:
				if t.unknownHandler!=nil && command!="" {
					t.unknownHandler(command)
				}
			}
			fmt.Print(t._prompt + " ")
		}
	}
	t.done <- true
}

// ListenUntilExit starts reading command until "exit" or "quit"
func (t *Term) ListenUntilExit() {
	go t.listen()
	<-t.done
}
<commit_msg>Formatting<commit_after>package congo

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

// Term struct representing a console manager
type Term struct {
	cmds           map[string]func([]string)
	done           chan bool
	_prompt        string
	unknownHandler func(string)
}

// NewTerm creates a new initialized Term struct
func NewTerm(prompt string) *Term {
	t := &Term{make(map[string]func([]string), 1), make(chan bool), prompt, nil}
	return t
}

// AddCommand adds a function handler for this command
func (t *Term) AddCommand(name string, funct func([]string)) {
	t.cmds[name] = funct
}

// RemoveCommand removes a command/handler entry
func (t *Term) RemoveCommand(name string) {
	delete(t.cmds, name)
}

// AddUnknownHandler adds a function handler for unknown command
func (t *Term) AddUnknownHandler(funct func(string)) {
	t.unknownHandler = funct
}

// Prompt set the prompt
func (t *Term) Prompt(prompt string) {
	t._prompt = prompt
}

// Display the prompt and listen for new commands
// Add them with .AddCommand(command name, function implementing it)
func (t *Term) listen() {
	scanner := bufio.NewScanner(os.Stdin)
	running := true
	fmt.Print(t._prompt + " ")
	for running && scanner.Scan() {
		tokens := strings.Split(strings.TrimSpace(scanner.Text()), " ")
		command := tokens[0]
		if command == "quit" || command == "exit" {
			running = false
		} else {
			f, found := t.cmds[command]
			switch {
			case found && len(tokens) > 1:
				f(tokens[1:])
			case found:
				f([]string{})
			default:
				if t.unknownHandler != nil && command != "" {
					t.unknownHandler(command)
				}
			}
			fmt.Print(t._prompt + " ")
		}
	}
	t.done <- true
}

// ListenUntilExit starts reading command until "exit" or "quit"
func (t *Term) ListenUntilExit() {
	go t.listen()
	<-t.done
}
<|endoftext|>


<commit_before>package golog

import . "fmt"
import . "regexp"
import . "strings"
import "bytes"

var anonCounter <-chan int64
func init() {
    // goroutine providing a counter for anonymous variables
    c := make(chan int64)
    var i int64 = 1
    go func() {
        for {
            c <- i
            i++
        }
    }()
    anonCounter = c
}

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

type Structure struct {
    Func    string
    Args    []Term
}
func (self *Structure) Functor() string {
    return self.Func
}
func (self *Structure) Arity() int {
    return len(self.Args)
}
func (self *Structure) Arguments() []Term {
    return self.Args
}
func (self *Structure) Body() Term {
    return self.Args[1]
}
func (self *Structure) Head() Term {
    return self.Args[0]
}
func (self *Structure) IsClause() bool {
    return self.Arity() == 2 && self.Functor() == ":-"
}
func (self *Structure) String() string {
    // an atom
    quotedFunctor := QuoteFunctor(self.Functor())
    if self.Arity() == 0 {
        return quotedFunctor
    }

    var buf bytes.Buffer
    Fprintf(&buf, "%s(", quotedFunctor)
    arity := self.Arity()
    for i := 0; i<arity; i++ {
        if i>0 {
            Fprintf(&buf, ", ")
        }
        Fprintf(&buf, "%s", self.Arguments()[i])
    }
    Fprintf(&buf, ")")
    return buf.String()
}
func (self *Structure) Indicator() string {
    return Sprintf("%s/%d", self.Functor(), self.Arity())
}
func (self *Structure) Error() error {
    panic("Can't call Error() on a Structure")
}

type Variable struct {
    Name    string
}
func (self *Variable) Functor() string {
    panic("Variables have no Functor()")
}
func (self *Variable) Arity() int {
    panic("Variables have no Arity()")
}
func (self *Variable) Arguments() []Term {
    panic("Variables have no Arguments()")
}
func (self *Variable) Body() Term {
    panic("Variables have no Body()")
}
func (self *Variable) Head() Term {
    panic("Variables have no Head()")
}
func (self *Variable) IsClause() bool {
    return false
}
func (self *Variable) String() string {
    return self.Name
}
func (self *Variable) Indicator() string {
    return Sprintf("%s", self.Name)
}
func (self *Variable) Error() error {
    panic("Can't call Error() on a Variable")
}

type Error string
func (self *Error) Functor() string {
    panic("Errors have no Functor()")
}
func (self *Error) Arity() int {
    panic("Errors have no Arity()")
}
func (self *Error) Arguments() []Term {
    panic("Errors have no Arguments()")
}
func (self *Error) Body() Term {
    panic("Errors have no Body()")
}
func (self *Error) Head() Term {
    panic("Errors have no Head()")
}
func (self *Error) IsClause() bool {
    return false
}
func (self *Error) String() string {
    return string(*self)
}
func (self *Error) Indicator() string {
    panic("Errors have no Indicator()")
}
func (self *Error) Error() error {
    return Errorf("%s", *self)
}

// NewTerm creates a new term with the given functor and optional arguments
func NewTerm(functor string, arguments ...Term) Term {
    return &Structure{
        Func:   functor,
        Args:   arguments,
    }
}

func NewVar(name string) Term {
    // sanity check the variable name's syntax
    isCapitalized, err := MatchString(`^[A-Z_]`, name)
    maybePanic(err)
    if !isCapitalized {
        panic("Variable names must start with a capital letter or underscore")
    }

    // make sure anonymous variables are unique
    if name == "_" {
        i := <-anonCounter
        name = Sprintf("_G%d", i)
    }
    return &Variable{
        Name:   name,
    }
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}
func IsError(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return false
        case *Error:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<commit_msg>Add ISO section headers where appropriate<commit_after>package golog

import . "fmt"
import . "regexp"
import . "strings"
import "bytes"

var anonCounter <-chan int64
func init() {
    // goroutine providing a counter for anonymous variables
    c := make(chan int64)
    var i int64 = 1
    go func() {
        for {
            c <- i
            i++
        }
    }()
    anonCounter = c
}

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

// ISO calls this a "compound term" see §6.1.2(e)
// We currently use this type to cover atoms defined in §6.1.2(b)
type Structure struct {
    Func    string
    Args    []Term
}
func (self *Structure) Functor() string {
    return self.Func
}
func (self *Structure) Arity() int {
    return len(self.Args)
}
func (self *Structure) Arguments() []Term {
    return self.Args
}
func (self *Structure) Body() Term {
    return self.Args[1]
}
func (self *Structure) Head() Term {
    return self.Args[0]
}
func (self *Structure) IsClause() bool {
    return self.Arity() == 2 && self.Functor() == ":-"
}
func (self *Structure) String() string {
    // an atom
    quotedFunctor := QuoteFunctor(self.Functor())
    if self.Arity() == 0 {
        return quotedFunctor
    }

    var buf bytes.Buffer
    Fprintf(&buf, "%s(", quotedFunctor)
    arity := self.Arity()
    for i := 0; i<arity; i++ {
        if i>0 {
            Fprintf(&buf, ", ")
        }
        Fprintf(&buf, "%s", self.Arguments()[i])
    }
    Fprintf(&buf, ")")
    return buf.String()
}
func (self *Structure) Indicator() string {
    return Sprintf("%s/%d", self.Functor(), self.Arity())
}
func (self *Structure) Error() error {
    panic("Can't call Error() on a Structure")
}

// See §6.1.2(a)
type Variable struct {
    Name    string
}
func (self *Variable) Functor() string {
    panic("Variables have no Functor()")
}
func (self *Variable) Arity() int {
    panic("Variables have no Arity()")
}
func (self *Variable) Arguments() []Term {
    panic("Variables have no Arguments()")
}
func (self *Variable) Body() Term {
    panic("Variables have no Body()")
}
func (self *Variable) Head() Term {
    panic("Variables have no Head()")
}
func (self *Variable) IsClause() bool {
    return false
}
func (self *Variable) String() string {
    return self.Name
}
func (self *Variable) Indicator() string {
    return Sprintf("%s", self.Name)
}
func (self *Variable) Error() error {
    panic("Can't call Error() on a Variable")
}

type Error string
func (self *Error) Functor() string {
    panic("Errors have no Functor()")
}
func (self *Error) Arity() int {
    panic("Errors have no Arity()")
}
func (self *Error) Arguments() []Term {
    panic("Errors have no Arguments()")
}
func (self *Error) Body() Term {
    panic("Errors have no Body()")
}
func (self *Error) Head() Term {
    panic("Errors have no Head()")
}
func (self *Error) IsClause() bool {
    return false
}
func (self *Error) String() string {
    return string(*self)
}
func (self *Error) Indicator() string {
    panic("Errors have no Indicator()")
}
func (self *Error) Error() error {
    return Errorf("%s", *self)
}

// NewTerm creates a new term with the given functor and optional arguments
func NewTerm(functor string, arguments ...Term) Term {
    return &Structure{
        Func:   functor,
        Args:   arguments,
    }
}

func NewVar(name string) Term {
    // sanity check the variable name's syntax
    isCapitalized, err := MatchString(`^[A-Z_]`, name)
    maybePanic(err)
    if !isCapitalized {
        panic("Variable names must start with a capital letter or underscore")
    }

    // make sure anonymous variables are unique
    if name == "_" {
        i := <-anonCounter
        name = Sprintf("_G%d", i)
    }
    return &Variable{
        Name:   name,
    }
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}
func IsError(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return false
        case *Error:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<|endoftext|>


<commit_before>package leakybucket

import (
	"math"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 10, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		addAndTestRemaining := func(add, remaining uint) {
			if state, err := bucket.Add(add); err != nil {
				t.Fatal(err)
			} else if bucket.Remaining() != state.Remaining {
				t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
					bucket.Remaining(), state.Remaining)
			} else if state.Remaining != remaining {
				t.Fatalf("expected %d remaining, got %d", remaining, state.Remaining)
			}
		}

		addAndTestRemaining(1, 9)
		addAndTestRemaining(3, 6)
		addAndTestRemaining(6, 0)

		if _, err := bucket.Add(1); err == nil {
			t.Fatalf("expected ErrorFull, received no error")
		} else if err != ErrorFull {
			t.Fatalf("expected ErrorFull, received %v", err)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		if len(remaining) != n {
			keys := []uint{}
			for key, _ := range remaining {
				keys = append(keys, key)
			}
			t.Fatalf("Did not observe correct bucket states. Saw %d distinct remaining values instead of %d: %v",
				len(remaining), n, keys)
		}
		if len(errors) != 1 && errors[0] != ErrorFull {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<commit_msg>test: ThreadSafeAdd: fix broken test condition<commit_after>package leakybucket

import (
	"math"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 10, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		addAndTestRemaining := func(add, remaining uint) {
			if state, err := bucket.Add(add); err != nil {
				t.Fatal(err)
			} else if bucket.Remaining() != state.Remaining {
				t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
					bucket.Remaining(), state.Remaining)
			} else if state.Remaining != remaining {
				t.Fatalf("expected %d remaining, got %d", remaining, state.Remaining)
			}
		}

		addAndTestRemaining(1, 9)
		addAndTestRemaining(3, 6)
		addAndTestRemaining(6, 0)

		if _, err := bucket.Add(1); err == nil {
			t.Fatalf("expected ErrorFull, received no error")
		} else if err != ErrorFull {
			t.Fatalf("expected ErrorFull, received %v", err)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		if len(remaining) != n {
			keys := []uint{}
			for key, _ := range remaining {
				keys = append(keys, key)
			}
			t.Fatalf("Did not observe correct bucket states. Saw %d distinct remaining values instead of %d: %v",
				len(remaining), n, keys)
		}
		if !(len(errors) == 1 && errors[0] == ErrorFull) {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<|endoftext|>


<commit_before>package structable
<commit_msg>Removed empty file.<commit_after><|endoftext|>